diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000000..e69de29bb2d diff --git a/2-Factor-Authentication/index.html b/2-Factor-Authentication/index.html new file mode 100644 index 00000000000..926ac9fce9c --- /dev/null +++ b/2-Factor-Authentication/index.html @@ -0,0 +1,980 @@ + + + + + + + + + + + + + + +2nd Factor - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Faraday supports 2nd Factor Authentication. We support any apps, e.g:

+
    +
  1. Google Authenticator Android
  2. +
  3. Google Authenticator iOS
  4. +
  5. Authy Android
  6. +
  7. Authy iOS
  8. +
  9. OTP Authenticator Android, Open Source
  10. +
+

Activate 2FA

+
    +
  • Click on the Faraday slider menu on the top right of the screen, select Account and go to the Two Factor Authentication tab.
  • +
+

imagen +* Once you enable 2FA, Faraday will show you a QR code and thus you can scan it with your chosen app.

+

imagen

+
+

As with every app using 2FA, the time on your phone and on your machine must be synchronized.

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/404.html b/404.html new file mode 100644 index 00000000000..1cf0e1ac5e7 --- /dev/null +++ b/404.html @@ -0,0 +1,2288 @@ + + + + + + + + + + + + + + + + + + + + + + + Faraday + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ +
+ + + + + + +
+ + +
+ +
+ + + + + + +
+
+ + + +
+
+
+ + + + + +
+
+
+ + + +
+
+
+ + + +
+
+
+ + + +
+
+ +

404 - Not found

+ +
+
+ + + +
+ +
+ + + +
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/API-Server/index.html b/API-Server/index.html new file mode 100644 index 00000000000..1d08d335510 --- /dev/null +++ b/API-Server/index.html @@ -0,0 +1,1820 @@ + + + + + + + + + + + + + + +API Server - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

API Server

+

Faraday Server API

+

Faraday has a RESTful API under _api url prefix where the server is configured (example: https://server.faradaysec.com:5985/_api/v3/)

+

The Faraday REST API enables you to interact with our server. Use this API to interact or integrate with Faraday server. [This page] documents the REST API, with HTTP response codes and example requests and responses.

+

We have a Swagger page to explore the api here:

+

Faraday Server API Description

+

Faraday has a Server RESTful API by default running on 127.0.0.1:5985.

+
+

INFO: +On cloud, you have to replace this with "https://yourdomain.faradaysec.com/"

+
+

You can check all API endpoints with the command:

+
$ faraday-manage show-urls
+
+

Methods

+

POST: creates objects

+

GET: get a list of objects or get one object given its object_id

+

PUT: update object

+

DELETE: delete object

+

Headers

+

Our API endpoints support JSON and you must always include the header:

+
Content-Type: application/json
+
+

Authentication

+

The server API requires authentication. Currently, we support cookie authentication.

+

The endpoint for login is /_api/login and the json payload is: +

{"email": "USERNAME", "password": "SECRET_PASSWORD"}
+

+

Endpoints +Faraday Config: +Here are the list of API endpoints for license, users, workspace and authentication:

+
(HEAD, POST, OPTIONS, GET) -> '/login' 
+(HEAD, OPTIONS, GET) -> '/logout' 
+(HEAD, OPTIONS, GET) -> '/session'
+(HEAD, POST, OPTIONS, GET) -> '/change' 
+(HEAD, OPTIONS, GET) -> '/config' 
+(HEAD, OPTIONS, GET) -> '/_api/v3/licenses/'
+(POST, OPTIONS) -> '/_api/v3/licenses/'
+(OPTIONS, DELETE) -> '/_api/v3/licenses/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/licenses/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/licenses/<object_id>/'
+(OPTIONS, DELETE) -> '/_api/v3/users/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/users/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/users/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/users/'
+(POST, OPTIONS) -> '/_api/v3/users/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/in'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/'
+(POST, OPTIONS) -> '/_api/v3/ws/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<object_id>/'
+
+

Host

+

This API endpoint allows you to change the Host objects:

+

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/hosts/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/count/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/countVulns/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/hosts/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/hosts/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/<host_id>/services/'
+(DELETE, OPTIONS) -> '/_api/v3/ws/<workspace_name>/hosts/bulk_delete/'
+
+JSON Body of the Host object:

+
{
+    "ip":"test",
+    "hostnames": [],
+    "mac":"00:00:00:00:00:00",
+    "description":"",
+    "default_gateway":"None",
+    "os":"",
+    "owned":false,
+    "owner":""
+}
+
+

Services

+

This API endpoint allows you to change the Service objects:

+
(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/services/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/services/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/services/count/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/services/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/services/<object_id>/'  
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/services/<object_id>/'
+
+

JSON Body of the Service object:

+
{
+    "name":"test",
+    "description":"",
+    "owned":false,
+    "owner":"",
+    "ports":[8080],
+    "protocol":"tcp",
+    "parent":1156,
+    "status":"open",
+    "version":"",
+    "type":"Service" 
+}
+
+

Vulnerability +This API endpoint allows you to change the Vulnerability objects:

+
(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/vulns/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/count/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/timeline/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/vulns/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/vulns/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/<vuln_id>/attachment/<attachment_filename>/' 
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace>/upload_report'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tags/'
+
+

JSON Body of the Vulnerability object:

+
+

INFO: key named type can be:

+

vulnerability: Normal vulnerability, the parent could be a service or a host. +vulnerability_web: Web vulnerability, the parent can only be a service. +

{
+    "owner":"faraday",
+    "parent":1156,
+    "parent_type":"Host",
+    "type":"Vulnerability",
+    "ws":"api",
+    "confirmed":true,
+    "data":"",
+    "desc":"Testing API",
+    "impact": 
+    {
+        "accountability":false,
+        "availability":false,
+        "confidentiality":false,
+        "integrity":false
+    },
+    "name":"test",
+    "owned":false,
+    "policyviolations":[],
+    "refs":[],
+    "resolution":"",
+    "severity":"high",
+    "issuetracker":"",
+    "status":"opened",
+    "_attachments":{},
+    "description":"",
+    "protocol":"",
+    "version":""
+}
+

+

Tasks

+

This API endpoint allows you to change the Task objects:

+

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tasks/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/tasks/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tasks/count/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/tasks/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tasks/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/tasks/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/taskGroups/manualimport/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/import/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/count/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/taskGroups/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/taskGroups/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/taskGroups/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/task_template/'
+(POST, OPTIONS) -> '/_api/v3/task_template/'
+(OPTIONS, DELETE) -> '/_api/v3/task_template/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/task_template/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/task_template/<object_id>/'
+(OPTIONS, DELETE) -> '/_api/v3/methodology_template/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/methodology_template/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/methodology_template/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/methodology_template/'
+(POST, OPTIONS) -> '/_api/v3/methodology_template/'
+
+JSON Body of the Task object:

+
{
+    "name":"test", 
+    "type":"TaskGroup", 
+    "group_type":"instance", 
+    "instance_of":"", 
+    "tCompletedtasks":0, 
+    "totaltasks":0
+}
+
+

Reports +This API endpoint allows you to create reports from the API and download them:

+

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/reports/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/count/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/countVulns/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/listTemplates/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/reports/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/reports/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/<report_id>/download/'
+
+JSON Body of the Reports object:

+
{
+    "name":"Testing-API",
+    "tags":[],
+    "title":"Network XYZ",
+    "enterprise":"ACMEINC",
+    "scope":"Scope",
+    "objectives":"Objetives",
+    "summary":"Summ",
+    "confirmed":false,
+    "conclusions":"Conclusions",
+    "recommendations":"Recommendations",
+    "vuln_count":4,
+    "template_name":"generic_default.docx",
+    "grouped":false
+}
+
+

Vulnerability Template

+

This API endpoint allows you to change the Vulnerability Template (VulnDB) objects:

+
(HEAD, OPTIONS, GET) -> '/_api/v3/vulnerability_template/'
+(POST, OPTIONS) -> '/_api/v3/vulnerability_template/'
+(OPTIONS, DELETE) -> '/_api/v3/vulnerability_template/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/vulnerability_template/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/vulnerability_template/<object_id>/'
+
+

JSON Body of the Vulnerability Template object:

+
{
+    "cwe":"",
+    "description":"Test",
+    "desc":"",
+    "exploitation":"high",
+    "name":"Testing API",
+    "references":[],
+    "refs":[],
+    "resolution":"",
+    "type":"vulnerability_template"
+}
+
+

Credentials +This API endpoint allows you to change the Credential objects:

+

(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/credential/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/credential/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/credential/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/credential/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/credential/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/credential/count/'
+
+JSON Body of the Credentials object:

+
{
+    "name":"Test",
+    "username":"faraday",
+    "password":"changeme",
+    "type":"Cred",
+    "parent_type":"Host",
+    "parent":"1147",
+    "owner":"",
+    "description":""
+}
+
+

Activity Feed

+

This API endpoint allows you to change the Activity Feed (from Dashboard) objects:

+
(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/activities/count/'
+(HEAD, OPTIONS, GET) ->  '/_api/v3/ws/<workspace_name>/commands/activity_feed/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/activities/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/activities/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/activities/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/activities/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/activities/'
+
+

Comments

+

This API endpoint allows you to change the Comment objects:

+
(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/comment/count/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/comment/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/comment/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/comment/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/comment/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/comment/'
+
+

Commands

+

This API endpoint allows you to change the Commands objects: +

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/commands/count/'
+(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/commands/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/commands/<object_id>/'
+(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/commands/<object_id>/'
+(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/commands/'
+(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/commands/'
+

+

Others:

+
(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/comment_unique/'
+
+

Examples

+

Assuming that our credentials are: +

username: faraday
+
+password: changeme
+

+

Login: in order to be able to login through the API, you must supply your credentials and store them in a cookie file just as the following example: +

    curl -s 'http://127.0.0.1:5985/_api/login' \
+        -H 'Origin: http://127.0.0.1:5985/' -H 'Accept-Encoding: gzip, deflate, br' \
+        -H 'Accept-Language: en-US,en;q=0.9' \
+        -H 'Content-Type: application/json' \
+        -H 'Accept: application/json, text/javascript, */*; q=0.01' \
+        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \
+        -H 'Connection: keep-alive' \
+        --data-binary '{"email":"faraday","password": "changeme"}' \
+        --compressed -c cookie.txt > /dev/null
+

+

Creating a host: assuming our workspace name is test:

+
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/hosts/ \
+        -d '{"ip":"127.0.0.1","hostnames":["testing"], "mac":"00:00:00:00:00:00","description":"Testing API", "default_gateway":"None", "os":"Linux", "owned":true, "owner":""}' \
+        -b cookie.txt \
+        -H 'Content-Type: application/json'
+
+

Getting a list of hosts:

+
curl -X GET http://127.0.0.1:5985/_api/v3/ws/test/hosts/ -b cookie.txt
+
+

Creating a service:

+
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/services/ \
+        -d '{"name":"Test","description":"Testing API", "owned":true, "owner":"","ports":[8080],"protocol":"tcp","parent":1157,"status":"open","version":"","metadata":{"update_time":1533152663.994,"update_user":"","update_action":0,"creator":"","create_time":1533152663.994,"update_controller_action":"UI Web New","owner":""},"type":"Service"}' \
+        -b cookie.txt \
+        -H 'Content-Type: application/json'
+
+

Creating a vuln:

+
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/vulns/ \
+        -d '{"metadata":{"update_time":1533152883.927, "update_user":"", "update_action":0,"creator":"UI Web", "create_time":1533152883.927, "update_controller_action":"UI Web New", "owner":"faraday"}, "obj_id":"", "owner":"faraday", "parent":1157, "parent_type":"Host","type":"Vulnerability","ws":"test","confirmed":true,"data":"","desc":"New vulnerability created for API purposes","easeofresolution":"simple","impact":{"accountability":false, "availability":false, "confidentiality":false, "integrity":false},"name":"New Vuln - Testing API","owned":false,"policyviolations":[],"refs":[], "resolution":"", "severity":"critical", "issuetracker":"", "status":"opened","_attachments":{},"description":"","protocol":"","version":""}' \
+        -b cookie.txt \
+        -H 'Content-Type: application/json'
+
+

Creating a user:

+
    curl -X POST http://127.0.0.1:5985/_api/v3/users/ \
+        -d '{"name":"faraday", "password":"changeme", "roles":["admin"], "type":"user", "role":"admin"}' \
+        -b cookie.txt \
+        -H 'Content-Type: application/json'
+
+

Generating a report:

+
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/reports/ \
+        -d '{"name":"Testing-API","tags":[], "title":"", "enterprise":"", "scope":"", "objectives":"", "summary":"", "confirmed":false, "conclusions":"", "recommendations":"", "vuln_count":2, "template_name":"generic_default.docx", "grouped":false}' \
+        -b cookie.txt \
+        -H 'Content-Type: application/json'
+
+

Uploading a report:

+

In order to be able to upload a report, you need the CSRF token and session's cookies. To get session's cookie, go to the Status Report and take it from RequestHeaders section of the console. And to get the CSRF token, in the same console, go to the tab Response.

+

On the first --form parameter,put the path of the file that you want to upload.

+
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/api/upload_report \
+       -H 'Content-Type: multipart/form-data' \
+       --cookie "session=.eJw90M2KwjAQB_BXWXL2YGu9CB6UlGJhpgSCZeZS2FpNJ2YXqkI24rtv18O-wO__8VTdeRpuTm3u02NYqG48qc1TfXyqjWK9SyyUYVsWmMrUWDei9Etsj4FaDKydw-Qj5KZo9CWSNUu2uzXktQM5XSnxyJVZgTaRrYkk-xEt5ZQfVmT3DmcfKvrhcBQUKMgeIoQysb0knjMh-QIEliyQQzJZ0-IV_kx7DWDZY1WPmNCD9Fv1Wqj-Np27-7cfvv4noNTSVCZjXSaYK2KgiLqMTTtX1H7daMpmPnLFgtpHSk7YbN_c4zZM7ztUoV6_3rRiDA.DkoypQ.q7eGzh1oof8dKnbF4q6xD_n1d6o" \
+       --form "file=@PATH/TO/FILE" \
+       --form "csrf_token=IjYyYzhkNWQxMzA4MTZmMTQxMTliYTA5OTg2NWYzMWRmYzQ5MWM4Y2Ui.Dko4Zw.sZ-LLdGoxaNFUaySFFQMvyLecxc" \
+       --compressed
+
+

Using the API to create a workspace

+

Here we provide a Python script using requests to create a new workspace:

+
# -*- coding: utf-8 -*-
+import click
+from requests import Session
+
+@click.command()
+@click.option('--username', prompt=True)
+@click.option('--password', prompt=True)
+@click.option('--server_address', prompt=True, help='Faraday server url', default='http://localhost:5985/')
+@click.option('--workspace_name', prompt=True)
+def create_workspace(username, password, server_address, workspace_name):
+    print('Authentication to server {0}'.format(server_address))
+    session = Session()
+    # authentication to faraday server
+    session.post(server_address + '/_api/login', json={'email': 'faraday', 'password': 'Password123'})
+    # create new workspace
+    ws_payload = {
+            "customer":"",
+            "name":workspace_name,
+            "type":"Workspace",
+            "users":["faraday"],
+            "public":False,
+            "children":[],
+            "duration":{"start_date":"","end_date":""},
+            "scope":[],
+            "description":""
+            }
+
+    res = session.post(server_address + '/_api/v3/ws/', json=ws_payload)
+    assert res.status_code == 201
+    print('Workspace {0} created'.format(workspace_name))
+
+
+create_workspace()
+
+

Using the API to create users in bulk

+
curl -s  'http://127.0.0.1:5985/_api/login' \
+        -H 'Origin: http://127.0.0.1:5985/' -H 'Accept-Encoding: gzip, deflate, br' \
+        -H 'Accept-Language: en-US,en;q=0.9' \
+        -H 'Content-Type: application/json' \
+        -H 'Accept: application/json, text/javascript, */*; q=0.01' \
+        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \
+        -H 'Connection: keep-alive' \
+        --data-binary '{"email":"faraday","password": "changeme"}' \
+        --compressed -c cookie.txt 
+
+
+while read -r line; do
+    curl -X POST http://127.0.0.1:5985/_api/v3/users/ \
+        -d '{"name":"'$line'","password":"Password123","roles":["client"],"type":"user","role":"client"}' \
+        -H 'Content-Type: application/json' \
+        -b cookie.txt
+done < "users.txt"
+
+

Using the API to delete hosts in bulk

+
curl -X DELETE http://127.0.0.1:5985/_api/v3/ws/test/hosts/bulk_delete/ \
+-d '{"hosts_ids": [ 1, 2, 3, 4]}' \
+-b cookie.txt \
+-H 'Content-Type: application/json'
+
+

Upload evidence to a Vulnerability

+

Remember to change the workspace name in the urls and vuln id to attach evidence.

+
curl -s  'http://127.0.0.1:5985/_api/login' \
+        -H 'Content-Type: application/json' \
+        -H 'Accept: application/json, text/javascript, */*; q=0.01' \
+        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \
+        -H 'Connection: keep-alive' \
+        --data-binary '{"email":"faraday","password": "changeme"}' \
+        --compressed -c cookie.txt 
+
+

obtain csrf token to upload files

+

csrf_token=$(curl -s -X GET http://127.0.0.1:5985/_api/session -b cookie.txt -c csrf_cookie.txt| python -c "import sys, json; print json.load(sys.stdin)['csrf_token']")

+

Upload the file evidence.png

+
curl 'http://localhost:5985/_api/v3/ws/demo_workspace/vulns/251/attachment/' \
+          -H 'Connection: keep-alive' --data-binary $'------WebKitFormBoundary4RCsZGBu1aaCqyxT\r\nContent-Disposition: form-data;name="csrf_token"\r\n\r\$csrf_token\r\n------WebKitFormBoundary4RCsZGBu1aaCqyxT\r\nContent-Disposition: form-data; name="file"; filename="evidence.png"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundary4RCsZGBu1aaCqyxT--\r\n' \ 
+          --compressed -c csrf_cookie.txt
+
+

Upload reports (XML results from tools) using curl

+

Please check the URLs and use the correct workspace name!

+
curl -s  'http://127.0.0.1:5985/_api/login' \
+        -H 'Origin: http://127.0.0.1:5985/' -H 'Accept-Encoding: gzip, deflate, br' \
+        -H 'Accept-Language: en-US,en;q=0.9' \
+        -H 'Content-Type: application/json' \
+        -H 'Accept: application/json, text/javascript, */*; q=0.01' \
+        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \
+        -H 'Connection: keep-alive' \
+        --data-binary '{"email":"faraday","password": "changeme"}' \
+        --compressed -c cookie.txt 
+
+csrf_token=$(curl -s -X GET http://127.0.0.1:5985/_api/session -b cookie.txt -c csrf_cookie.txt | python -c "import sys, json; print json.load(sys.stdin)['csrf_token']")
+echo $csrf_token
+
+echo ";currentUrl=%2Fstatus%2Fws%2Ftest1; currentComponent=status" >> cookie.txt
+curl -i -v http://127.0.0.1:5985/_api/v3/ws/test1/upload_report \
+        -H "Connection: keep-alive" \
+        -H "Pragma: no-cache" \
+        -H "Cache-Control: no-cache" \
+        -H "Accept: application/json, text/plain, */*" \
+        -H "Origin: http://127.0.0.1:5985/" \
+        -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36" \
+        -H "Content-Type: multipart/form-data" \
+        -H "Referer: http://127.0.0.1:5985/" \
+        -H "Accept-Encoding: gzip, deflate, br" \
+        -H "Accept-Language:  en-US,en;q=0.9,es;q=0.8" \
+        --form "csrf_token=$csrf_token" \
+        --form "file=@/PATH/TO/FILE" \
+        -b csrf_cookie.txt 
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/API-Token/index.html b/API-Token/index.html new file mode 100644 index 00000000000..bb5b12bb853 --- /dev/null +++ b/API-Token/index.html @@ -0,0 +1,947 @@ + + + + + + + + + + + + + + +API Token - Faraday + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

API Token

+

Upon faraday v3.9 we included an API Token for our api. +The token for the API will expire when the user changes the password.

+

You can configure token expiration in the [server] section of the configuration with the option api_token_expiration expressed in seconds.

+

Token expires by timeout or when the user changes the password. +Each token is associated to the user who requests the token.

+

This is a example request of how to obtain a token

+
curl --user USER:PASSWORD http://localhost:5985/_api/v3/token/
+"eyJhbGciOiJIUzUxMiIsImlhdCI6MTYxOTAzMTU3OCwiZXhwIjoxNjIxNjIxNzc4fQ.eyJ1c2VyX2lkIjoiZjNjYTUyNjYtOWU2ZS00NzQwLWI0NWItN2Y2M2JkZWMzN2UwIiwidmFsaWRhdGlvbl9jaGVjayI6IiQ1JHJvdW5kcz01MzUwMDAkVDZ3cy9ZMGFHUW10UnEzSSRpRS5OSG1oaDNWR0h4VXIudVpRNGRnaEVVUXFiS09pWGg5VGdrTURtQXIwIn0.gu6AgQ-iIvdnrHBphBfzWopn5B21D_RvTFvltcoMnksAj0eHhfh7dkJW4GfjhZPQd02RBAsb3vvUUCA0fORvfw"
+
+

Now that you got the auth token you can start using it on every request to the api:

+
curl 'http://localhost:5985/_api/v3/ws/' -H 'Authorization:Token AUTH_TOKEN' -H 'Content-Type: application/json' 
+
+
import requests
+session = requests.Session()
+user = 'faraday'
+password = 'yourpassword'
+session.auth = (user, password)
+auth = session.post('https://localhost:5985/_api/v3/token')
+response = session.get('https://localhost5985/_api/v3/token')
+print(response.text) ## now the token is in response
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Activity-Dashboard/index.html b/Activity-Dashboard/index.html new file mode 100644 index 00000000000..fa6767609e9 --- /dev/null +++ b/Activity-Dashboard/index.html @@ -0,0 +1,937 @@ + + + + + + + + + + + + + + +Activity Dashboard - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Activity Dashboard

+

Activity dashboard provides a quick view with graphics and an Activity Feed that will display in an effective view all the changes and stats for the workspace.

+

+

The Central view Vulnerabilities by Severities provides a New Filter that will allow to display confirmed or not closed Vulnerabilities, to show an overall but modifying the scope.

+

+

There are new Latest tags also linked to the vuln view to quickly access to some tag from the activity dashboard.

+

+

Comments will show all the latest comments in a selected Workspace

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Architecture/index.html b/Architecture/index.html new file mode 100644 index 00000000000..ac2c1a2241f --- /dev/null +++ b/Architecture/index.html @@ -0,0 +1,1018 @@ + + + + + + + + + + + + + + +Arch - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Technical introduction

+

Faraday is a web application, the Server is made with python using Flask and the frontend is made with AngularJS (we are moving to ReactJS). It is deployed as a standard WSGI application. Its possible to interact with the Server using Faraday CLI and you can automatize tool usage with Faraday agent.

+

Faraday architecture overview

+

The data is persisted within a PostgreSQL database, processed with python libraries as SQLAlchemy and Marshmallow.

+

The server has other main components as the Report Processor, or the Websocket Server. The latter provides information to the CLI and the Agents.

+

Faraday CLI

+

Faraday CLI provides an interface for interacting with a terminal that allows the user to execute commands which results will be loaded inside Faraday Server. +The CLI also allows the user to upload tool reports, create workspaces and configure your instance.

+

Faraday Agent

+

The Faraday Agents allows to automate the upload of different data to the server, such as integration with other applications or services; or execute some tools that the Faraday plugins can process. Moreover, the Agents can be executed on any remote computer and its Executors can be written in any language.

+

Burp / Zap Addons

+

Faraday has Burp/Zap Extensions that run inside the third party application. Using Faraday addons provides flexibility to ingress information inside Faraday Server from other applications.

+

Appendix

+

Database schema

+

Faraday manage command can generate the current database schema with:

+
faraday-manage database-schema
+
+ +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Assets-and-Services-v4/index.html b/Assets-and-Services-v4/index.html new file mode 100644 index 00000000000..3c45b1a5f61 --- /dev/null +++ b/Assets-and-Services-v4/index.html @@ -0,0 +1,1084 @@ + + + + + + + + + + + + + + +Assets and Services - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Assets and Services

+

You can manage your Assets and their associated Services by accessing the Hosts View in the Manage section through the Faraday Web UI.

+

How to Manage Assets

+

+

Create an Asset

+

From the Assets View, click Add Asset and fill out the form
+The only mandatory field is IP v4 or v6

+

+

Edit an Asset

+

From the Assets View, click on the Asset IP field

+

+

The services list will be displayed and on the left side you click on Edit button to +add or modify details (hostnames, MAC address, owned, OS, description)

+

+

Delete an Asset

+

From the Assets View, select one or more assets and click Delete

+

+

How to Manage Services

+

To manage services for an specific asset, click on the asset IP field you would like to make changes

+

+

The services associated to the asset will be displayed, you can also see how many +vulnerabilites again each service

+

+

Create a Service

+

From the Services window, click New and fill out the form
+Name, Port and Protocol fields are mandatory

+

+

Edit a Service

+

From the Services window, select the service and click Edit

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Backup-v4/index.html b/Backup-v4/index.html new file mode 100644 index 00000000000..d929ac071b1 --- /dev/null +++ b/Backup-v4/index.html @@ -0,0 +1,1028 @@ + + + + + + + + + + + + + + +Backup - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Backup

+

Saving backups is always a good choice, whether it is to keep data safe or to share with others.

+

Faraday configuration and evidence backup

+

Faraday server stores configuration, processed reports and saves evidence in the directory /home/faraday/.faraday. +Remember to do a backup of this directory of the user running faraday-server.

+

Database backup

+

In order to create a backup for your database, follow these steps:

+
    +
  1. +

    Stop Faraday Server. +

    sudo service faraday-service stop
    +

    +
  2. +
  3. +

    In order to backup your Faraday database, execute the PostgreSQL tool: +

    sudo pg_dump faraday > backup_file
    +

    +
  4. +
  5. +

    Where faraday is the default name of Faraday's database and backup_file is the file where the pg_dump will save your data.

    +
  6. +
  7. +

    Start the Faraday Server +

    sudo service faraday-service start
    +

    +
  8. +
+

Database restore

+

To restore a previously created backup turn again Faraday Server off and execute: +

sudo service faraday-service stop
+sudo psql faraday < backup_file
+sudo service faraday-service start
+

+
+

Remember
+To restore the backup you need to have the database empty.

+
+

For more information about PostgreSQL Backup follow this link

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Basic-plugin-development/index.html b/Basic-plugin-development/index.html new file mode 100644 index 00000000000..e1b0e291f15 --- /dev/null +++ b/Basic-plugin-development/index.html @@ -0,0 +1,1633 @@ + + + + + + + + + + + + + + +Plugin Development - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Plugin Development

+

In this guide we are going to learn how to develop a new plugin for Faraday.

+

Configure Custom Plugins

+

To add custom plugins in faraday, you first need to run this command:

+
faraday-manage settings -a update reports
+
+
+

Create Plugin structure

+

Create the folder new_plugin inside the custom_plugins folder and add the following files inside the new_plugin folder:

+

Plugin Structure:

+
new_plugin/
+    __init__.py # leave this file empty
+    plugin.py
+
+
+

Warning

+

Please respect both file names: +__init__.py and plugin.py

+
+
+

Plugin code

+

There are two types of plugins:

+
    +
  • File plugins (plugins that process the contents of a file)
  • +
  • Command plugins (plugins that process the execution of a command)
  • +
+

A faraday plugin can be either or both of these types. +For example the ping plugin only process the execution of the command, but the nmap command supports both the xml generated by nmap or process the execution of nmap.

+

In your plugin.py file you must provide a function called createPlugin for the plugin manager to instantiate the plugin

+
def createPlugin(ignore_info=False, hostname_resolution=True):
+    return YourPluginClass(ignore_info=ignore_info)
+
+

Plugin classes

+

PluginBase is the base class.

+

For File plugins we provide all this classes. +But you can add other by creating a subclass of PluginByExtension

+
    +
  • PluginBase
  • +
  • PluginByExtension
      +
    • PluginXMLFormat
    • +
    • PluginJsonFormat
    • +
    • PluginMultiLineJsonFormat
    • +
    • PluginCSVFormat
    • +
    • PluginZipFormat
    • +
    +
  • +
+

For Command plugins only you must inherit from PluginBase

+

Your plugin class __init__ method must define the id, that will be the identifier of your plugin.

+

Here's an example of the Ping tool plugin: +

class CmdPingPlugin(PluginBase):
+    def __init__(self, *arg, **kwargs):
+        super().__init__(*arg, **kwargs)
+            self.id = "ping"
+            self.name = "Ping"
+            self.plugin_version = "0.0.1"
+            self.version = "1.0.0"
+            self._command_regex = re.compile(r'^(sudo ping|ping|sudo ping6|ping6)\s+.*?')
+

+

Beware that it must be unique, you can list all the plugins identifiers with this command: faraday-plugins list-plugins

+

File Plugins

+

Each of the subclasses for File plugins provide a different way for the plugin to detect if it can process the file

+
PluginByExtension:
+

This class adds the functionality for identify a file by its extension by setting the attribute extension.

+

It can be one extension (".xml") or a list (['.xml', '.xxx']) if your file can have multiple extensions.

+

You never inherit directly from this class in a plugin but from some of its subclasses that are more specific.

+
class ExampleXMLTool(PluginByExtension):
+
+        def __init__(self):
+            super().__init__()
+            self.extension = ".xml"
+
+
PluginXMLFormat:
+

Use this class if the plugin generates vulnerabilities from a xml file.

+

If your report has xml format but a different extension (like nessus), remember to define the extension attribute

+

To identify the file set in the identifier_tag attribute the main tag of the xml (ScanGroup in the example), it also can be one tag or a list of tags.

+

You can also set the identifier_tag_attributes attribute, it is a set of attributes that the main tag must have.

+

This is used to be more specific for example if the main tag is too generic and the xml of other plugin has the same one.

+

Example XML +

<?xml version="1.0"?>
+<ScanGroup ExportedOn="2021-11-05T11:18:57.673843">
+    <Scan>
+    </Scan>
+</ScanGroup>
+

+
from urllib.parse import urlparse
+from faraday_plugins.plugins.plugin import PluginXMLFormat
+import xml.etree.ElementTree as ET
+
+class ExampleToolXmlParser:
+
+    def __init__(self, xml_output):
+        self.vulns = self.parse_xml(xml_output)
+
+    def parse_xml(self, xml_output):
+        vulns = []
+        tree = ET.fromstring(xml_output)
+        items = tree.iterfind('details/item')
+        for item in items:
+            ip = item.get('ip')
+            os = item.get('os')
+            uri = item.find('uri').text
+            url = urlparse(uri)
+            hostname = [url.netloc]
+            path = url.path
+            if url.scheme == 'https':
+                port = 443
+            else:
+                port = 80
+            issue = item.find('issue')
+            severity = issue.get('severity')
+            issue_text = issue.text
+            vuln = {'ip': ip, 'uri': uri, 'os': os,
+                    'hostname': hostname, 'port': port, 'path': path,
+                    'issue_text': issue_text, 'severity': severity}
+            vulns.append(vuln)
+        return vulns
+
+
+class ExampleToolPlugin(PluginXMLFormat):
+    def __init__(self, *arg, **kwargs):
+        super().__init__(*arg, **kwargs)
+        self.identifier_tag = "example_tool"
+        self.id = "example_tool"
+        self.name = "Name of the tool"
+        self.plugin_version = "0.0.1"
+
+    def parseOutputString(self, output, debug=False):
+        parser = ExampleToolXmlParser(output)
+        for vuln in parser.vulns:
+            h_id = self.createAndAddHost(vuln['ip'], vuln['os'], hostnames=vuln['hostname'])
+            s_id = self.createAndAddServiceToHost(h_id, 'webserver', protocol='tcp', ports=vuln['port'])
+            v_id = self.createAndAddVulnWebToService(h_id, s_id, vuln['issue_text'], severity=vuln['severity'],
+                                                    path=vuln['path'])
+
+def createPlugin(*args, **kwargs):
+    return ExampleToolPlugin(*args, **kwargs)
+
+
PluginJsonFormat:
+

Use this class if the plugin generates vulnerabilities from a json file.

+

If yor report has json format but a different extension (not .json), remember to define the extension attribute

+

To identify the file set in the json_keys attribute a set with some identifiers keys of the json object

+

Example JSON +

{
+  "name": "some name",
+  "hosts": ["host1", "host2"],
+  "other_field": "some value"
+}
+

+
class ExampleJsonTool(PluginJsonFormat):
+    def __init__(self, ignore_info):
+        super().__init__(ignore_info)
+        self.json_keys = {'name', 'hosts'}
+
+
PluginMultiLineJsonFormat:
+

Is the same as PluginJsonFormat but use it when the file has multiple lines and every line is a json.

+

Example JSON +

{ "name": "some name", "hosts": ["host1", "host2"],"other_field": "some value"}
+{ "name": "other name", "hosts": ["host3", "host4"],"other_field": "other value"}
+

+
class ExampleMultipleJsonTool(PluginMultiLineJsonFormat):
+    def __init__(self, ignore_info):
+        super().__init__(ignore_info)
+        self.json_keys = {'name', 'hosts'}
+
+
PluginCSVFormat:
+

Use this class if the plugin generates vulnerabilities from a csv file.

+

If yor report has csv format but a different extension (not .csv), remember to define the extension attribute

+

To identify the file set in the csv_headers attribute a set with some identifiers headers of the csv object

+

Example CSV +

name,ip,os
+host1,10.10.10.10,windows
+host2,10.10.10.11,linux
+

+
class ExampleCSVTool(PluginCSVFormat):
+    def __init__(self, ignore_info):
+        super().__init__(ignore_info)
+        self.json_keys = {'name', 'ip'}
+
+
PluginZipFormat:
+

Use this class if the plugin generates vulnerabilities from a zip file.

+

If yor report has csv format but a different extension (not .zip), remember to define the extension attribute

+

To identify the file set in the files_list attribute a set with some file names inside the zip file.

+
class ExampleJsonTool(PluginZipFormat):
+    def __init__(self, ignore_info):
+        super().__init__(ignore_info)
+        self.files_list = {'file1.txt', 'file2.txt'}
+
+
Generating data
+

The PluginBase class give you all the main methods to create hosts, services and vulnerabilities

+

After you parse the data you will need to create the objects with the information to send to faraday. +This are the main methods

+
def createAndAddHost(self, name, os="unknown", hostnames=None, mac=None, scan_template="", site_name="",
+                    site_importance="", risk_score="", fingerprints="", fingerprints_software=""):
+
+def createAndAddServiceToHost(self, host_id, name, protocol="tcp?", ports=None, status="open", version="unknown",
+                            description=""):
+
+def createAndAddVulnToHost(self, host_id, name, desc="", ref=None, severity="", resolution="", vulnerable_since="", 
+                            scan_id="", pci="", data="", external_id=None, run_date=None):
+
+def createAndAddVulnToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="", 
+                            risk="", data="", external_id=None, run_date=None):
+
+def createAndAddVulnWebToService(self, host_id, service_id, name, desc="", ref=None, severity="", resolution="",
+                                website="", path="", request="", response="", method="", pname="",
+                                params="", query="", category="", data="", external_id=None, run_date=None):
+
+

createAndAddHost and createAndAddServiceToHost will give you a host ID and a service ID. +You need to send those to the create vulnerabilities methods

+

The main method to parse data and create the vulnerabilities objects is parseOutputString, no mather if is a File or a Command plugin.

+

Command Plugins

+

For command plugins the detection is done via regex.

+

If the plugin is only for command you inherit from PluginBase if it also will support file detection inherit from the appropriate class for that type of file.

+

In both cases to detect a command you will need to set the _command_regex attribute with the regex to match the command

+

Here's an example of the Ping tool plugin: +

class CmdPingPlugin(PluginBase):
+    def __init__(self, *arg, **kwargs):
+        super().__init__(*arg, **kwargs)
+            self.id = "ping"
+            self.name = "Ping"
+            self.plugin_version = "0.0.1"
+            self.version = "1.0.0"
+            self._command_regex = re.compile(r'^(sudo ping|ping|sudo ping6|ping6)\s+.*?')
+
+    def parseOutputString(self, output):
+        reg = re.search(r"PING ([\w\.-:]+)( |)\(([\w\.:]+)\)", output)
+        if re.search("0 received|unknown host", output) is None and reg is not None:
+            ip_address = reg.group(3)
+            hostname = reg.group(1)
+            self.createAndAddHost(ip_address, hostnames=[hostname])
+        return True
+
+    def _isIPV4(self, ip):
+        if len(ip.split(".")) == 4:
+            return True
+        else:
+            return False
+

+

In this case the plugin manager will run the command and send the output to the parseOutputString method.

+

But if the tool generate an ouput file instead of send the data to stdout you will need to check that the command has the required parameters to do that.

+

To do that you will need to implement the processCommandString method, by default it will return the command without modifications.

+

To use output files you will need to set 2 attributes in you plugin: _use_temp_file and _temp_file_extension

+

If _use_temp_file is set the plugin will create a temp file and assign its path to the attribute self._output_file_path of the plugin.

+

If you need that the temp file has and specific extension use the _temp_file_extension attribute like in the example.

+

If the _use_temp_file attribute is set the plugin will send te content of that file to parseOutputString()instead of the output of the command.

+

Here is and extract of the nmap plugin to see how processCommandString will modify the original command and return a new command with the required parameters.

+
class NmapPlugin(PluginXMLFormat):
+    """
+    Example plugin to parse nmap output.
+    """
+
+    def __init__(self, *arg, **kwargs):
+        super().__init__(*arg, **kwargs)
+        self.identifier_tag = "nmaprun"
+        self.id = "Nmap"
+        self.name = "Nmap XML Output Plugin"
+        self.plugin_version = "0.0.3"
+        self.version = "6.40"
+        self.framework_version = "1.0.0"
+        self.options = None
+        self._current_output = None
+        self._command_regex = re.compile(r'^(sudo nmap|nmap|\.\/nmap)\s+.*?')
+        self._use_temp_file = True
+        self._temp_file_extension = "xml"
+        self.xml_arg_re = re.compile(r"^.*(-oX\s*[^\s]+).*$")
+        self.addSetting("Scan Technique", str, "-sS")
+
+    def parseOutputString(self, output):
+        ...
+
+    def processCommandString(self, username, current_path, command_string):
+        """
+        Adds the -oX parameter to get xml output to the command string that the
+        user has set.
+        """
+        super().processCommandString(username, current_path, command_string)
+        arg_match = self.xml_arg_re.match(command_string)
+        if arg_match is None:
+            return re.sub(r"(^.*?nmap)",
+                          r"\1 -oX %s" % self._output_file_path,
+                          command_string)
+        else:
+            return re.sub(arg_match.group(1),
+                          r"-oX %s" % self._output_file_path,
+                          command_string)
+
+

Full Example

+
+
+

This is an example of a Faraday Plugin that process a xml report.

+

In this example we will create a plugin to analyze this XML provided by the output of a tool.

+

example.xml +

 <?xml version="1.0" ?>
+<!DOCTYPE example_tool>
+<example_tool scanstart="Thu Nov  9 15:59:13 2017">
+    <details>
+    <item id="999979" ip="10.23.49.232" os="linux">
+    <uri>http://test.com/example.php</uri>
+    <issue severity="low">Some vuln text</issue>
+    </item>
+    <item id="39023023" ip="10.232.62.20" os="linux">
+    <uri>http://test.com/login.php</uri>
+    <issue severity="low">Some other text</issue>
+    </item>
+    <item id="8348343" ip="10.12.37.24" os="linux">
+    <uri>http://test.com/example.php</uri>
+    <issue severity="low">Yet another vuln text</issue>
+    </item>
+    <statistics elapsed="402" itemsfound="3" itemstested="10" />
+    </details>
+</example_tool>
+

+

plugin.py

+
from urllib.parse import urlparse
+from faraday_plugins.plugins.plugin import PluginXMLFormat
+import xml.etree.ElementTree as ET
+
+class ExampleToolXmlParser:
+
+    def __init__(self, xml_output):
+        self.vulns = self.parse_xml(xml_output)
+
+    def parse_xml(self, xml_output):
+        vulns = []
+        tree = ET.fromstring(xml_output)
+        items = tree.iterfind('details/item')
+        for item in items:
+            ip = item.get('ip')
+            os = item.get('os')
+            uri = item.find('uri').text
+            url = urlparse(uri)
+            hostname = [url.netloc]
+            path = url.path
+            if url.scheme == 'https':
+                port = 443
+            else:
+                port = 80
+            issue = item.find('issue')
+            severity = issue.get('severity')
+            issue_text = issue.text
+            vuln = {'ip': ip, 'uri': uri, 'os': os,
+                    'hostname': hostname, 'port': port, 'path': path,
+                    'issue_text': issue_text, 'severity': severity}
+            vulns.append(vuln)
+        return vulns
+
+
+class ExampleToolPlugin(PluginXMLFormat):
+    def __init__(self):
+        super().__init__()
+        self.identifier_tag = "example_tool"
+        self.id = "example_tool"
+        self.name = "Name of the tool"
+        self.plugin_version = "0.0.1"
+
+    def parseOutputString(self, output, debug=False):
+        parser = ExampleToolXmlParser(output)
+        for vuln in parser.vulns:
+            h_id = self.createAndAddHost(vuln['ip'], vuln['os'], hostnames=vuln['hostname'])
+            s_id = self.createAndAddServiceToHost(h_id, 'webserver', protocol='tcp', ports=vuln['port'])
+            v_id = self.createAndAddVulnWebToService(h_id, s_id, vuln['issue_text'], severity=vuln['severity'],
+                                                    path=vuln['path'])
+
+def createPlugin(ignore_info=False, hostname_resolution=True):
+    return ExampleToolXmlParser(ignore_info=ignore_info)
+
+
+

Test and Debug

+

You can test your plugin by enabling the custom_plugins_folder setting, and try it with faraday.

+

You can also test your plugin from the command line.

+
Test Plugins
+

List all available plugins

+

Verify that the plugins is loaded by the plugin manager

+
faraday-plugins list-plugins
+
+Available Plugins:
+...
+...
+...
+example_tool - Name of the tool
+Loaded Plugins: 84
+
+

Test plugin report detection

+

Verify that your file is detected by your plugin

+
faraday-plugins detect-report /path/to/report.xml
+
+Plugin: example_tool
+
+

Test plugin process report

+

Verify that your plugin parses the file ok and generate the json structure that will be loaded into faraday

+
faraday-plugins process-report /path/to/report.xml
+
+
+{"hosts": [{"ip": "10.23.49.232", "os": "linux", "hostnames": ["test.com"], "description": "", "mac": null, "credentials": [], "services": [{"name": "webserver", "protocol": "tcp", "port": 80, "status": "open", "version": "unknown", "description": "", "credentials": [], "vulnerabilities": [{"name": "Some vuln text", "desc": "", "severity": "low", "refs": [], "external_id": null, "type": "VulnerabilityWeb", "resolution": "", "data": "", "website": "", "path": "/example.php", "request": "", "response": "", "method": "", "pname": "", "params": "", "query": "", "category": ""}]}], "vulnerabilities": [], "scan_template": "", "site_name": "", "site_importance": "", "risk_score": "", "fingerprints": "", "fingerprints_software": ""}, {"ip": "10.232.62.20", "os": "linux", "hostnames": ["test.com"], "description": "", "mac": null, "credentials": [], "services": [{"name": "webserver", "protocol": "tcp", "port": 80, "status": "open", "version": "unknown", "description": "", "credentials": [], "vulnerabilities": [{"name": "Some other text", "desc": "", "severity": "low", "refs": [], "external_id": null, "type": "VulnerabilityWeb", "resolution": "", "data": "", "website": "", "path": "/login.php", "request": "", "response": "", "method": "", "pname": "", "params": "", "query": "", "category": ""}]}], "vulnerabilities": [], "scan_template": "", "site_name": "", "site_importance": "", "risk_score": "", "fingerprints": "", "fingerprints_software": ""}, {"ip": "10.12.37.24", "os": "linux", "hostnames": ["test.com"], "description": "", "mac": null, "credentials": [], "services": [{"name": "webserver", "protocol": "tcp", "port": 80, "status": "open", "version": "unknown", "description": "", "credentials": [], "vulnerabilities": [{"name": "Yet another vuln text", "desc": "", "severity": "low", "refs": [], "external_id": null, "type": "VulnerabilityWeb", "resolution": "", "data": "", "website": "", "path": "/example.php", "request": "", "response": "", "method": "", "pname": "", "params": "", "query": "", "category": ""}]}], "vulnerabilities": [], "scan_template": "", "site_name": "", "site_importance": "", "risk_score": "", "fingerprints": "", "fingerprints_software": ""}], "command": {"tool": "example_tool", "command": "example_tool", "params": "/path/to/report.xml", "user": "faraday", "hostname": "", "start_date": "2020-04-01T18:43:34.552623", "duration": 2650, "import_source": "report"}}
+
+

You can optionally specify the plugin id to not do the detection step and force to process it with the specific plugin

+
faraday-plugins process-report --plugin_id YourPluginId /path/to/report.xml
+
+
+{"hosts": [{"ip": "10.23.49.232", "os": "linux", "hostnames": ["test.com"], "description": "", "mac": null, "credentials": [], "services": [{"name": "webserver", "protocol": "tcp", "port": 80, "status": "open", "version": "unknown", "description": "", "credentials": [], "vulnerabilities": [{"name": "Some vuln text", "desc": "", "severity": "low", "refs": [], "external_id": null, "type": "VulnerabilityWeb", "resolution": "", "data": "", "website": "", "path": "/example.php", "request": "", "response": "", "method": "", "pname": "", "params": "", "query": "", "category": ""}]}], "vulnerabilities": [], "scan_template": "", "site_name": "", "site_importance": "", "risk_score": "", "fingerprints": "", "fingerprints_software": ""}, {"ip": "10.232.62.20", "os": "linux", "hostnames": ["test.com"], "description": "", "mac": null, "credentials": [], "services": [{"name": "webserver", "protocol": "tcp", "port": 80, "status": "open", "version": "unknown", "description": "", "credentials": [], "vulnerabilities": [{"name": "Some other text", "desc": "", "severity": "low", "refs": [], "external_id": null, "type": "VulnerabilityWeb", "resolution": "", "data": "", "website": "", "path": "/login.php", "request": "", "response": "", "method": "", "pname": "", "params": "", "query": "", "category": ""}]}], "vulnerabilities": [], "scan_template": "", "site_name": "", "site_importance": "", "risk_score": "", "fingerprints": "", "fingerprints_software": ""}, {"ip": "10.12.37.24", "os": "linux", "hostnames": ["test.com"], "description": "", "mac": null, "credentials": [], "services": [{"name": "webserver", "protocol": "tcp", "port": 80, "status": "open", "version": "unknown", "description": "", "credentials": [], "vulnerabilities": [{"name": "Yet another vuln text", "desc": "", "severity": "low", "refs": [], "external_id": null, "type": "VulnerabilityWeb", "resolution": "", "data": "", "website": "", "path": "/example.php", "request": "", "response": "", "method": "", "pname": "", "params": "", "query": "", "category": ""}]}], "vulnerabilities": [], "scan_template": "", "site_name": "", "site_importance": "", "risk_score": "", "fingerprints": "", "fingerprints_software": ""}], "command": {"tool": "example_tool", "command": "example_tool", "params": "/path/to/report.xml", "user": "faraday", "hostname": "", "start_date": "2020-04-01T18:43:34.552623", "duration": 2650, "import_source": "report"}}
+
+

If you do not have faraday-server installed or don't have the custom_plugins_folder setting, you can use the --custom_plugins_folder parameter with any if the commands (list, detect and process)

+

Example:

+
faraday-plugins list-plugins --custom-plugins-folder /home/user/.faraday/plugins/
+
+
Logging
+

In the PluginBase there is a logger defined in self.logger that you can use.

+

If you need to debug for plugins with the command line set this variable:

+
export PLUGIN_DEBUG=1
+faraday-plugins process-report appscan /path/to/report.xml
+2019-11-15 20:37:03,355 - faraday.faraday_plugins.plugins.manager - INFO [manager.py:113 - _load_plugins()]  Loading Native Plugins...
+2019-11-15 20:37:03,465 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [acunetix]
+2019-11-15 20:37:03,495 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [amap]
+2019-11-15 20:37:03,549 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [appscan]
+2019-11-15 20:37:03,580 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [arachni]
+2019-11-15 20:37:03,613 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [arp_scan]
+2019-11-15 20:37:03,684 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [beef]
+2019-11-15 20:37:03,714 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [brutexss]
+2019-11-15 20:37:03,917 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [burp]
+2019-11-15 20:37:03,940 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [dig]
+...
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Burp-proxy-extender/index.html b/Burp-proxy-extender/index.html new file mode 100644 index 00000000000..33318cad33c --- /dev/null +++ b/Burp-proxy-extender/index.html @@ -0,0 +1,1131 @@ + + + + + + + + + + + + + + +Burp - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Burp

+

This plugin is a script developed in Java as a extender to the Burp Proxy API (Pro/Community).

+

Installation

+

From the App Store

+

You can install the Burp extension from the Burp App Store

+

+

From file

+

Download the jar from this link

+

Once you have it, follow these steps:

+
    +
  • +

    Go to Extender->Extensions and click in the Add button.

    +
  • +
  • +

    In the Extension Details section, the extension type should be Java, and select the file.

    +
  • +
+

+
    +
  • +

    Click Next, and if everything went well, you should see no errors and you can close the window.

    +
  • +
  • +

    Now, make sure the extension is loaded in the Extensions tab.

    +
  • +
+

+

Extension configuration

+

Once the Faraday extension is loaded into your Burp, you will see a new tab called "Faraday".

+

+

Here, you can login to Faraday and you can edit the extension's settings:.

+

Login to Faraday

+

In order to connect the Faraday's Burp extension to Faraday, follow these steps:

+

1) Set your Faraday Server URL. This should point to the same URL that you use when you are connecting to Faraday Server, e.g: http://127.0.0.1:5985

+

2) Connect Burp to Faraday by clicking on the Connect button.

+

+

3) Once you are connected, type your Faraday's credentials: username, password and 2FA Token (if it is the case).

+

4) Login into Faraday by click on the Login button. If everything goes well, Burp should pop up a Login successful! modal.

+

+

5) Once you are logged in, you can edit the extension's settings.

+

Extension Settings

+

+

From here, you can:

+

1) Choose the workspace where you want to work on.

+

2) Choose whether the vulnerabilities should be imported automatically or not (it's disabled by default).

+

3) Import the vulnerabilities you've found so far.

+

4) Check if you want to use only Burp scope.

+

Send to Faraday

+

Once you have everything setup, you can send the issues or requests to Faraday.

+

+

!!! warning "REMEMBER: If the request is missing the response, the information can't be sent to faraday! +REMEMBER 2: Vulnerabilities will only work with commercial versions of burp"

+

Other Settings

+

+

From here, you can Restore Settings to default.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 00000000000..ab9e081a65f --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +docs.faradaysec.com diff --git a/Comments/index.html b/Comments/index.html new file mode 100644 index 00000000000..e24176d547e --- /dev/null +++ b/Comments/index.html @@ -0,0 +1,930 @@ + + + + + + + + + + + + +Comments & Notifications - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Comments & Notifications

+

Now, you can enrich Vuln data by leaving Comments and Notes, while mentioning other users to notify them about important events in real time. Also, you are now able to configure alerts to follow up on each project, having a more efficient view of their status and updates.

+

The idea behind this is promoting better ways to get involved with your co-workers by improving communication and daily results.

+

Usage +Go into the vulnerability preview (by clicking in the name of the vulnerability). Then click on Comments tab:

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Contact-us/index.html b/Contact-us/index.html new file mode 100644 index 00000000000..72aff083134 --- /dev/null +++ b/Contact-us/index.html @@ -0,0 +1,1039 @@ + + + + + + + + + + + + + + +Contact Us - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+ +
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Custom-Fields-v4/index.html b/Custom-Fields-v4/index.html new file mode 100644 index 00000000000..7c87ba253c1 --- /dev/null +++ b/Custom-Fields-v4/index.html @@ -0,0 +1,1041 @@ + + + + + + + + + + + + + + +Custom Attributes - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+ +
+
+
+

Custom Attributes

+

Custom Attributes allow you to extend the vulnerability's model with more fields. Custom attributes type can be int, +string, choice, date, markdown and list.

+

If you want to learn more about the usage of Custom Attributes through Faraday's API, follow this +link.

+

How to create Custom Attributes

+

From Web UI

+

You can create/edit/delete a Custom Attribute clicking in the Custom Attributes button from the Column Order icon.

+

+

Let's create one as an example:

+
    +
  • +

    You must fill the following fields in order to create a Custom Attribute:

    +
      +
    • name: the display name that you will see on the vulnerability form.
    • +
    • Type: data type of the field.
    • +
    +

    +
  • +
  • +

    After successfully creating the Custom Attribute, you will see it on the vulnerability form:

    +
  • +
+

+

From Terminal (local install only)

+

Step 1: Add custom attribute

+
$ faraday-manage add-custom-field 
+
+

Step 2: After the command execution, you will be prompted by a wizard where you must input the following information:

+
    +
  • Field name: the name of the field.
  • +
  • Display name: the display name that you will see on the vulnerability form.
  • +
  • Type: data type of the field, it can be: int, string, choice, markdown and list.
  • +
  • Order: the order shown on the vulnerability form.
  • +
+

The following example will add the CVSS field to the vulnerability model:

+
This wizard will guide you to ADD custom attributes to the vulneraiblity model.
+Field name: cvss
+Display name: CVSS
+Field type (int, str, list) (int, str, list): str
+Field order index: 0
+New CustomField will be added to vulnerability -> Order 0 (cvss,CVSS,str) <-, confirm to continue (yes/no): yes
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Dashboard-v4/index.html b/Dashboard-v4/index.html new file mode 100644 index 00000000000..b0124c7c1f0 --- /dev/null +++ b/Dashboard-v4/index.html @@ -0,0 +1,1095 @@ + + + + + + + + + + + + + + +Dashboard - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Dashboard

+

Faraday's Dashboard contains a summary of all data within a Workspace. Each box is a visualization for an specific aspect of the collected information.

+

When you create a new Workspace an empty dashboard will look as below

+

+

Once you start adding data by importing scans, running tools, etc, it will be like this

+

+

Let's see in more detail the functionality and information displayed in the dashboard

+

Switching Workspaces

+

Top left corner next to F you can see the current Workspace, click on it and +a drop-list will be displayed to switch between Workspace quickly

+

+

Progress and Vulnerabilities Distribution/Counters

+

Percentage of time spend using Workspace settings (start/end date) +and pie charts for vulnerabilies by Severity and Status also total counters +of vulnerabilities by Severity included

+

+

Activity Feed

+

Users and actions with results performed on the workspace for quickly seeing the +progress been made on the workspace

+

+

Last Vulnerabilities

+

Quick list of latest vulnerabilities added into the workspace

+

+

Service Report

+

A counter view of Services found in the workspace

+

+

Workspace Summary

+

An overall summary of Hosts, Services and Vulnerabilties found so far

+

+

Hosts

+

List of Assets and Vulnerabilities currently in the workspace.

+

+

Tags

+

View of the recent used tags.

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Development-setup/index.html b/Development-setup/index.html new file mode 100644 index 00000000000..d673e6a55ee --- /dev/null +++ b/Development-setup/index.html @@ -0,0 +1,1371 @@ + + + + + + + + + + + + +Development setup - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Development setup

+

To use faraday follow the new Faraday Install Guide. This is for development

+

Index

+ +

Topics

+

Faraday Server

+

Faraday Server is the interface between PostgreSQL and Faraday Client and WebUI. The server's responsibility is to transmit information between the client or WebUI and PostgreSQL, and make sure that they are kept in sync. The Web UI client, which allows you to handle enormous workspaces from your favorite web browser.

+

Important: You should keep in mind that is recommended to install Faraday server on the same instance as PostgreSQL.

+

Downloading

+

Clone the Faraday Git Project repository and checkout the dev branch:

+
$ git clone https://github.com/infobyte/faraday.git faraday-dev
+$ cd faraday-dev
+$ pip install .
+
+

After doing so, make sure to install system dependencies, install Python dependencies and configure the Server.

+

Requirements

+

Faraday Server is built with minimum requirements. This is by design, so you can install it even on the most bare-bones machine you can possibly imagine.

+

The Python requirements for the server are stored in the requirements.

+

Installing system dependencies

+
Debian based distributions (Debian, Ubuntu, Backtrack, etc)
+

Or if you wanna do it manually you can run the following command to install the required dependencies on any Debian based distribution.

+

$ sudo apt update
+
+$ sudo apt install build-essential ipython python3-setuptools \
+                python3-pip python3-dev libssl-dev \
+                libffi-dev pkg-config libxml2-dev \
+                libxslt1-dev libfreetype6-dev libpng-dev postgresql libpq-dev
+
+Warning: If you already have postgresql installed, please corroborate the version is upper than 9.4.

+
Kali Linux
+

If you are running Kali, please run the following commands:

+
$ sudo apt-get update
+$ sudo apt-get install build-essential ipython python-setuptools \
+                python-pip python-dev libssl-dev \
+                libffi-dev pkg-config libxml2-dev \
+                libxslt1-dev libfreetype6-dev libpng-dev
+
+
Others
+

Please consult with your distribution documentation to install the dependencies listed above.

+

Creating a virtualenv

+

Before installing Faraday, we need to create a virtualenv so Faraday runs in it. In order to install and create a virtualenv, run the following commands:

+
$ pip install virtualenv
+$ virtualenv -p python3 faraday_venv
+$ source faraday_venv/bin/activate
+
+

For more information about virtualenv, please follow this link.

+

+

Installing Python 3 dependencies

+

Once you have the required system dependencies, you just have to install the Python modules needed to run the server using:

+
$ python setup.py develop
+
+

+

Initializing PostgreSQL

+

In order to initialize PostgreSQL database, run the following command:

+
faraday-manage initdb
+
+

IMPORTANT: The command initdb will create a random password for the admin user, remeber to COPY THE PASSWORD. You can use the command faraday-manage change-password if you want to change it.

+

Note: You sould have the PostgreSQL service started. To do it run +systemctl start postgresql or the equivalant command for your GNU/Linux +distro.

+

Note: if at the moment you run this command, it throws an error, be sure +you have sudo installed. Once you have installed it, run the command again.

+

Manual PostgreSQL configuration

+

If you need an advance configuration of the postgres database, like having a +custom database name or run it in a separate host, the faraday-manage initdb +command probably won't be enough for you, so you should configure it manually +by doing something like this:

+
sudo -u postgres psql -c "CREATE ROLE faraday_postgresql WITH LOGIN PASSWORD 'YOURPASSWORD'"
+sudo -u postgres createdb -O faraday_postgresql faraday
+
+

Then, edit the ~/.faraday/config/server.ini by adding the connection string +to the database:

+
[database]
+connection_string = postgresql+psycopg2://faraday_postgresql:YOURPASSWORD@localhost/faraday
+
+

Then you should run faraday-manage create-tables to create all the required +tables to make faraday work, and faraday-manage createsuperuser to create an +admin user.

+

Manually importing from CouchDB

+

If you were using Faraday 2.7.2 and setup the database manually instead of +using the faraday-manage initdb, you should run the following command to import +the data from CouchDB:

+
$ python manage.py import-from-couchdb
+
+

Updating Nginx configuration

+

Note: This only applies if you are using Nginx and https.

+

Please, make sure you have this settings on your Nginx config:

+
1
+2
proxy_pass http://localhost:5985/;
+proxy_redirect http:// $scheme://;
+
+

Configuration

+

By default, Faraday server will listen on port 5985. You can edit this on ~/.faraday/config/server.ini.

+

Exposing the Server

+

If you wish to access the Server form a different box you need to expose the service. In order to do so, edit the server configuration file and set the bind_address param to 0.0.0.0.

+

Edit the file located in ~/.faraday/config/server.ini and under the section [faraday-server] set the param, it should look something like this:

+
[faraday-server]
+...
+bind_address=0.0.0.0
+
+

Then restart the server if you had it running and reload your browser in case you were already trying to access the Web UI form a different IP.

+

faraday-server also allow to use --bind and --port to override server.ini settings.

+

Running

+

Once everything is installed and the server is configured, you can proceed to run the Faraday server script:

+
$ faraday-server
+
+

If you want to run the server in background mode, you should use the --start option:

+
$ faraday-server --start
+
+

This is the recommended way to do this. Other methods like using the bash & could cause unexpected IOErrors and other related exceptions.

+

Web UI

+

Once the server is running, you can access Faraday's Web UI using any browser: +just point it to http://SERVER_IP:SERVER_PORT/ (by default it will be +http://localhost:5985/) and you can start playing with Faraday.

+

+

Faraday Client

+

Faraday Client is the software which will allow you to work with your favorite security tools and capture their output in an organized manner. It works under a GTK+3 interface with the popular VTE terminal with a custom ZSH shell that respects the user's configuration (yes, that means you get to keep your exact ZSH terminal inside Faraday, even if you use ZPrezto or Oh My ZSH).

+

From the client you can also create and delete workspaces, specify plugin configuration, view information about your hosts, resolve conflics that may arise and much more.

+

It's also a responsibility of the client to send all of the collected information to the server, which will then process it and format it in an friendly way for you to view, edit, and confirm.

+

The client is bundled in the same package as the server, so if you have already downloaded Faraday, you can skip the next step.

+

Downloading

+

Download the latest tarball or clone the Faraday Git Project repository and checkout dev branch:

+
1
+2
+3
$ git clone https://github.com/infobyte/faraday.git faraday-dev
+$ git checkout dev
+$ cd faraday-dev
+
+

Requirements

+

Faraday Client works under any modern Linux distribution or Mac OS X, and needs Python 3.6+.

+

The Python requirements for the client are stored in the requirements.txt file. Some additional requirements are necessary for specific features to work, these are stored in the requirements_extras.txt file.

+

Out tests include Debian, Ubuntu, Kali, Backtrack.

+

+

Installing system dependencies

+

+
Debian and derivatives
+

You can run the following command to install the required dependencies on any Debian based distribution.

+
$ sudo apt update
+
+

If you are running Ubuntu 12.04 LTS, or Ubuntu 14.04 LTS, please execute this command:

+
$ sudo apt install libpq-dev python-pip python-dev gir1.2-gtk-3.0 gir1.2-vte-2.90 python-gobject zsh curl
+
+

If you are any other version, please execute the following command:

+
$ sudo apt install libpq-dev python-pip python-dev gir1.2-gtk-3.0 gir1.2-vte-2.91 python-gobject zsh curl
+
+

Gentoo

+

This are the dependencies for Gentoo with Emerge:

+
dev-libs/gobject-introspection net-libs/webkit-gtk x11-libs/gtk+ \
+x11-libs/vte dev-python/pygobject app-shells/zsh net-misc/curl dev-python/ipython
+
+

Extras dependencies:

+
dev-python/beautifulsoup dev-python/gevent-psycopg2
+
+

Using GTK client with virtualenv

+

If you are working inside a Virtual enviroment you need to follow this extra steps for GTK to work: +

pip install vext
+pip install vext.pygtk
+pip install vext.gi
+

+

+

Configuration

+

Now you need to configure every Faraday instance so it can connect to the server.

+
    +
  • If you're using the GTK interface click on the Preferences icon and fill in the server URL, for example http://127.0.0.1:5985
  • +
+

+
    +
  • If you are using the --gui=no-gui option
  • +
+

Edit the file: ~/.faraday/config/user.xml +And search for the following api_uri tag and set it to the server URL, for example:

+

<api_uri>http://127.0.0.1:5985</api_uri>

+

If you are using SSL you need to use https in your configuration. For example use https://192.168.0.20 when you are using an nginx server with SSL enabled and faraday-server is listening on 192.168.0.20.

+

Running

+

Once you have already configured the client and have Faraday Server running, you simply have to run:

+
$ faraday-client
+
+

Some distributions or installations require additional steps, so look down below if you are using something different than Debian or Ubuntu, or if you need to apply some configuration to the client.

+

+
Kali
+

Faraday comes pre-installed in Kali Rolling. The package name is python-faraday. Keep in mind that this package can only be used for the Community edition.

+

In order to run Faraday in Kali: +

$ systemctl start postgresql.service
+$ cd /usr/share/python-faraday
+$ faraday-server
+$ faraday-client
+

+

Due to Kali's package updates the pre-installed package may not be the last version. If you want the latest updates use the Debian install steps.

+
Gentoo
+

If you are running Gentoo, this are the dependencies with Emerge:

+
dev-python/flask-sqlalchemy dev-python/service_identity dev-python/twisted \
+dev-python/pyopenssl dev-java/mockito dev-python/Whoosh \
+dev-python/configargparse dev-python/restkit dev-python/requests www-servers/tornado \
+dev-python/flask dev-python/colorama dev-python/setuptools dev-python/pip dev-libs/libpqxx \
+libffi-dev
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/FAQ/index.html b/FAQ/index.html new file mode 100644 index 00000000000..b7357ba7f4b --- /dev/null +++ b/FAQ/index.html @@ -0,0 +1,1312 @@ + + + + + + + + + + + + + + +FAQs - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

FAQs

+

+

Index

+ +

Is your question not listed here? Contact us

+

Topics

+

+

Where does the name come from?

+

The name was picked to honor Michael Faraday, an English scientist whose main discoveries include electromagnetism induction, diamagnetism and electrolysis. Mainly his six principles of scientific discipline, acquired at a young age from Isaac Watts' "The Improvement of the mind": +* Always carry a small pad to take notes at any time +* Maintain abundant correspondence +* Collaborate regularly with others to exchange ideas +* Avoid controversy +* Verify everything that was said to him +* Do not generalize, speak and write as precisely as possible

+

Read more at:
+https://en.wikipedia.org/wiki/Michael_Faraday
+http://www.eng.auburn.edu/~sjreeves/cm/improve.html

+

+

What is Faraday?

+

Faraday is a multiuser integrated penetration test and vulnerability management environment. It is to Penetration Testing what an IDE is to Development. The main purpose of Faraday is to re-use the available tools in the community to take advantage of them in a multiuser way.

+

+

Is Faraday free?

+

Yes, we have a Community version which is totally free, you can download it from Github We also have two Commercial versions, details about those in our webpage.

+

Compare different versions of Faraday

+

+

Does Faraday have collaboration tools?

+

Faraday supports over 80 tools. Full plugin list available here.

+

+

Which platforms are supported?

+

RedHat, CentOS, Fedora, Debian, Kali, Ubuntu, Docker.

+

+

Does Faraday work on my servers or on the cloud?

+

Yes it does, depending on your needs. For more information you can contact us at sales@infobytesec.com

+

+

What are the system requirements to run Faraday?

+

CPU: 2 Dualcore 2GHz Intel CPU
+Disk: 40 GB
+Memory: 4 GB RAM (8 GB RAM recommended)

+

Current tests include Debian, Ubuntu, Kali, and Backtrack.

+

If instead of installing you want to take a quick look at Faraday you can also use Docker.

+

+

I purchased a License, now what?

+

You will receive an email with a link to download everything regarding your license. If you haven’t received it or are having issues, please contact us at sales@infobytesec.com.

+

+

Can I keep using the Kali version with my newly bought Professional/Corporate license?

+

In a nutshell, yes. Even though the Kali Faraday version is incompatible with both the Professional and Corporate licenses, you can upgrade the platform in the same box without losing all your data.

+

You will need to remove the package python-faraday and then you need to install the pro/corp .deb with apt install ./faraday-server_amd64.deb

+

+

Can I install the Server and/or Client in my own box instead of using a Virtual Machine you provided?

+

The only intended purpose for the Faraday VM is as a commercial demo.

+

For production environments we recommend doing a fresh install in a Ubuntu Server, please do not use your provided Demo License VM.

+

If the use of a Virtualized environment is a must-have, then we recommend doing a proper install in a fresh Virtual Machine following the regular installation steps.

+

+

How do I know which Faraday Version I'm using?

+

By running faraday-server --version or hovering your mouse over the Faraday logo at the top left of the Web UI. Latest version and information available in the Upgrading Faraday section.

+

To get the latest available version:

+ +

+

What if I want to add a Vulnerability manually?

+

You can do this using our Web UI, read our documentation on manually adding vulnerabilities.

+

+

How do I bind Faraday to 0.0.0.0?

+

Just go to /home/faraday/.faraday/config/server.ini and inside the [faraday-server] section write:

+

bind_address=0.0.0.0

+

Restart Faraday Server if you had it running. That's it!

+

+

Where are my credentials?

+

When installing Faraday you run the following command:

+
faraday-manage initdb
+
+

and get your credentials on the terminal (something like this):

+

username: faraday
+password: a7e8d3seWqy5
+
+If you don't remember this, below, you can see how to re-generate them.

+

+

I lost my credentials

+

If during the instalation you forget to store or keep your credentials, don't worry, you can either create a new admin user or change the default admin user:

+

Change faraday default admin user (enter the new password): +

$ faraday-manage change-password
+
+
    Username: faraday
+    Password:
+    Repeat for confirmation:
+    Password changed succesfully
+

+

Create a new admin user (Only for paid users): +

$ faraday-manage create-superuser
+
+
    Username: admin
+    Email: admin@example.com
+    Password:
+    Repeat for confirmation:
+    User admin created successfully!
+

+

Is your question not listed here?

+

Generate a support ticket to get aid from our Help Desk staff.

+

If you are using Faraday community, you can reach us by using our GitHub issues page.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Faraday-Manage-Settings-v4/index.html b/Faraday-Manage-Settings-v4/index.html new file mode 100644 index 00000000000..5f74047f61a --- /dev/null +++ b/Faraday-Manage-Settings-v4/index.html @@ -0,0 +1,1050 @@ + + + + + + + + + + + + + + +Faraday Manage Settings - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Faraday Manage Settings

+

The purpose of this documentation is to explain how to use faraday-manage settings

+

Update executive reports configuration

+

To update executive reports configuration to enable markdown +

faraday-manage settings -a update executive_reports
+
+markdown: True
+border_size: 3
+
+Then restart your Faraday Server instance +
systemctl restart faraday-server
+

+

Update SMTP configuration

+

To setup your SMTP configurations

+
faraday-manage settings -a update smtp
+
+enabled:
+username
+host:
+port: 
+sender: 
+ssl:
+
+

Then update every field to the desired configuration

+

Update reports configuration and custom plugin folder

+

To update the custom plugin folder run the following command +

faraday-manage settings -a update reports
+
+ignore_info_severity[False]: 
+custom_plugins_folder:
+

+

Then update the field custom plugin folder to the specified path

+

Enable SAML

+

To enable SAML and update the SAML configuration, +

faraday-manage settings -a update saml
+
+enabled[False]: 
+display_name [Identity Provider]:
+identity_id []:
+user_role [admin]:
+attribute_identifier []:
+sso_url [http://localhost/saml/login]:
+sp_certificate []:
+sp_private_key []:
+idp_certificate []:
+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Faraday-Manage/index.html b/Faraday-Manage/index.html new file mode 100644 index 00000000000..2c98b29d4d1 --- /dev/null +++ b/Faraday-Manage/index.html @@ -0,0 +1,1407 @@ + + + + + + + + + + + + + + +Faraday Manage - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Faraday Manage

+

Faraday Manage is a backend tool that helps us administrate Faraday's configuration.

+

To use Faraday Manage, you can run it as follow:

+
$ faraday-manage COMMAND
+
+

If you run only faraday-manage, it will list you all the available commands.

+

+

Available Commands

+

add-custom-attribute

+

This command allows you to create Custom Fields from the terminal. For more information about Custom Fields, you can see their wiki page

+

change-password

+

It allows you to change your user's password

+

create-superuser

+

The name says it all! This is the way to create a new admin user through the command line.

+

create-tables

+

This command allows the user to manually create a table on Faraday's database. It would come in handy if something in the initdb command fails for example.

+

create workspace

+

Create workspace

+

database-schema

+

This will print a PNG image with Faraday's internal working scheme.

+

delete-custom-field

+

It allows you to delete a Custom Field from terminal

+

generate-nginx-config

+

This command displays the nginx config example to be added in nginx config

+

generate-roles-permission

+

This command displays the roles permission in a JSON file

+

generate-rsa-keys

+

It will create an RSA key for integrations

+

import-license

+

Imports Faraday License.

+

import-methodologies

+

Imports methodologies and tasks from a csv file

+

import-vulnerability-templates

+

Imports vuln templates from a file

+

initdb

+

This command needs to be executed only at the moment of Faraday's installation. It will create the tables of the database, Faraday's user among other things.

+

If you try to execute this a second time it will indeed fail.

+
+

Danger

+

Warning: Please do not lose the random password that this command will print on the screen. It will be necessary to login into Faraday.

+
+

list-plugins

+

Lists available plugins.

+

load-samples

+

Loads pre-loaded samples for config, attributes, searchfilters, pipelines and planner

+

migrate

+

Migrates database schema.

+

openapi-yaml

+

Show URLs in OpenApi format

+

remove-rsa-keys

+

Remove RSA key pair generated for an...

+

rename-user

+

Change username.

+

settings

+

It allows you to manage settings inside faraday configuration

+

show-rsa-keys

+

Show RSA key pair for an integration's

+

show-urls

+

Prints a list of all the URLs available to communicate with our API Rest.

+

sql-shell

+

This command will open a PostgreSQL shell already configured with Faraday's user and configuration.

+

take-stats-snapshot

+

Generates vulnerabilities stats of the analytics and workspace view.

+

update-enrichment-database

+

Download latest enrichment database

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Faraday-Zap-extension/index.html b/Faraday-Zap-extension/index.html new file mode 100644 index 00000000000..e97243d863f --- /dev/null +++ b/Faraday-Zap-extension/index.html @@ -0,0 +1,1007 @@ + + + + + + + + + + + + +Faraday Zap extension - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Faraday Zap extension

+

Importing to Faraday a XML report generated by OWASP Zap

+

Faraday Zap Extension

+

Using Faraday Zap Extension

+

With Faraday Zap Extension, you are able to send new issues directly from OWASP Zap into Faraday.

+

Download Faraday Zap Extension

+

The first thing we need to do is to download Faraday Zap Extension.

+

Configuring Faraday Zap Extension

+

Once we have downloaded it, we need to load it into OWASP Zap. You can load an add-on as the sample image below or by typing [Ctrl + L]:

+

+

Now we need to authenticate into the Faraday Zap extension by using our Faraday's credentials. Go into Tools/Faraday configuration options or type [Ctrl+Alt+F]:

+

+

Type your credentials and set the Faraday Server URL to the correct one. Then click Login:

+

+

Once you are logged in, you can go to the Configuration tab and select the workspace where you want to work in:

+

+

Note: by clicking on Refresh, you can update your workspaces from Faraday.

+

Sending requests and alerts into Faraday

+

Now that you have configured Faraday Zap extension, you can proceed to send issues into Faraday:

+
    +
  • Sending a request:
  • +
+

+
    +
  • Sending an alert:
  • +
+

+

Uninstalling Faraday Zap Extension

+

To uninstall the extension, go into Manage Add-ons, select the extension named Faraday and then click on Uninstall Selected

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Filters/index.html b/Filters/index.html new file mode 100644 index 00000000000..7295769d4ec --- /dev/null +++ b/Filters/index.html @@ -0,0 +1,1400 @@ + + + + + + + + + + + + +Search - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Search

+

Using Search Field in Faraday V 4

+

In ordear to ease the need of searching we've developed a way to use the search bar in order to be able to select the search fields and easily build the queries needed.

+

To select Vulns click on Vulnerability as the image bellow:

+

+

then select the desired Field as:

+

+

Operator value Contains:

+

+

and then type the value that will be searched:

+

+

After finishing typing hit Enter or click on the search button

+

Filters

+

Making search queries

+

Clients can make advanced searchs using the UI Clicking on the Switch to advanced mode Link, after doing this the search field will admit using a dictionary with values as the description bellow

+

{"name": <fieldname>, "op": <operatorname>, "val": <argument>}

+

The operator strings recognized by the API incude:

+
==, eq, equals, equals_to
+!=, neq, does_not_equal, not_equal_to
+>, gt, <, lt
+>=, ge, gte, geq, <=, le, lte, leq
+in, not_in
+is_null, is_not_null
+like
+ilike
+has
+any
+
+

Manage vulns (aka status report) fields

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field nameField TypeValid OperatorsConfirmed Working
namestringall
descriptionstringall
severityseverities enumeq, neq
targetstringall
servicerelationship
service.namestringall
service.portnumbereq, neq, >,>=, <, <=
easeofresolution (ease_of_resolution in model)ease_of_resolutions enumeq, neq
references (reference_instances in model)relationship
references.namestringall
resolutionstringall
datastringall
requeststringall
methodstringall
responsestringall
pname (parameter_name en el modelo)stringall
params (parameters en el model)stringall
pathstringall
query (query_string en el modelo)stringall
websitestringall
creatorrelationship
creator.usernamestringall
typevuln_types enumeq, neq
confirmedbooleaneq, neq
idnumbereq, neq, >, >=, <, <=
+

Data types

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
boolean = [ true, True, false, False ]
+
+EASE_OF_RESOLUTIONS = [
+    'trivial',
+    'simple',
+    'moderate',
+    'difficult',
+    'infeasible'
+]
+
+VULN_TYPES = [
+    'vulnerability',
+    'vulnerability_web',
+    'vulnerability_code'
+]
+
+SEVERITIES = [
+    'critical',
+    'high',
+    'medium',
+    'low',
+    'informational',
+    'unclassified',
+]
+
+STATUS = [
+    'open',
+    'closed',
+    'filtered'
+]
+
+
Some examples
+

Endpoint

+

http://localhost:5985/_api/v2/ws/testws1/vulns/filter?q={"filters": [...]}

+

Basic one

+

name == "test 1" +

{
+    "filters": [
+                { "name": "name", 
+                    "op": "eq",  
+                   "val": "test1" 
+                }
+               ]
+}
+
+With and

+

severity == medium

+
{
+    "filters": [
+                { "name": "name", 
+                    "op": "eq",  
+                   "val": "test1" 
+                },
+                { "name": "severity",  
+                    "op": "eq",
+                   "val": "medium" 
+                } 
+              ]
+}
+
+

A bit complex one

+

name like "t%" and (severity == "critical" or severity == "medium")

+

{ "filters": [ 
+                { "name": "name", "op": "like", "val": "t%"  }, 
+                {  "or": [ 
+                     { "name": "severity",    "op": "eq",    "val": "medium"  } ,
+                     { "name": "severity",    "op": "eq",    "val": "critical"  }
+                  ] 
+                 } 
+            ]
+}
+
+so to do this query it can be used something like this:

+

+

With case insensitive logic and fields with relationships

+

name ilike "%php%" and (service.name like "%http%" or service.port eq 80)

+
{ "filters": [ 
+                { "name": "name", "op": "ilike", "val": "%php%"  }, 
+                {  "or": [ 
+                     { "name": "service", 
+                        "op": "has",  
+                        "val": { "name": "name", "op": "like",  "val": "%http%" } 
+                      } ,
+                     { "name": "service", 
+                        "op": "has",  
+                       "val": { "name": "port", "op": "eq",  "val": "80" } 
+                     }
+                   ] 
+                } 
+            ]
+}
+
+

Previous filters but just the ones created by user faraday

+

name ilike "php%" and (service.name like "%http%" or service.port eq 80) and creator.username == 'faraday'

+
{ "filters": [
+                { "name": "creator", 
+                    "op": "has",
+                   "val": { "name": "username", "op": "eq",  "val": "faraday" } } ,
+                { "name": "name", "op": "ilike", "val": "%php%"  }, 
+                {  "or": [ 
+                     { "name": "service", 
+                        "op": "has",  
+                        "val": { "name": "name", "op": "like",  "val": "%http%" } 
+                      } ,
+                     { "name": "service", 
+                        "op": "has",  
+                       "val": { "name": "port", "op": "eq",  "val": "80" } 
+                     }
+                   ] 
+                } 
+            ]
+}
+
+

HOSTS

+

Manage hosts fields

+

Endpoint

+

http://localhost:5985/_api/v2/ws/testws1/hosts/filter?q={"filters": [..]

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Field nameField TypeValid Operators
ipstringall
hostnamesrelationship
hostnames.namestringall
servicesrelationship
services.namestringall
services.portnumbereq, neq, >,>=, <, <=
services.statusstatus enumeq, neq
osstringall
ownedbooleaneq, neq
vulnerability_critical_generic_countnumbereq, neq, >,>=, <, <=
vulnerability_high_generic_countnumbereq, neq, >,>=, <, <=
vulnerability_medium_generic_countnumbereq, neq, >,>=, <, <=
vulnerability_low_generic_countnumbereq, neq, >,>=, <, <=
vulnerability_info_generic_countnumbereq, neq, >,>=, <, <=
vulnerability_unclassified_generic_countnumbereq, neq, >,>=, <, <=
+

Some examples

+
{"filters": [
+       { "and":  [
+              { "name": "hostnames", 
+                  "op": "any", 
+                 "val": { "name": "name", 
+                            "op": "eq", 
+                           "val": "asdf1" 
+                        }
+              }
+          ] 
+      } 
+  ] 
+}
+
+
{"filters": [
+       { "and":  [
+              { "name": "services", 
+                  "op": "any", 
+                 "val": { "name": "port", 
+                            "op": "eq", 
+                           "val": "80" 
+                        }
+              }
+          ] 
+      } 
+  ] 
+}
+
+
{
+    "filters": [
+                { "name": "ip", 
+                    "op": "like",  
+                   "val": "192.168.0.%" 
+                }
+               ]
+}
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/First-Steps/index.html b/First-Steps/index.html new file mode 100644 index 00000000000..e9ccb3230d8 --- /dev/null +++ b/First-Steps/index.html @@ -0,0 +1,1052 @@ + + + + + + + + + + + + + + +First Steps - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

First Steps

+

Now that you have installed Faraday, we will take the first steps together in this journey

+

Accessing Faraday Web UI

+

First, navigate to Faraday Web UI and log in.

+

+

Where are my credentials?

+

Creating a Workspace

+

Faraday has the concept of Workspaces where you can put all your data +related to a project in one place, you can have many workspaces to represent +different engagements, weekly/monthly scans for internal/dmz/external networks, specific application assessments, etc

+

Details on Workspace here

+

Creating a Host

+

See how to create, edit and delete an asset in Assets and Services

+

Creating a Vuln

+

See how to create, edit and delete a vuln in Vulns

+

Creating a Report

+

See how to create, edit and delete a report in Reports

+

Getting Started

+

Using faraday to integrate your tools has never been this easy!

+

Details on Getting started here

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Getting-started/index.html b/Getting-started/index.html new file mode 100644 index 00000000000..3bd28ecb01e --- /dev/null +++ b/Getting-started/index.html @@ -0,0 +1,1012 @@ + + + + + + + + + + + + + + +First Steps - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+ +
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/How-to-build-your-template/index.html b/How-to-build-your-template/index.html new file mode 100644 index 00000000000..c24bdaa6dcc --- /dev/null +++ b/How-to-build-your-template/index.html @@ -0,0 +1,1222 @@ + + + + + + + + + + + + + + +How to Build Your Own Template - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

How to build a Template

+
+

We use Jinja2 to create Report Templates. Here are listed the main variables available when creating a Template.

+

General Variables

+

These are the variables loaded when creating a report

+
    +
  • +

    date - the date when the Report was created, as the name of the month and four digits for the year

    +
  • +
  • +

    title

    +
  • +
  • +

    enterprise

    +
  • +
  • +

    summary

    +
  • +
  • +

    conclusions

    +
  • +
  • +

    recommendations

    +
  • +
  • +

    scope

    +
  • +
  • +

    objectives

    +
  • +
+
+
+
    +
  • workspace.scope - a list containing the different scopes of the workspace.
  • +
  • workspace - a dictionary with all workspace information.
      +
    • name
    • +
    • description
    • +
    • id
    • +
    • duration.start_date
    • +
    • duration.end_date
    • +
    • users
    • +
    • update_date
    • +
    • stats.total_vulns
    • +
    • stats.std_vulns
    • +
    • stats.web_vulns
    • +
    • stats.code_vulns
    • +
    • stats.hosts
    • +
    • stats.services
    • +
    • stats.credentials
    • +
    • public
    • +
    • readonly
    • +
    • active
    • +
    • create_date
    • +
    • _id
    • +
    +
  • +
+
+

Date Format

+

start_date and end_date are displayed in timestamp format. If you want to change their format, you can use datetimeformat() function and pass the desired format as parameter. E.g.:

+
+

   workspace.duration.start_date|datetimeformat('%m-%d-%Y')
+
+   workspace.duration.end_date|datetimeformat('%B %Y')
+
+ For more information about date format check Python docs.

+
+
+
    +
  • hosts_amount - an int containing the amount of hosts in the Workspace
  • +
  • hosts - a dictionary with all the hosts in the Workspace
      +
    • type
    • +
    • description
    • +
    • default_gateway
    • +
    • ip
    • +
    • owned
    • +
    • tags
    • +
    • name
    • +
    • services
    • +
    • versions
    • +
    • mac
    • +
    • hostnames
    • +
    • vulns
    • +
    • owner
    • +
    • credentials
    • +
    • service_summaries
    • +
    • id
    • +
    • os
    • +
    • metadata
    • +
    +
  • +
+
+
+
    +
  • services_amount - an int containing the amount of services in the Workspace
  • +
  • services - a dictionary with all the services in the Workspace
      +
    • status
    • +
    • protocol
    • +
    • description
    • +
    • parent
    • +
    • tags
    • +
    • vulns
    • +
    • metadata
    • +
    • owned
    • +
    • summary
    • +
    • port
    • +
    • owner
    • +
    • version
    • +
    • host_id
    • +
    • id
    • +
    • credentials
    • +
    • type
    • +
    • ports
    • +
    • name
    • +
    +
  • +
+
+
+
    +
  • counter_severity - a dictionary with all the severities and the amount of vulns for each one vulnerability pie charts
  • +
  • vulns_amount - an int containing the amount of vulnerabilities in the Workspace except for vulns with severity unclassified, which are not included
  • +
  • vulns - a dictionary with all the vulnerabilities in the Workspace except for vulns with severity unclassified, which are not included
      +
    • update_user
    • +
    • parent_type
    • +
    • owned
    • +
    • owner
    • +
    • id
    • +
    • impact
    • +
    • confirmed
    • +
    • severity
    • +
    • service
    • +
    • data
    • +
    • policyviolations
    • +
    • evidence_subdoc
    • +
    • type
    • +
    • refs
    • +
    • metadata
    • +
    • status
    • +
    • issuetracker
    • +
    • description
    • +
    • parent
    • +
    • tags
    • +
    • easeofresolution
    • +
    • hostnames
    • +
    • data
    • +
    • host_os
    • +
    • desc
    • +
    • name
    • +
    • obj_id
    • +
    • target
    • +
    • resolution
    • +
    • severity_numbers
    • +
    • method
    • +
    • params
    • +
    • website
    • +
    • query
    • +
    • path
    • +
    • request
    • +
    • response
    • +
    +
  • +
+

Grouped reports will have an additional field: + vulns_grouped_amount - an int containing the total amount of vulnerabilities after grouping

+
+
+
+

Custom Fields in Executive Report

+

You can access your Custom Attributes on the docx templates like a dictionary and by the field name: +

vuln.custom_fields["cvss"] 
+

+

Jinja2 Context

+

For more technical information, here is the Jinja2 context, where you can find all the DataTypes and structures implemented with Jinja.

+

Template Examples

+

Here are some basic templates.

+

Default Templates

+

Default Generic/Grouped

+

Markdown Templates

+

Markdown_Grouped/Generic

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Install-guide-Advanced/index.html b/Install-guide-Advanced/index.html new file mode 100644 index 00000000000..ab3d141ea42 --- /dev/null +++ b/Install-guide-Advanced/index.html @@ -0,0 +1,1143 @@ + + + + + + + + + + + + + + +Advanced Install - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Faraday Advanced Installation with Websockets Notifications

+

Faraday, as a powerful security platform, supports sending notifications through websockets, a crucial feature also utilized by Faraday Agents. To enable and properly configure websockets in an on-premises installation, follow the comprehensive guide below.

+

Install NGINX:

+
sudo apt install nginx
+
+

Configuring NGINX

+

Use the following configuration file:

+
map $http_upgrade $connection_upgrade {
+    default upgrade;
+    ''      close;
+}
+
+server {
+    listen 443 ssl; 
+    server_name faraday.local;
+    client_max_body_size 500M;
+    ssl_session_cache shared:SSL:50m;
+    ssl_certificate /etc/ssl/faraday.crt;
+    ssl_certificate_key /etc/ssl/faraday.key;
+
+    location / {
+        alias /opt/faraday/lib/python3.10/site-packages/faraday/server/www;
+        try_files $uri $uri/ /index.html;
+    }
+
+    location /_api/ {
+        proxy_pass http://127.0.0.1:5985/_api/;
+        proxy_set_header Host $host;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Ssl on;
+        proxy_set_header X-Forwarded-Proto $scheme;
+    }
+
+
+
+    location /socket.io {
+        include proxy_params;
+        proxy_http_version 1.1;
+        proxy_buffering off;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection $connection_upgrade;
+        proxy_pass http://127.0.0.1:5985;# Expires map
+map $sent_http_content_type $expires {
+    default                    off;
+    text/html                  max;
+    text/css                   max;
+    application/javascript     max;
+    ~image/                    max;
+}
+
+server {
+    server_name replacewithyourip;
+    listen 443 ssl http2;
+
+    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
+    add_header X-XSS-Protection "1; mode = block";
+    add_header X-Frame-Options "SAMEORIGIN";
+    add_header X-Content-Type-Options nosniff;
+    client_max_body_size 5G;
+
+    ssl on;
+    ssl_session_cache shared:SSL:50m;
+    ssl_certificate           /etc/ssl/faraday.crt;
+    ssl_certificate_key       /etc/ssl/faraday.key;
+    gzip on;
+    gzip_types application/javascript text/css;
+
+    expires $expires;
+
+    location / {
+        alias /opt/faraday/lib/python3.10/site-packages/faraday/server/www/;
+        try_files $uri $uri/ /index.html;
+    }
+
+    location /_api/ {
+        proxy_pass http://{faraday-ip}:5985/_api/;
+        proxy_redirect http:// $scheme://;
+        proxy_read_timeout 6000;
+    proxy_connect_timeout 6000;
+    proxy_send_timeout 6000;
+        proxy_set_header Host $host;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Ssl on;
+        proxy_cookie_path / "/; secure";
+        proxy_set_header X-Forwarded-Proto $scheme;
+    }
+
+    location /websockets {
+        proxy_http_version 1.1;
+        proxy_pass http://{faraday-ip}:9000/websockets;
+
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
+    }
+
+    location /_api/wsocket/v1/ {
+      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+      proxy_pass http://{faraday-ip}:5000/_api/wsocket/v1/;
+      proxy_http_version 1.1;
+      proxy_set_header Upgrade $http_upgrade;
+      proxy_set_header Connection "upgrade";
+    }
+
+
+}
+
+server {
+    server_name {faraday-ip};
+    listen 80 ;
+    listen [::]:80 ;
+
+    # https redirect
+    if ($host = {faraday-ip}) {
+        return 301 https://$host$request_uri;
+    } 
+
+    return 404;
+}
+
+

Place it in /etc/nginx/sites-available.

+

Generating Certificates

+
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/faraday.key -out /etc/ssl/faraday.crt
+
+

The Common Name should be the same as the FQDN, in our case faraday.

+

Create an alias inside the file pointing front on location / to the path where the static files are.

+

Section location inside the nginx file (no need to change it): +

location / {
+    alias /home/faraday/faraday/faraday/frontend/www/;
+}
+

+

Create symlinks for sites-enabled to sites-available:

+
sudo ln -s /etc/nginx/sites-available/faraday /etc/nginx/sites-enabled/faraday
+
+

Restart NGINX:

+
sudo systemctl restart nginx
+
+

Startup the websockets server:

+
faraday-websocket-server
+
+

After this local configuration, you should see http://faraday.local with websockets up and running.

+

In case faraday.local is not resolved, check /etc/hosts for the line:

+
127.0.0.1    faraday.local
+
+

We highly recommend you to check our First Steps guide.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Install-guide-Docker/index.html b/Install-guide-Docker/index.html new file mode 100644 index 00000000000..a7450019cd3 --- /dev/null +++ b/Install-guide-Docker/index.html @@ -0,0 +1,1076 @@ + + + + + + + + + + + + + + +Docker - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Faraday Community Edition Installation Guide with Docker

+

This guide provides step-by-step instructions for installing the Community Version of Faraday using Docker. The instructions cover both running Faraday as a standalone container and as a service. Additionally, environment variables and volumes for configuration are explained in detail.

+

Configuration

+

This image can be run as a service or as a standalone container. Both run Faraday Server without PostgreSQL. You will note that we have created /faraday-storage and /faraday-config volumes (for mounting your storage and configuration). We have also created environment variables for Faraday configuration in case you don't mount a config volume. We will get more in detail of these volumes and environment variables:

+

Example:

+

Running Faraday as a standalone container +

docker run \
+    ...
+    -v /path/to/my_doc_folder:/faraday-license \
+    -v /path/to/my_storage_folder:/faraday-storage \
+    -v /path/to/my_config_folder:/faraday-config
+    ...
+    faradaysec/faraday:4.6.2
+

+

Running Faraday as a service +

vim docker-compose.yml
+version: '4.02'
+services:
+  ...
+  volumes:
+    - /path/to/{my_config_folder}:/home/faraday/.faraday
+  ...
+

+

We will get more in details about this configuration below.

+

Environment Variables

+

In case you don't have a configuration file you'll need to set some environment variables. These come with default values so you'll need to customize some or all of them depending on your installation config.

+
PGSQL_HOST=172.2.0.1 # PostgreSQL server host.
+PGSQL_USER=faraday_postgresql # PostgreSQL user
+PGSQL_PASSWD=mypgsqlpassword # PostgreSQL user's password.
+PGSQL_DBNAME=faraday # Faraday's database name
+
+

Running Faraday

+

Now that we have learnt about the volumes and the environment variables above, let's run Faraday assuming we want to connect into PostgreSQL's address 192.168.20.29 and that we have located Faraday's config folder in its default location: ~/.faraday

+

As a standalone container

+

Run the following command specifying the correct information:

+

With environment variables +

docker run \
+    -v ~/.faraday/doc:/faraday-license \
+    -v ~/.faraday/storage:/faraday-storage \
+    -p 5985:5985 \
+    -e PGSQL_HOST='192.168.20.29' \
+    -e PGSQL_PASSWD='mypgsqlpassword' \
+    -e LISTEN_ADDR='0.0.0.0' \
+    faradaysec/faraday:latest
+

+

With config volume mounted +

docker run \
+    -v ~/.faraday/doc:/faraday-license \
+    -v ~/.faraday/storage:/faraday-storage \
+    -v ~/.faraday/config:/faraday-config \
+    -p 5985:5985 \
+    faradaysec/faraday:latest
+

+

To check the container, run the following command: +

docker container ls
+

+

As you can see, Faraday Server is running on port 5985.

+

As a service

+
    +
  1. +

    Initialize a Swarm: +

    docker swarm init
    +# In case you have more than one IP addr configured in your machine you have to specify which one to use.
    +docker swarm init --advertise-addr=192.168.20.29
    +

    +
  2. +
  3. +

    Docker Compose File: Now, you need to create a docker-compose.yml file. You can use this docker-compose as an example:

    +
  4. +
+

With environment variables

+
version: '4.02' 
+
+services: 
+  server: 
+    image: faradaysec/faraday:latest
+    environment: 
+      - LISTEN_ADDR=0.0.0.0 
+      - PGSQL_HOST=192.168.20.29 
+      - PGSQL_USER=faraday_postgresql 
+      - PGSQL_PASSWD=/run/secrets/pgsql_passwd 
+      - PGSQL_DBNAME=faraday 
+    secrets: 
+      - pgsql_passwd 
+    ports: 
+      - 5985:5985 
+    volumes: 
+      - ~/.faraday/storage:/faraday-storage 
+    deploy: 
+      replicas: 1 
+      placement: 
+        constraints: [node.role == manager] 
+secrets: 
+  pgsql_passwd: 
+    external: true
+
+

When Faraday runs as a service, PGSQL_PASSWD can be configured with Docker secrets (default in docker-compose.yml). The simplest way to create a secret is reading from standard input (you should take care of bash history). +

printf mypgsqlpassword | docker secret create pgsql_passwd -
+

+

Once you have created the secret, edit your docker-compose.yml and set: +

vim docker-compose.yml
+version: 'latest'
+services:
+  ...
+  environment:
+    - PGSQL_PASSWD=/run/secrets/pgsql_passwd  
+  ...
+

+

For more information about secrets, check Docker’s web page

+

With config volume mounted +

version: '4.02' 
+
+services: 
+  server: 
+    image: faradaysec/faraday:latest
+    ports: 
+      - 5985:5985 
+    volumes: 
+      - ~/.faraday/storage:/faraday-storage 
+      - ~/.faraday/config:/faraday-config 
+    deploy: 
+      replicas: 1 
+      placement: 
+        constraints: [node.role == manager] 
+

+
    +
  1. +

    Deploy: Once you are done setting up your docker-compose.yml file, let's deploy it by running the following command: +

    docker stack deploy -c docker-compose.yml faraday
    +

    +
  2. +
  3. +

    Check service: To check the service, run the following command: +

    docker service ls
    +docker service logs faraday_server
    +

    +
  4. +
+

Web UI

+

Once Faraday Server is running, you'll have to obtain the container's IP address. For this, run: +

docker inspect $(docker ps -lq) | grep \"IPAddress
+

+

This command will throw the following output: +

"IPAddress": "172.17.0.2",
+"IPAddress": "172.17.0.2",
+

+

Now you can direct your browser to http://172.17.0.2:5985/_ui/

+

We highly recommend you to check our First Steps guide.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Install-guide-Linux/index.html b/Install-guide-Linux/index.html new file mode 100644 index 00000000000..5abfc90b00f --- /dev/null +++ b/Install-guide-Linux/index.html @@ -0,0 +1,984 @@ + + + + + + + + + + + + + + +Linux - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Installation Guide for Ubuntu/Debian/Kali

+

Requirements:

+
    +
  • Postgres
  • +
  • Redis
  • +
+

PostgreSQL

+

Please follow the installation guide from the PostgreSQL site for installing PostgreSQL >= 9.6 either local or remote.

+
# Ubuntu
+sudo apt-get install postgresql
+
+

Redis

+

Please follow the installation guide from the PostgreSQL site for installing PostgreSQL >= 9.6 either local or remote.

+
# Ubuntu
+sudo apt-get install redis
+
+

Installing Faraday

+

Step 1 - Downloading Faraday Installer

+

Download the Faraday installer (.deb or .rpm) from:

+ +

Step 2 - Installing the package

+

Go to your Download directory and run the following command:

+
# For .deb
+sudo dpkg -i ./faraday-server_amd64.deb
+
+

Step 3 - Adding User to faraday Group

+

Once installed, add your user to the faraday group and re-login:

+
sudo usermod -aG faraday $USER
+
+

Step 4 - Initializing the Database (first time only)

+

Initialize the DB, use it for Faraday Web UI and change it:

+
faraday-manage initdb
+
+

Importing License

+
faraday-manage import-license
+
+

Or, in isolated servers, download the license file from the portal and place it in /home/faraday/.faraday/doc/. Remove old license files from the doc folder when renewing the license:

+
tar xvf {license file}.tar.gz
+
+

Post Install (First Time Only)

+

Start the Faraday server by running:

+
systemctl start faraday-server
+systemctl enable faraday-server
+
+systemctl start faraday-worker
+systemctl enable faraday-worker
+
+systemctl start faraday-worker-reports
+systemctl enable faraday-worker-reports
+
+

We highly recommend checking our First Steps guide and the Advanced Install guide for starting Faraday using nginx and expose ssl certificates.

+

Update +Advanced Install +Remote db implementation

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Install-guide-Redhat-8/index.html b/Install-guide-Redhat-8/index.html new file mode 100644 index 00000000000..a8df4cb81af --- /dev/null +++ b/Install-guide-Redhat-8/index.html @@ -0,0 +1,1012 @@ + + + + + + + + + + + + + + +RedHat 8/Centos - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

RedHat8

+

Before installation

+

Please note that PostgreSQL YUM repository and Faraday, depend on EPEL repository for some packages. Users with RHEL, CentOS, etc. should install EPEL repo RPM along with PGDG repo RPMs to satisfy dependencies. In order to do that, follow these instructions:

+

If you are using RHEL, first run the following command:

+

Install EPEL using the following command: +

yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
+
+Refresh repo by typing the following command: +
yum repolist
+

+

RedHat8 Installation Guide for PostgreSQL

+
    +
  1. +

    Install PostgreSQL >= 9.6 (local or remote). + Follow the Postgres installation guide for Redhat: Postgres(RedHat)

    +
  2. +
  3. +

    Download Faraday installer (.rpm)

    + +
  4. +
  5. Go to your Download directory and run the following command +
    sudo yum install ./faraday-server_amd64.rpm
    +
    +

    💡 + If PostgreSQL is running in a remote machine please follow these instructions, if instead, it is running locally, you need to open the pg_hba.conf file.

    +
    +
  6. +
+

There, you need to modify the localhost authentication type from "ident" to "md5". To do this, change host IPV4 local and IPV6 local from "ident" to "md5".

+
    +
  1. Go to the file: +
    $ nano /var/lib/pgsql/POSTGRESQL_VERSION/data/pg_hba.conf  
    +
    +Edit the following lines:
    +
    # IPv4 local connections:
    +host all         all 127.0.0.1/32       md5
    +# IPv6 local connections:
    +host all         all ::1/128       md5
    +
  2. +
  3. +

    Once installed, add your user to the faraday group and re-login +

    sudo usermod -aG faraday $USER
    +

    +
  4. +
  5. +

    Restart PostgreSQL server and initialize the database(first time only)
    + This will generate a random password, use it for Faraday Web UI and change it

    +
  6. +
+
sudo systemctl restart postgresql-XX
+
+
sudo faraday-manage initdb
+
+
+

⚠️ Important: In case of being in a SELinux environment run prior to the checks:

+
+
sudo setenforce 0
+
+

Redis install

+
sudo dnf install redis
+
+

Importing License

+

Step 1

+

Import license from Faraday Portal
+

faraday-manage import-license
+
+In case of offline environment, check import license on Install Guide Advanced

+

Step 2

+
    +
  1. Start and enable the autostart of Faraday server by running:
    +
    systemctl start faraday-server
    +systemctl enable faraday-server
    +
    +systemctl start faraday-worker
    +systemctl enable faraday-worker
    +
    +systemctl start faraday-worker-reports
    +systemctl enable faraday-worker-reports
    +
  2. +
+

We highly recommend you to check our First Steps guide.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Install-guide-Troubleshooting/index.html b/Install-guide-Troubleshooting/index.html new file mode 100644 index 00000000000..c46a81a7f1b --- /dev/null +++ b/Install-guide-Troubleshooting/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + +Troubleshooting - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Troubleshooting

+

+

PyPI/GitHub

+

If you're getting the following error:

+
    Complete output from command python setup.py egg_info:
+    running egg_info
+    creating pip-egg-info/psycopg2.egg-info
+    writing pip-egg-info/psycopg2.egg-info/PKG-INFO
+    writing dependency_links to pip-egg-info/psycopg2.egg-info/dependency_links.txt
+    writing top-level names to pip-egg-info/psycopg2.egg-info/top_level.txt
+    writing manifest file 'pip-egg-info/psycopg2.egg-info/SOURCES.txt'
+    Error: b'You need to install postgresql-server-dev-NN for building a server-side extension or libpq-dev for building a client-side application.\n'
+
+    ----------------------------------------
+Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-mkj8d84u/psycopg2/
+
+

If you never install PostgreSQL before, you must install it first, by doing this:

+

sudo apt install postgresql-12
+
+or +
sudo yum install postgresql-12
+

+

Once you installed this, run the pip3 command again.

+

pip3 install faradaysec
+
+or +
pip3 install .
+

+

Nix

+

directory /nix exists, but is not writable by you

+

If you never install Nix before, this error appears because you have installed Faraday server or client .deb or .rpm on the system. +You must uninstall it first, by doing this:

+

sudo apt remove faraday-server
+
+Once you uninstalled this, remove /nix directory and then run the Nix install again.

+
sudo rm -rf /nix
+
+

Error: while setting up the build environment: mounting /proc: Operation not permitted

+

This happens when running Nix on a container like LXC or similar. In theses cases, you should disable the sandbox.

+

First, create the following file:

+
~/.config/nix/nix.conf
+
+

Run the following command to add the flag to the file:

+
echo 'sandbox = false' >> ~/.config/nix/nix.conf
+
+

The, run the Nix install again.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Install-guide-community/index.html b/Install-guide-community/index.html new file mode 100644 index 00000000000..7689aa8afb4 --- /dev/null +++ b/Install-guide-community/index.html @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + +Community - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Community

+

Install Guide

+

In order to install Faraday Community version, you can use pip to install Faraday or you can clone the repository. Additionally you can either use our docker-compose.yml file that will install all in one place.

+

Install using Docker

+

git clone git@github.com:infobyte/faraday.git
+docker-compose up -d
+
+then run the following to check if the pod is running:

+
docker-compose ps
+
+

Startup docker postgres

+
docker pull postgres
+docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres
+
+

Installation from PyPI

+

You can install Faraday from PyPI by running the following command:

+
pip3 install faradaysec
+
+

Installation from using pip from source

+
git clone git@github.com:infobyte/faraday.git
+cd faraday
+pip install .
+
+

After Installation

+

Once the installation is completed, make sure you have a PostgreSQL (local or remote)

+

Then initialize the database
+This will generate a random password, use it for Faraday Web UI and change it +

faraday-manage initdb
+

+

Start Faraday server by running:

+
+
sudo systemctl start faraday-server
+
+
+
+
faraday-server
+
+
+
+

We highly recommend you to check our First Steps guide.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Jinja2-context/index.html b/Jinja2-context/index.html new file mode 100644 index 00000000000..c625df70cf1 --- /dev/null +++ b/Jinja2-context/index.html @@ -0,0 +1,1179 @@ + + + + + + + + + + + + + + +Jinja2 Context - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Jinja2 Context json

+

These are examples of jinja2 static dataset usage. You can access this information from the docx template.

+
+

Info

+

Executive reports use jinja for rendering the report, check jinja documentation for more details.

+
+

Report Context

+
+

This report lists all vulnerabilities of the workspace. +

{
+    "counter_severity": <severities dict>,
+    "date": <datetime>,
+    "enterprise": format_text_docxtpl_patch(report.enterprise),
+    "hosts": <list host>,
+    "hosts_amount": <int>,
+    "overview_images": <image>,
+    "vulnerabilities_image": <image>,
+    "ease_resolution_image": <image>,
+    "impact_image": <image>,
+    "services": <list service>,
+    "services_amount": <int>,
+    "title": <str>,
+    "vulns": <list of vuln>,
+    "vulns_amount": <int>,
+    "workspace": <workspace_object>,
+   "conclusions": <string>,
+    "objectives": <string>,
+    "recommendations": <string>,
+    "scope": <string>,
+    "summary": <string>,
+    "methodologies": [<methodology>]
+}
+

+
+
+

This type of report groups the data using the name and description of the vulnerability. vulns_grouped_amount number of vulnerabilities in the group. +

{
+    "counter_severity": <dict severities>,
+    "date": <datetime>,
+    "enterprise": format_text_docxtpl_patch((report.enterprise)),
+    "hosts": <list host>,
+    "hosts_amount": <int>,
+    "overview_images": <image>,
+    "vulnerabilities_image": <image>,
+    "ease_resolution_image": <image>,
+    "impact_image": <image>,
+    "services": <list service>,
+    "services_amount": <int>,
+    "title": <str>,
+    "vulns": <list of vuln>,
+    "vulns_amount": <int>,
+    "vulns_grouped_amount": <int>,
+    "workspace":<str>,
+    "conclusions": <string>,
+    "objectives": <string>,
+    "recommendations": <string>,
+    "scope": <string>,
+    "summary": <string>,
+    "methodologies": [<methodology>]
+}
+

+
+
+

Inside each Template, in either of the two report Dataset, we can use these variables:

+
+
{
+'_rev': '',
+'type': 'Host',
+'_id': 1,
+'versions': [],
+'owned': False,
+'mac': <str>,
+'os': 'Linux Kernel 3.8',
+'owner': None,
+'services': 1,
+'ip': '127.0.0.1',
+'default_gateway': '',
+'service_summaries': ['(80/tcp) www'],
+'tags': ['QA'],
+'credentials': 0,
+'description': '',
+'name': '127.0.0.1',
+'hostnames': ['localhost'],
+'metadata': {'create_time': <datetime>,
+'update_time': <datetime>,
+'creator': '',
+'update_controller_action': '',
+'owner': None,
+'command_id': None,
+'update_action': 0,
+'update_user': None},
+'id': 1,
+'vulns': 91
+}
+
+
+
+
{
+'_rev': '',
+'type': 'Service',
+'_id': 1,
+'owned': False,
+'summary': '(80/tcp) http',
+'version': 'unknown',
+'parent': 4,
+'owner': None,
+'tags': ['QA'],
+'protocol': 'tcp',
+'credentials': 0,
+'port': <int>,
+'description': '',
+'name': 'http',
+'host_id': 4,
+'ports': 80,
+'metadata': {'create_time': <datetime>,
+'update_time': <datetime>,
+'creator': '',
+'update_controller_action': '',
+'owner': None,
+'command_id': None,
+'update_action': 0,
+'update_user': None},
+'id': 1,
+'vulns': 1,
+'status': 'open'
+}
+
+
+
+
{
+'data': <SubDoc>,
+'vulnerability_duplicate_id': None,
+'confirmed': False,
+'_rev': '',
+'easeofresolution': None,
+'childs': [],
+'cvss3_vector_string' : <str>,
+'cvss3_base_score' : <float>,
+'cvss3_exploitability_score' : <float>,
+'cvss3_impact_score' : <float>,
+'cvss3_base_severity' : <str>,
+'cvss3_temporal_score' : <float>,
+'cvss3_temporal_severity' : <str>,
+'cvss3_environmental_score' : <float>,
+'cvss3_environmental_severity' : <str>,
+'cvss3_attack_vector' : <str>,
+'cvss3_attack_complexity' : <str>,
+'cvss3_privileges_required' : <str>,
+'cvss3_user_interaction' : <str>,
+'cvss3_confidentiality_impact' : <str>,
+'cvss3_integrity_impact' : <str>,
+'cvss3_availability_impact' : <str>,
+'cvss3_exploit_code_maturity' : <str>,
+'cvss3_remediation_level' : <str>,
+'cvss3_report_confidence' : <str>,
+'cvss3_confidentiality_requirement' : <str>,
+'cvss3_integrity_requirement' : <str>,
+'cvss3_availability_requirement' : <str>,
+'cvss3_modified_attack_vector' : <str>,
+'cvss3_modified_attack_complexity' : <str>,
+'cvss3_modified_privileges_required' : <str>,
+'cvss3_modified_user_interaction' : <str>,
+'cvss3_modified_scope' : <str>,
+'cvss3_modified_confidentiality_impact' = <str>,
+'cvss3_modified_integrity_impact' : <str>,
+'cvss3_modified_availability_impact' : <str>,
+'type': 'Vulnerability',
+'_id': 1,
+'severity': 'med',
+'refs': ['CVSS: 3.2'],
+'date': <datetime>,
+'owned': False,
+'parent': 1,
+'policyviolations': [],
+'resolution': 'Resolution text',
+'owner': None,
+'service': {'version': 'unknown',
+'name': 'postgresql',
+'protocol': 'tcp',
+'ports': 80,
+'_id': 1,
+'summary': '(80/tcp) http',
+'status': 'open'},
+'issuetracker': {},
+'update_user': None,
+'external_id': '1233',
+'tags': [],
+'vulnerability_template_id': None,
+'impact': {'accountability': False,
+'confidentiality': False,
+'integrity': False,
+'availability': False},
+'obj_id': '1',
+'custom_fields': {'list': None, 'integer': None, 'choice': None},
+'parent_type': 'Service',
+'description': 'Description',
+'host_os': 'Linux Kernel 4.8',
+'name': 'Vulnerability title',
+'_attachments': {},
+'hostnames': ['localhost'],
+'desc': <SubDoc>,
+'target': '127.0.0.1',
+'metadata': {'create_time': <datetime>,
+'update_time': <datetime>,
+'creator': 'OpenVAS',
+'update_controller_action': '',
+'owner': None,
+'command_id': 1,
+'update_action': 0,
+'update_user': None},
+'status': 'opened',
+'id': 1,
+'__target__': '127.0.0.1 / 80 / tcp'
+}
+
+
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/LDAP-OKTA/index.html b/LDAP-OKTA/index.html new file mode 100644 index 00000000000..cc862042e4d --- /dev/null +++ b/LDAP-OKTA/index.html @@ -0,0 +1,968 @@ + + + + + + + + + + + + + + +LDAP with OKTA - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

LDAP with OKTA

+
+

Here are the steps to integrate LDAP to Faraday using OKTA:

+

Step 1: Navigate to OKTA's website.

+

Step 2: Sing up.

+

Remember your user and workdomain from user@workdomain.com

+

Step 3: Okta will send you an e-mail with the URL and your temporary password, use those to log-in into Okta.

+

Step 4: Enter to the Directory Integrations Label from your Okta URL.

+

Step 5: Click Add LDAP Interface

+

add-interface

+

Step 6: Configure your Faraday Server.

+

Run the following command:

+

faraday-manage settings -a update ldap
+
+
enabled = true
+server = <domain>.ldap.okta.com
+domain_dn = OU=users, DC=<domain>, DC=okta, DC=com
+domain =<domain>.okta.com
+admin_group = fadmin
+pentester_group = fpentester
+asset_owner_group = fassetowner
+client_group = fclient
+use_ldaps = true
+use_start_tls = false
+port = 636
+disconnect_timeout = 2.0
+use_local_roles = true
+default_local_role = admin
+bind_format = DN
+bind_dn = dc=<domain>,dc=okta,dc=com
+

+

Check our LDAP Article if you need more info.

+

Step 7: Restart Faraday Server with:

+
systemctl restart faraday-server
+
+

Step 8: Login into Faraday with the User and Password you used to login into Okta.

+
+

Info

+

(Remember you can only access as an Admin user and you can't create more users).

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/LDAP/index.html b/LDAP/index.html new file mode 100644 index 00000000000..889368fdb4d --- /dev/null +++ b/LDAP/index.html @@ -0,0 +1,1024 @@ + + + + + + + + + + + + + + +LDAP - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

LDAP Configuration

+
+

UI Settings

+

Using the LDAP integration has never been that easy, now with faraday UI you can use LDAP users and assign roles to the ldap groups, you can configure it going to upper right corner click on the User circle and then hit on preferences.

+

+

after this, click on preferences, and go to the Ldap section and click on the activate LDAP slider.

+

+

Follow the steps to complete the configuration. Don't forget click on the Save button on the upper corner.

+

Console Settings

+
+

LDAP Users

+

For the time being Faraday doesn't support a hybrid installation using both LDAP and local users. Enabling LDAP disables local users and vice versa.

+
+

In order to configure LDAP, run the following command:

+
faraday-manage settings -a update ldap
+
+

Then update every field according to the configuration on-prem.

+
$ faraday-manage settings -a update ldap
+Update settings for: ldap
+enabled [False]:
+use_local_roles [True]:
+default_local_role [admin]:
+admin_group []:
+asset_owner_group []:
+client_group []:
+pentester_group []:
+disconnect_timeout [2.0]:
+server []:
+port [389]:
+use_ldaps [False]:
+use_start_tls [False]:
+domain []:
+domain_dn []:
+bind_format [CN]:
+bind_dn []:
+user_class [user]:
+user_attribute [sAMAccountName]:
+group_class [group]:
+paginated_fetch [False]:
+Do you confirm your changes on ldap?
+
+

Remember to restart the server after doing changes!

+
systemctl restart faraday-server
+
+
+

Warning

+

If use_local_roles is set to true, any user on the AD will be allowed to use Faraday.

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/NGINX-Setup/index.html b/NGINX-Setup/index.html new file mode 100644 index 00000000000..d820b46a6ed --- /dev/null +++ b/NGINX-Setup/index.html @@ -0,0 +1,1133 @@ + + + + + + + + + + + + + + +NGINX (SSL Config) - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

NGINX (SSL Config)

+

The recommended way to run Faraday is using SSL via Nginx

+
+

If you use NGINX you need to generate swagger config to let it work over the domain

+
+

faraday-manage openapi-swagger --server https://your-fqdn-for-faraday.com

+

Nginx

+
+

New Faraday release 4.1.0 can generate a ngnix configuration for you

+
+

Installing Nginx

+

You can find a detailed guide on how to install nginx in the official Nginx documentation

+

Configure NGINX

+

After installing and configuring NGINX, Faraday's setup should be as follows:

+
1
+2
Faraday Server on port 5985 using HTTP. You can find this configuration inside the file ~/.faraday/config/server.ini in section [faraday_server].
+Web UI using https://example_domain:port/
+
+

Note: For both cases, NGINX on port 80 redirecting to HTTPS.

+

Generating Certificates

+

In order to generate self signed certificates, run the following command:

+
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/faraday.key -out /etc/ssl/faraday.crt
+
+
+

Be sure to type the Common Name of this certificate. If you don't type a Common Name, then Faraday will not be launched.

+

For further information about certificates, follow this link.

+
+

Sample Configuration Files

+

Below you can find a sample config files for NGINX. You can use this same configuration by pasting it inside the folder /etc/nginx/sites-enabled/ or in conf.d and naming the file as you want. +

faraday-manage generate-nginx-config --fqdn faraday.mydomain.com --port 5985 --ws-port 9000 --ssl-certificate /etc/ssl/faraday.crt --ssl-key /etc/ssl/faraday.key
+
+
Generating Faraday nginx config for server: faraday.mydomain.com
+Faraday
+- Port: 5985
+- Websocket Port: 9000
+SSL: certificate [/etc/ssl/faraday.crt] - key [/etc/ssl/faraday.key ]
+Confirm [Y/n]: y
+NGINX Config
+#####################################
+
+
+# Expires map
+map $sent_http_content_type $expires {
+    default                    off;
+    text/html                  max;
+    text/css                   max;
+    application/javascript     max;
+    ~image/                    max;
+}
+
+server {
+    server_name faraday.mydomain.com;
+    listen 443 ssl http2;
+
+    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
+    add_header X-XSS-Protection "1; mode = block";
+    add_header X-Frame-Options "SAMEORIGIN";
+    add_header X-Content-Type-Options nosniff;
+    client_max_body_size 150M;
+
+    ssl on;
+    ssl_session_cache shared:SSL:50m;
+    ssl_certificate           /etc/ssl/faraday.crt;
+    ssl_certificate_key       /etc/ssl/faraday.key
+    gzip on;
+    gzip_types application/javascript text/css;
+    expires $expires;
+
+    location / {
+        alias /opt/faraday/lib/python3.8/site-packages/faraday/server/www/;
+    }
+
+    location /_api/ {
+        proxy_pass http://localhost:5985/_api/;
+        proxy_redirect http:// $scheme://;
+        proxy_read_timeout 300;
+        proxy_cookie_path / "/; secure";
+
+        proxy_set_header Host $host;
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Ssl on;
+        proxy_set_header X-Forwarded-Proto $scheme;
+    }
+
+    location /websockets {
+        proxy_http_version 1.1;
+        proxy_pass http://localhost:9000/websockets;
+
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+        proxy_set_header Upgrade $http_upgrade;
+        proxy_set_header Connection "upgrade";
+    }
+}
+
+server {
+    server_name faraday.mydomain.com;
+    listen 80 ;
+
+    # https redirect
+    if ($host = faraday.mydomain.com) {
+        return 301 https://$host$request_uri;
+    }
+
+    return 404;
+}
+

+

Now you can access to https://faraday.mydomain.com

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Notifications-Slack/index.html b/Notifications-Slack/index.html new file mode 100644 index 00000000000..dade86506e2 --- /dev/null +++ b/Notifications-Slack/index.html @@ -0,0 +1,1060 @@ + + + + + + + + + + + + + + +Configure Slack Notifications - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Configure Slack Notifications

+

Getting Ready with Slack Configuration

+
    +
  1. Go to https://api.slack.com/apps.
  2. +
  3. Click on “Create New App.”
  4. +
+

+
    +
  1. Select "From an app manifest"
  2. +
+

+
    +
  1. Choose the Slack workspace where you want to install the app.
  2. +
+

+
    +
  1. In step 2, paste the following manifest JSON data:
  2. +
+
{
+    "display_information": {
+        "name": "faraday-notifications",
+        "description": "Notifications for Faraday",
+        "background_color": "#82AFD9"
+    },
+    "features": {
+        "app_home": {
+            "home_tab_enabled": false,
+            "messages_tab_enabled": true,
+            "messages_tab_read_only_enabled": true
+        },
+        "bot_user": {
+            "display_name": "Faraday Notifications",
+            "always_online": true
+        }
+    },
+    "oauth_config": {
+        "scopes": {
+            "bot": [
+                "app_mentions:read",
+                "channels:join",
+                "channels:read",
+                "chat:write",
+                "chat:write.customize",
+                "chat:write.public",
+                "im:write",
+                "links:write",
+                "reactions:write",
+                "team:read",
+                "usergroups:read",
+                "users:read",
+                "users:write"
+            ]
+        }
+    },
+    "settings": {
+        "event_subscriptions": {
+            "bot_events": [
+                "app_mention"
+            ]
+        },
+        "interactivity": {
+            "is_enabled": true
+        },
+        "org_deploy_enabled": false,
+        "socket_mode_enabled": true,
+        "token_rotation_enabled": false
+    }
+}
+
+
    +
  1. Click on “Create.”
  2. +
  3. Click on “OAuth & Permissions.” and Install it “Org-wide.”
  4. +
+

+

Note: Obtain the OAuth token for later use by pasting it into Faraday.

+

+
    +
  1. Click on “Add apps,” locate the faraday-notifications app, and add it.
  2. +
  3. Get your Slack ID from your Slack profile and paste it into Faraday.
  4. +
+

Configure your Slack integration

+

Using the OAuth token and your Slack ID, you can configure Slack notifications. Use the shortcut button from the Notifications Settings to be redirected to the Slack configuration in Faraday's Preferences and paste the token and your Slack ID obtained in the steps above.

+

+

Info If your role differs from an administrator, you only need to paste your Slack ID. For the integration to work, an administrator must initially paste the OAuth token into their own Faraday account.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Notifications/index.html b/Notifications/index.html new file mode 100644 index 00000000000..0e713ed446f --- /dev/null +++ b/Notifications/index.html @@ -0,0 +1,1059 @@ + + + + + + + + + + + + + + +Notifications Settings - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Notification Center

+

Faraday's Notification Center feature is tailored to bolster your organization's security posture by delivering timely and customizable alerts related to vulnerabilities, threats, and all other available Faraday features within your license.

+

Notification Settings

+

You can configure notifications through the Notifications section located in the left panel. +

+

Currently, there are various System Notification Categories available for configuration:

+
    +
  • Agents
  • +
  • Assets
  • +
  • Comments
  • +
  • Pipelines
  • +
  • Planner
  • +
  • Reports
  • +
  • Users
  • +
  • Vulnerabilities
  • +
  • Workspaces
  • +
+

The configuration options for each category are contingent upon your license and role.

+

For users with a Corporate License and Administrator role, all categories are available for configuration by default.

+

By default, all in-app notifications are enabled. You have the option to disable an entire category using the toggle switch on the left. Disabling a category will halt notifications within that category from reaching you.

+

+

If you enable the EMAIL option, notifications from the enabled category will be dispatched to the email address linked to your user account.

+

Enabling the SLACK option will direct notifications from the enabled category to your Slack workspace (please refer to the Slack integration section for details on configuring Slack).

+

Typically, notifications for each category are designed to keep users informed about changes in the workspace where they are assigned. Planner notifications specifically inform users about updates to tasks they are assigned or were assigned to. Notifications will not be sent to users without permissions to access the relevant workspace, regardless of whether they have enabled the category.

+

Though notifications are primarily designed to inform users about background activity or changes initiated by other platform users, users can tailor their notification settings to receive notifications related to their own activity. You can achieve this by toggling on the "Notify me about my own activity" button.

+

Additionally, you can temporarily pause all notifications using the pause button. This action will halt all notifications to any channel until you choose to resume them using the resume button.

+

Notifications Log

+

Notifications from all enabled categories will be logged. This log contains a history of all notifications.

+

+

Each row in the log represents a notification and includes a brief description, the category it belongs to, who triggered it, and the exact time it was generated.

+

You can mark all notifications as read using the button. Rows can be selected using the checkbox on the left of each row and deleted using the delete button.

+

Clicking on a notification row will redirect you to the source of the notification, such as the updated vulnerabilities or planner tasks assigned to you.

+

In-App Notifications

+

If you select the IN-APP column in the Notification Settings, notifications from the selected category will also appear in the Notifications Bell located at the top right. Clicking on the bell will display the last 4 notifications in a dropdown menu.

+

+

A red indicator shows the number of unread notifications in the notification log. You can view all unread notifications by clicking on it at the bottom of the dropdown menu. This action redirects you to the Notifications Log, where you can find both unread and read notifications.

+

Notifications displayed in the bell, like those in the notification log, can be clicked to be redirected to the source of the notification.

+

Email Notifications

+

If you select the EMAIL column in the Notification Settings, notifications from the selected category will also be sent to the email address configured in your user account.

+

Slack Notifications

+

If you select the SLACK column in the Notification Settings, notifications from the selected category will be sent to your Slack account. To enable this integration, a Faraday admin user must complete the steps outlined in the following section.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Pipelines/index.html b/Pipelines/index.html new file mode 100644 index 00000000000..ff4ae3a81f3 --- /dev/null +++ b/Pipelines/index.html @@ -0,0 +1,946 @@ + + + + + + + + + + + + + + +Pipelines and jobs - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Pipelines and jobs

+

We were thinking on a pain solver in case of importing manually files, or working with the vulnerabilities massively in your Workspace.

+

Faraday created pipelines designed exclusively to automate and change vulnerabilities applying custom Job rules, according to patterns inside a name or any attribute inside a Vulnerability.

+

The hierarchy will be Jobs are run inside Pipelines. The first view will show in the left the pipelines, and clicking on one title, will show the configuration of each.

+

Pipelines

+

Jobs will run sequentially inside a Pipeline to a Target Workspace. If you click on Create New the Jobs view will be opened.

+

Jobs

+

In this view is needed to setup a Name, Description and Object and Attributes.

+

Based on Two models, Assets and Vulnerability. it can be added Rules and Tasks

+

Rules are sets of attributes based on the vulnerability, such as Name, Description, Tag, etc. The operators for the rules are equal, not equal and contains, using the operators the rule can be created.

+

Attributes

+

The Tasks contain Actions these can be Update, Append and Delete the object. The last option will delete the object that matches the condition, this is used to Delete the Vulnerability. The action Update will select a Field based on this condition and update it to the value selected in the Action to the desired Value. Append is useful to create an attribute such as Tag, Comment or Policy Violation. in Case of Comments a user can be addressed with a "@" symbol.

+

Tasks

+

Click on Save on the up right Corner.

+

Select The Target Workspace and click on Save

+

Tasks

+

From the Enable slide the pipeline can be either enabled or disabled, and from the Run Button the pipeline can be manually triggered.

+

Pipelines

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Planner/index.html b/Planner/index.html new file mode 100644 index 00000000000..7e0a4a956ba --- /dev/null +++ b/Planner/index.html @@ -0,0 +1,941 @@ + + + + + + + + + + + + + + +Planner - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Planner

+

Organize your vulnerabilities and get work done easily and comfortably without using any extra platforms. Be more productive and share work with your team. +Task assignment, status, alerts, and more: manage the progress of your vulnerabilities in one place.

+

The overview page can be accessed using the planner icon .

+

The sections are divided by Project, inside project Tasks/Milestones can be created, those can be assigned to users, and have dependencies.

+

+

The Task can be appended hovering in a project and clicking on the Add Task Button.

+

+

The task can contain values such start/end date, progress, description and Assigned users and Dependencies

+

+

Click on Create and the task will be assigned inside the Project

+

A task can have linked Vulnerabilities, from the Quick Planner module from Vulnerabilies view

+

Refer to Vulnerability view document to assign a vulnerabilty to a task from the Quick Planner view.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Plugin-List-v4/index.html b/Plugin-List-v4/index.html new file mode 100644 index 00000000000..ff7b27d21a1 --- /dev/null +++ b/Plugin-List-v4/index.html @@ -0,0 +1,1767 @@ + + + + + + + + + + + + + + +Supported-Plugins - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Supported-Plugins

+

The main purpose of Faraday is to re-use the available tools in the community to take advantage of them in a multiuser way.

+
+

You break it. We keep track of the pieces!

+
+

To maximize flexibility Faraday Plugins run only on the client, which means you can have custom, private plugins all for yourself!

+

There are three kinds of plugins available for Faraday; console, report and API also called online. However, these are not mutually exclusive, meaning that some tools have more than one Plugin to process their output. For example, Nmap has a Console plugin which allows you to run it directly from ZSH, but it also has a Report one, in order to import scans that were run outside of Faraday.

+

Console

+

Check Faraday-Cli to use this feature!

+

Plugins that intercept commands, fired directly when a command is detected in the console. These are transparent to you and no additional action on your part is needed.

+

Report

+

Use the web UI to import reports. Check this Article!

+

API

+

Plugin connectors or online (BeEF, Metasploit, Burp), these connect to external APIs or databases, or talk directly to Faraday's API.

+

Custom

+

If you think your favourite tool is missing code your own plugin or ask us to do it!

+

The following table contains name, id, command or report, in the case of command it is that the command can be used inside faraday-cli and it gets imported into faraday after the run, for report it means that the file can be imported in the Faraday IU.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameIDCommandReport
Acunetix XML Output PluginAcunetixNoYes
Acunetix360 Output PluginAcunetix360NoYes
Acunetix JSON Output PluginAcunetix_JsonNoYes
Amap Output PluginAmapYesNo
Appscan XML PluginAppscanNoYes
Appscan CSV Output PluginAppscan_CSVNoYes
AppSpider XML Output PluginAppSpiderNoYes
Arachni XML Output PluginArachniYesYes
arp-scan network scannerarp-scanYesNo
AWS Inspector JSON Output PluginAWSInspector_JsonNoYes
Bandit XML Output PluginBanditNoYes
BeEF Online Service PluginBeefYesNo
brutexssbrutexssYesNo
Burp XML Output PluginBurpNoYes
Checkmarx XML Output PluginCheckmarxNoYes
CIS XML Output PluginCISNoYes
Cobalt CSV Output PluginCobaltNoYes
Crowdstrike JSON Output PluginCrowdstrike_JsonNoYes
DiGdigYesNo
DirbdirbYesNo
dirsearchdirsearchYesNo
Dnsenum XML Output PluginDnsenumYesNo
Dnsmap Output PluginDnsmapYesNo
Dnsrecon XML Output PluginDnsreconYesNo
Dnswalk XML Output PluginDnswalkYesNo
Faraday CSV Pluginfaraday_csvNoYes
Faraday JsonFaraday_JSONNoYes
Fierce Output PluginFierceYesNo
Fortify XML Output PluginFortifyNoYes
FtpftpYesNo
Goohost XML Output PluginGoohostYesNo
Grype JSON PlugingrypeYesYes
hping3Hping3YesNo
Hydra XML Output PluginHydraYesNo
Core Impact XML Output PluginCoreImpactNoYes
Invicti XML Output PluginInvictiNoYes
Ip360 CSV Output PluginIp360NoNo
Junit XML Output PluginJunitNoYes
Kubescape JsonKubescape_JSONNoYes
Lynis DAT Output PluginLynisYesYes
Maltego MTGX & MTGL Output PluginMaltegoNoYes
Microsoft Baseline Security AnalyzerMBSANoYes
Medusa Output PluginMedusaYesNo
Metasploit XML Output PluginMetasploitNoYes
NaabunaabuYesYes
ncrack XML PluginncrackNoYes
ndiffNdiffYesNo
Nessus XML Output PluginNessusNoYes
Nessus Sc Output PluginNessus_scNoYes
netdiscoverNetdiscoverYesNo
Netsparker XML Output PluginNetsparkerNoYes
NetsparkerCloud XML Output PluginNetsparkerCloudNoYes
Nexpose XML 2.0 Report PluginNexposeFullNoYes
nextnetnextnetYesNo
Nikto XML Output PluginNiktoYesYes
Nipper XML Output PluginNipperNoYes
Nmap XML Output PluginNmapYesYes
NucleinucleiYesYes
Nucleinuclei_legacyYesYes
OpenScap XML Output PluginOpenScapNoYes
Openvas XML Output PluginOpenvasNoYes
pasteAnalyzer JSON Output PluginpasteAnalyzerYesNo
PeepingTompeepingtomYesNo
Pentera Json Output PluginPentera_JsonNoYes
PingpingYesNo
Ping Castle XML Output PluginPingCastleNoYes
Popeye JSON Output PluginPopeye_JsonNoYes
propecia port scannerpropeciaYesNo
ProwlerprowlerNoYes
Prowlerprowler_legacyNoYes
Qualysguard XML Output PluginQualysguardNoYes
QualysWebapp XML Output PluginQualysWebappNoYes
rdpscanrdpscanYesNo
Reconng XML Output PluginReconngNoYes
Retina XML Output PluginRetinaNoYes
Reverseraider XML Output PluginReverseraiderYesNo
Sarif PluginSarifNoYes
Semgrep JsonSemgrep_JSONNoYes
ShodanshodanYesYes
Skipfish Output PluginSkipfishYesNo
SnykSnykNoYes
SonarQube API PluginsonarqubeAPINoYes
SourceclearsourceclearNoYes
sshdefaultscansshdefaultscanYesNo
SSL LabsssllabsNoYes
Sslyze PluginSslyze_XMLNoYes
Sslyze JsonSslyze_JSONYesYes
Syhunt XML PluginSyhuntNoYes
TelnetTelnetYesNo
Terraform Plugin JSON Output PluginTerraformPluginJsonNoYes
Theharvester XML Output PluginTheharvesterYesNo
TracerouteTracerouteYesNo
Trivy JSON Output PluginTrivy_JsonNoYes
W3af XML Output PluginW3afYesYes
Wapiti XML Output PluginWapitiYesYes
Wcscan XML Output PluginWcscanYesNo
Webfuzzer Output PluginWebfuzzerYesNo
WebinspectWebinspectNoYes
Wfuzz PluginWfuzzYesNo
WhatWebPluginwhatwebNoYes
whitesourcewhitesourceNoYes
WhoiswhoisYesNo
Windows Defender JsonlWindowsDefender_JSONLNoYes
WPscanwpscanYesYes
Onapsis X1 XML Output PluginX1YesYes
xsssniperxsssniperYesNo
Zap XML Output PluginZapNoYes
Zap Json Output PluginZap_JsonNoYes
+

References to the Tools:

+ +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/RELEASE/index.html b/RELEASE/index.html new file mode 100644 index 00000000000..a263978b9a1 --- /dev/null +++ b/RELEASE/index.html @@ -0,0 +1,4146 @@ + + + + + + + + + + + + + + +Faraday - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

New features in the latest update

+

5.2.0 [Mar 12th, 2024]:

+
    +
  • [MOD] Remove websockets port from docker-compose. #7679
  • +
  • [FIX] Fix hosts stats when bulk delete is applied to vulns. #7676
  • +
  • [FIX] Fix agents status from database. We were not updating the agent's status on faraday-server restarts. #7677
  • +
+

Changes in Faraday Professional: + * [ADD] Add the possibility to see and edit personal information of non Admin users. #7622 + * [MOD] Improved global_host endpoint performance. #7674

+

Changes in Faraday Corporate: + * [ADD] Add active field to ticketing tools integrations. #7555

+

5.1.1 [Feb 9th, 2024]:

+
    +
  • [FIX] Improve of host view performance.
  • +
+

5.1.0 [Feb 8th, 2024]:

+
    +
  • [ADD] Performance improved in assets views making several vulnerabilities stats statics in asset's model. #7634
  • +
  • [ADD] Now custom fields are available for filtering vulnerabilities. Also add date type for custom fields. #7625
  • +
  • [MOD] Modify analytics type enum. #7615
  • +
  • [MOD] We changed the order in which we set the path constant of faraday_home in order to fix a bug with faraday_manage when is installed by deb/rpm. #7653
  • +
  • [FIX] Fix references. #7648
  • +
+

Changes in Faraday Professional: + * [ADD] Add commit to recalculate risk API call. #7575 + * [ADD] Add split function to jinja sandboxed environment. #7590 + * [FIX] Now the pattern of grouped templates is searched also inside tables. #7637

+
    +
  • Changes in Faraday Corporate:
  • +
  • [ADD] Advanced notifications. #7549
  • +
  • [FIX] There was a bug when adding references through the enrichment modules. #7647
  • +
+

5.0.1 [Jan 2nd, 2024]:

+
    +
  • [MOD] Code refactor.
  • +
+

Changes in Faraday Professional: + * [FIX] Restore websockets notifications logic. #7640 + * [FIX] Command status update fixed when no hosts parsed. #7636 + * [FIX] Exception handler added in order to check malformed cvss vector strings. #7638

+

Changes in Faraday Corporate: + * [FIX] Now current flask context is valid for faraday-manage integrations rsa commands. #7639

+

5.0.0 [Dec 13th, 2023]:

+
    +
  • [ADD] Breaking change We now use Celery as the main way to import reports. In addition, we have removed twisted and replaced raw websockets with socket.io. #7352
  • +
  • [ADD] Added option to faraday-server to run workers. #7623
  • +
+

Changes in Faraday Professional: + * [FIX] Update the pypandoc arguments to eliminate deprecation warnings. #7536

+

4.6.2 [Nov 10th, 2023]:

+
    +
  • [ADD] Exclude unnecessary fields from VulnerabilitySchema in filter endpoint. #7608
  • +
+

Changes in Faraday Professional: + * [FIX] Bug fixed when attribute_identifier was defined but not present in saml. #7618

+

4.6.1 [Oct 19th, 2023]:

+
    +
  • [ADD] New exclude_stats query param in workspace endpoint. #7595
  • +
  • [MOD] Optimize hosts API when stats aren't needed. #7596
  • +
  • [FIX] Filter .webp files in vulns attachment endpoint because CVE-2023-4863. #7603
  • +
+

Changes in Faraday Professional: + * [FIX] Improve the way that CSRF token errors are showed. #7553 + * [FIX] object_type for report custom logo. #7464

+

Changes in Faraday Corporate: + * [ADD] Add new analytics endpoint vulnerabilities_by_risk_score. #7412 + * [ADD] Add option in saml settings to search for roles when creating new users. #7428

+

4.6.0 [Sep 6th, 2023]:

+
    +
  • [FIX] Delete Cascade from KB. #7569
  • +
+

Changes in Faraday Professional: + * [MOD] New notification center. #7385

+

Changes in Faraday Corporate: + * [FIX] Allow multiple tags per job. #7530 + * [MOD] Added tags as job action. #7520 + * [MOD] Allow more user roles to use the enrichment API. #7517

+

4.5.2 [Jul 26th, 2023]:

+
    +
  • [FIX] Add pango as an external requirement for nix to fix compatibility issues. #7535
  • +
+

4.5.1 [Jul 15th, 2023]:

+
    +
  • [FIX] Fix pillow version to 9.4.0. #7531
  • +
+

4.5.0 [Jul 7th, 2023]:

+
    +
  • [MOD] Upgrade nixpkgs version to 23.05. Also update version of packages in requirements. #7518
  • +
  • [FIX] Add missing scope cvss3 field. #7493
  • +
  • [FIX] Improve performance in hosts and hosts/filter views. #7501
  • +
+

Changes in Faraday Professional: + * [MOD] Now the users that are used in the jira integration needs to be added manually. Also add endpoint to add and remove jira users for jira integrations. #7512 + * [FIX] Now Schedule will require and use timezone. #7485

+

4.4.0 [May 29th, 2023]:

+
    +
  • [ADD] Now it's possible to modify the host or service assigned of a vulnerability. #7476
  • +
  • [MOD] Now /get_manifest separates the optional environment variables from the rest. #7481
  • +
  • [FIX] Add not_any filter operator which will retrieve results that not contains the value requested. #7394
  • +
  • [FIX] Make get_manifest compatible with all versions of dispatcher. #7500
  • +
+

Changes in Faraday Professional: + * [FIX] Now we show the correct import license url when no installed license was found. #7402 + * [FIX] ThreadFix Api export. #7489 + * [FIX] Now when uploading a report faraday will check if the host is already on the database. #7495

+

Changes in Faraday Corporate: + * [ADD] Add upload executive report templates. #7250 + * [ADD] Add new logic for sn_vul_app_vulnerable_item table. #7429

+

4.3.5 [Apr 12th, 2023]:

+
    +
  • [FIX] Modify migration with autocommit. #7487
  • +
+

4.3.4 [Apr 3rd, 2023]:

+
    +
  • [FIX] Fix bandit vulns. #7430
  • +
  • [FIX] Return public IP when behind a proxy. #7417
  • +
  • +

    [ADD] Add report_template as an object type. #7463 + Changes in Faraday Professional:

    +
  • +
  • +

    [ADD] Add set_tags method to service and host views and add service_tags and host_tags to tag view. #7451

    +
  • +
  • +

    [MOD] Check if tag is empty string in set_tags. #7469 +Changes in Faraday Corporate:

    +
  • +
  • +

    [MOD] Rollback jira integrations to use faraday users. #7467

    +
  • +
  • [MOD] Change permission for Jira endpoint to allow pentesters users connect and send issues to jira. #7403
  • +
  • [MOD] Refactor jira integration into jira_cloud_integration and jira_prem_integration. #7244
  • +
  • [FIX] Clone and update now gets the correct markdown value of old executive report. #7413
  • +
+

4.3.3 [Feb 9th, 2023]:

+
    +
  • [FIX] Add tags columns in AgentSchedule model in white version. #7341
  • +
  • [FIX] Now sending a patching a vuln with empty list will remove all the relationships with all references. #7405
  • +
  • [FIX] Migration cascade on KB #7396
  • +
  • [FIX] Migration cascade on KB #7396 +[Changes in Faraday Professional:]
  • +
  • [FIX] add nested sessions in concurrency process. #7329
  • +
  • [ADD] Now set tags accepts filters if no vulns ids are passed. #7357 +[Changes in Faraday Corporate:]
  • +
  • [FIX] Adapt get_jira_users for jira cloud. #7406
  • +
  • [MOD] Now the users list when sending a vuln to jira are jira's users with CREATE_ISSUE and ASSIGNABLE_USER permission #7177
  • +
  • [ADD] Attachment's type validation addition in pdf executive reports generation. #7364
  • +
  • [ADD] Add mkdir for ticketing tools directories of custom templates. #7401
  • +
  • [MOD] Modify context of references for integrations templates. #7397
  • +
+

4.3.2 [Jan 3rd, 2023]:

+
    +
  • Change column type of advanced field in executive reports
  • +
  • Change column type of advanced field in executive reports
  • +
  • [MOD] Modify empty fields comparison criteria in Executive Reports
  • +
  • [FIX] Fix memory use when generating executive reports
  • +
  • [MOD] Modify empty fields comparison criteria in Executive Reports
  • +
  • [ADD] Use of the trending enrichment field to tag vulnerabilities and also calculate risk.
  • +
  • [ADD] Total risk average and counters of vulnerabilities that have their risk below/above average.
  • +
  • [FIX] Risk calculation execution inside vulnerabilities pipeline.
  • +
+

4.3.1 [Dec 15th, 2022]:

+
    +
  • [ADD] Workspace api stats refactor
  • +
+

4.3.0 [Dec 1st, 2022]:

+
    +
  • [FIX] Update the associated command when a agent execution return empty
  • +
  • [ADD] cvss3 scope field to vulnerability schema
  • +
  • [ADD] Add cvss⅔ and cwe to export_csv
  • +
  • Improve command object creation in bulk create.
  • +
  • Fix open and closed stats in ws filter endpoint.
  • +
  • Add error command status in every validation of reports upload process
  • +
  • [ADD] BulkDelete with filters
  • +
  • Change filter logic on numeric fields.
  • +
  • Fix order of vulnerabilities in executive reports. Also add some graphics in templates.
  • +
  • [MOD] For security disable custom plugins on cloud
  • +
  • [MOD] Add an optional custom logo to executive reports
  • +
  • [ADD] Add command to load configuration samples
  • +
  • Added vuln history to bulk create
  • +
  • [FIX] severity description in risk schema when risk is 0 or null.
  • +
  • Added cve, cwe, cvss score and risk score to conditions
  • +
  • Add enrichment database key with creation date information in config api
  • +
  • [ADD] risk stats in workspace endpoint.
  • +
  • Add risk score field into Corporate Executive Reports
  • +
+

4.2.0 [Oct 27th, 2022]:

+
    +
  • Add stats param in hosts endpoint.
  • +
  • [FIX] Now get agents dosent returns tokens
  • +
  • [FIX] Now when a constrain is violated faraday use the actual object to query if there is another object
  • +
  • [MOD] Improve agents logs
  • +
  • Add global commands and summary field in command's model +Changes in Faraday Professional:
  • +
  • [FIX] Check if AgentScheduler has tags before running
  • +
  • [FIX] Fix agents_schedule/id/run endpoint adding user_id to get_command_and_agent_execution function +Changes in Faraday Corporate:
  • +
  • Add vulnerability enrichment and risk calculation
  • +
  • [ADD] Settings to enable enrichment
  • +
  • Fix executive reports template for grouped vulnerabilities with markdown.
  • +
  • Upload new executive report templates
  • +
+

4.1.0 [Sep 12th, 2022]:

+
    +
  • Improve the speed of bulk create by adding multiprocessing.
  • +
  • Abort with status_code 503 when try to send vulns with ticketing tools with a template that not exists
  • +
  • [MOD] Asset owners now can tag vulns
  • +
  • Fix showing data of vulns with same parent in grouped executive reports. Also separate website and path on templates.
  • +
  • Add create_date to possible fields on conditions of workflow
  • +
  • Add tool and external_id to pipelines
  • +
+

4.0.4 [Jul 28th, 2022]:

+
    +
  • Remove workspaces agents relationship an now agent can run to multiple workspaces
  • +
  • Fix migration f82a9136c408 checking if index and constrains exist before deleting
  • +
  • Added count to vulns closed
  • +
  • Fix order_by cve_instances__name when no filter was provided
  • +
  • +

    Add index into vulnerability +Changes in Faraday Professional:

    +
  • +
  • +

    Add user_type field to the return of users API +Changes in Faraday Corporate:

    +
  • +
  • +

    Improved regex of username for notifs

    +
  • +
  • User cant delete self
  • +
  • Add list_usernames endpoint to users
  • +
+

4.0.3 [Jun 16th, 2022]:

+
    +
  • Replace usage of strings for user_types enumerator constants
  • +
  • Increase the default duration of faraday token
  • +
  • Fix order by Role in Filters API
  • +
  • Refactor of bulk create API
  • +
  • Remove attachments and attachments_count properties from vulnerability. This improves performance.
  • +
  • Get token from user model
  • +
  • Ignore info and dns resolution as params when uploading report
  • +
  • Replace usage of is_ldap field of User model for user_type
  • +
  • Add user type enumerator
  • +
  • Add weight in role model to sort arbitrarily
  • +
  • Move export CSV from its own endpoint to /filter endpoint as a request's argument
  • +
  • Fix count in filter
  • +
  • Add endpoint to get top 10 most repeated vulns' name
  • +
  • Prevent Admin from changing role of self
  • +
  • Fix bug with grouped report using markdown
  • +
  • Add top ten most affected hosts analytics
  • +
  • Add analytics clone
  • +
  • Add analytics monthly reports
  • +
  • Add endpoint to get vulnerabilities' severities per hosts
  • +
  • Fix pipelines creating empty comments
  • +
  • Add Analytics vulnerabilities by status and by severity
  • +
  • Allow numeric users to be created
  • +
  • Change the date to epoch in planner task api
  • +
+

4.0.2 [Apr 4th, 2022]:

+
    +
  • models.py refactor
  • +
  • add check to see if workspace name is longer than 250 characters. In that case raises an error
  • +
  • Generate token with pyjwt
  • +
  • allow to use email as username
  • +
  • User filter api only show LDAP users if enabled
  • +
  • Change 'user' data type field parser in order to use Faraday's usernames
  • +
  • Added planner feature
  • +
  • Fix last_login for saml login
  • +
+

4.0.1 [Mar 18th, 2022]:

+
    +
  • Improve the logs +Changes in Faraday Professional:
  • +
  • Remove comments' column from CSV exporter
  • +
  • Add a piechart of status of vulns to reports
  • +
+

4.0.0 [Feb 25th, 2022]:

+
    +
  • Add a None limit and 0 offset to GET queries.
  • +
  • Truncate response and requests in reports
  • +
  • Full refactor of Workflows
  • +
+

3.19.0 [Dec 27th, 2021]:

+
    +
  • ADD v3 bulks endpoints DELETE and EDIT (PATCH)
  • +
  • Add logs of login, logout and log error to main log
  • +
  • Fix bug in bulk update for m2m fields
  • +
  • ADD clear settings command
  • +
  • Add open medium, high and critical vulns histogram
  • +
  • Fix integrity constraint error on cve update
  • +
  • FIX static content for react
  • +
  • Add cvss within vulnerability model
  • +
  • add check to see if workspace name is longer than 250 characters. In that case raises an error
  • +
  • change concat in urlstrings for join or urljoin
  • +
  • Add cve to csv export
  • +
  • limited the version of Weasyprint to <53
  • +
  • review of the reports code
  • +
  • Add workspace data to comment notification. Also fix agentexecution notification.
  • +
  • ADD save in history if vuln is re-opened
  • +
  • FIX vuln description in grouped reports
  • +
  • add auth to preference endpoint
  • +
  • FIX notification data fields with None value
  • +
  • Add notification websocket server
  • +
  • filter users field in ws endpoint
  • +
  • Change the hardcoded roles for the roles defined in faraday/server/models.py User
  • +
  • Change warning log to debug
  • +
  • add endpoint for getting Jira public key
  • +
  • clean not used imports
  • +
  • Fixes in workflows
  • +
  • ADD cache to integration configuration
  • +
  • ADD SAML Auth
  • +
+

3.18.1 [Nov 5th, 2021]:

+

Fix CVE issue

+

3.18.0 [Oct 21st, 2021]:

+
    +
  • Remove attachments in vulns filter endpoint
  • +
  • Add open and confirmed vulns in workspace stats
  • +
  • Add migration disabling several notifications.
  • +
  • Add user id to session API endpoint
  • +
  • Add cve to vulnerability model
  • +
  • Change funcs to views
  • +
  • FIX report import
  • +
  • Add last_run_agent_date field to workspace endpoint
  • +
  • Fix cve parsing in vulnerability create and bulk create
  • +
  • ADD check if postgres db is running during server start
  • +
  • Fix order_by in filters api
  • +
  • Fix 500 status code with invalid executor arguments
  • +
+

Changes in Faraday Professional:

+
    +
  • Add vuln stats in reports within hosts and workspace entities
  • +
  • create user validates if users_limit is reached
  • +
  • return 'null date' if pass to method a null or timestamp == 0
  • +
  • remove unused code, dont inform if hosts used are > 4000
  • +
  • Add obj history into notification data payload
  • +
  • FIX issue with images and markdown
  • +
  • Fix agent token api auth
  • +
  • Fix use of notification_enabled config variable in notifier logic
  • +
  • Update report templates to new logo
  • +
  • Add object and event types cache for notification event creation
  • +
  • Fix logs and validation. Also add try/catch in notification event creation.
  • +
  • Fix comments in filtered executive reports
  • +
  • Disable render request and response in PDF templates
  • +
  • Filter schedulers by workspace and executors to prevent remove all workspace's schedulers
  • +
  • add statics to avoid a crash when dont has a valid licence
  • +
  • Fix issue with second jinja rendering
  • +
+

Changes in Faraday Corporate:

+
    +
  • Add vuln's link in Jira's issue description
  • +
  • MOD Search filter API is now usable by all roles
  • +
  • change whoami to view
  • +
  • FIX error creating workflow
  • +
  • Add option to merge multiple vulnerabilities into one Jira issue
  • +
  • Improve Jira's custom fields
  • +
  • Set required key to a Jira custom field
  • +
  • FIX ldap group issue
  • +
  • Replace Jira templates with fields text that accepts Jinja2 syntax for the issue's name and description
  • +
+

3.17.2 [Aug 27th, 2021]:

+

Changes in Faraday Professional:

+
    +
  • FIX ignore for now the notification functions as it's only v4 feature
  • +
+

Changes in Faraday Corporate:

+
    +
  • FIX asset owner is again allowed to edit vulnerabilities' status
  • +
+

3.17.1 [Aug 20th, 2021]:

+
    +
  • FIX bug when starting the server, creates a pool for reporting that breaks.
  • +
+

3.17.0 [Aug 10th, 2021]:

+
    +
  • ADD --data parameter to faraday-manage settings
  • +
  • MOD Process report files in a separate process
  • +
  • MOD Make bulk_create requests asynchronous
  • +
+

Changes in Faraday Professional:

+
    +
  • ADD All features are now controlled by license with more granularity
  • +
  • ADD --mail parameter to faraday-manage initdb
  • +
  • MOD Limit creation of hosts when licence limit is reached
  • +
  • MOD Improve in API filters
  • +
  • MOD Improve logs role reading
  • +
  • FIX Can't alter role when trying to modify the last admin
  • +
+

Changes in Faraday Corporate:

+
    +
  • FIX various bugs in Jira's issue types API
  • +
  • MOD Internal improvement in integrations api
  • +
+

3.16.2 [Jul 2nd, 2021]:

+

Changes in Faraday Professional:

+
    +
  • FIX bug where workspaces are not updatable by UI
  • +
+

3.16.1 [Jul 2nd, 2021]:

+
    +
  • MOD only show settings of this version in faraday-manage settings
  • +
  • FIX update minimum version of click dependency
  • +
+

3.16.0 [Jun 29th, 2021]:

+
    +
  • BREAKING CHANGE: API V2 discontinued
  • +
  • BREAKING CHANGE: Changed minimum version of python to 3.7
  • +
  • ADD agent parameters has types (protocol with agent and its APIs)
  • +
  • ADD move settings from server.in to a db model
  • +
  • ADD (optional) query logs
  • +
  • MOD new threads management
  • +
  • MOD vulnerabilities' endpoint no longer loads evidence unless requested with get_evidence=true
  • +
  • FIX now it is not possible to create workspace of name "filter"
  • +
  • FIX bug with dates in the future
  • +
  • FIX bug with click 8
  • +
  • FIX bug using --port command
  • +
  • FIX endpoints returning 500 as status code
  • +
  • REMOVE the need tom CSRF token from evidence upload api
  • +
+

Changes in Faraday Professional:

+
    +
  • ADD reports can contain user comments
  • +
  • ADD special characters restrictions to faraday-manage create-superuser
  • +
  • ADD randomized id within the generated executive reports
  • +
  • ADD API limited by license presence
  • +
  • ADD redis support as session storage.
  • +
  • ADD server configuration by API
  • +
  • MOD Roles now works with the security library, making API and database changes
  • +
  • MOD code style improvements
  • +
  • FIX endpoints returning 500 as status code
  • +
+

Changes in Faraday Corporate:

+
    +
  • ADD improved regex for scheduled agents
  • +
  • ADD issue types gotten from directly from the user Jira instance's API
  • +
  • MOD match ServiceNow OAuth endpoint's URL with the same format as Jira
  • +
  • FIX typo when running faraday-manage database-schema
  • +
  • FIX error downloading logs using LDAP
  • +
  • REMOVE unnecessary data sent to integrations endpoints
  • +
+

3.15.1 [May 31st, 2021]:

+

Changes in Faraday Corporate:

+
    +
  • FIX workspace comparison
  • +
+

3.15.0 [May 18th, 2021]:

+
    +
  • ADD Basic Auth support
  • +
  • ADD support for GET method in websocket_tokens, POST will be deprecated in the future
  • +
  • ADD CVSS(String), CWE(String), CVE(relationship) columns to vulnerability model and API
  • +
  • ADD agent token's API says the renewal cycling duration
  • +
  • MOD Improve database model to be able to delete workspaces fastly
  • +
  • MOD Improve code style and uses (less flake8 exceptions, py3 super style, Flask app as singleton, etc)
  • +
  • MOD workspaces' names regex to verify they cannot contain forward slash (/)
  • +
  • MOD Improve bulk create logs
  • +
  • FIX Own schema breaking Marshmallow 3.11.0+
  • +
  • UPD flask_security_too to version 4.0.0+
  • +
+

Changes in Faraday Professional:

+
    +
  • ADD reading feature flags from the license. (Feature flags are InProgress)
  • +
  • ADD mult_websocket_token API GET method, POSTwill be deprecated.
  • +
  • MOD improve regex for agent scheduling
  • +
  • MOD improve code stability (more testing, less flake8 exceptions)
  • +
+

Changes in Faraday Corporate:

+
    +
  • ADD OAuth2.0 to ServiceNow integration
  • +
  • MOD Actions API return which model is from that action
  • +
  • MOD Save issuetracker from backend instead of from frontend
  • +
  • MOD ServiceNow OAuth endpoint's URL to the same format as Jira
  • +
  • FIX Role change with LDAP login
  • +
  • FIX serviceNow integration bug when the configuration is empty
  • +
  • FIX bug when using in Jira's custom field
  • +
+

3.14.4 [Apr 15th, 2021]:

+
    +
  • Updated plugins package, which update appscan plugin
  • +
+

Changes in Faraday Corporate:

+
    +
  • FIX Get list of jira templates
  • +
+

3.14.3 [Mar 30th, 2021]:

+
    +
  • MOD MAYOR Breaking change: Use frontend from other repository
  • +
  • ADD last_run to executors and agents
  • +
  • ADD ignore info vulns option (from faraday-plugins 1.4.3)
  • +
  • ADD invalid logins are registered in audit.log
  • +
  • ADD agent registration tokens are now 6-digit short and automatically regenerated every 30 seconds
  • +
  • MOD Fix logout redirect loop
  • +
  • REMOVE support for native SSL
  • +
+

Changes in Faraday Professional:

+
    +
  • MOD Fix user creation when trying to use an already registered email or numeric username
  • +
  • MOD FIX API validation in /v2/2fa/confirm, which returned error
  • +
  • MOD migrate secrets from 2FA from 16 to 32 length size. WARN: if you first upgrade, and then downgrade the database, 2FA will be desactivated in some users (can't fix 32 in 16 length)
  • +
+

Changes in Faraday Corporate:

+
    +
  • ADD validation for crontab in agent scheduling
  • +
  • ADD New workflow API, only in V3 API: /ws/<workspace_name>/workflow/. It reimplements the +POST logic to only need to use one POST.
  • +
  • MOD Fix bug in generate-rsa-keys command when no integration configuration has been saved. In this case, the user + must save the configuration through the Settings section of the web UI
  • +
  • MOD Fix the ticket subject in whd integration and add name and ws to detail
  • +
  • MOD Change integrations issue's URL key in response from 'self' to 'url'
  • +
+

3.14.2 [Feb 26th, 2021]:

+
    +
  • ADD New plugins:
      +
    • microsoft baseline security analyzer
    • +
    • nextnet
    • +
    • openscap
    • +
    +
  • +
  • FIX old versions of Nessus plugins bugs
  • +
+

3.14.1 [Feb 17th, 2021]:

+
    +
  • ADD forgot password
  • +
  • ADD update services by bulk_create
  • +
  • ADD FARADAY_DISABLE_LOGS varibale to disable logs to filesystem
  • +
  • ADD security logs in audit.log file
  • +
  • UPD security dependency Flask-Security-Too v3.4.4
  • +
  • MOD rename total_rows field in filter host response
  • +
  • MOD improved Export cvs performance by reducing the number of queries
  • +
  • MOD sanitize the content of vulns' request and response
  • +
  • MOD dont strip new line in description when exporting csv
  • +
  • MOD improved threads management on exception
  • +
  • MOD improved performance on vulnerability filter
  • +
  • MOD improved API documentation
  • +
  • FIX upload a report with invalid custom fields
  • +
  • ADD v3 API, which includes:
      +
    • All endpoints ends without /
    • +
    • PATCH {model}/id endpoints
    • +
    • ~~Bulk update via PATCH {model} endpoints~~ In a future release
    • +
    • ~~Bulk delete via DELETE {model} endpoints~~ In a future release
    • +
    • Endpoints removed:
    • +
    • /v2/ws/<workspace_id>/activate/
    • +
    • /v2/ws/<workspace_id>/change_readonly/
    • +
    • /v2/ws/<workspace_id>/deactivate/
    • +
    • /v2/ws/<workspace_name>/hosts/bulk_delete/
    • +
    • /v2/ws/<workspace_name>/vulns/bulk_delete/
    • +
    • Endpoints updated:
    • +
    • /v2/ws/<workspace_name>/vulns/<int:vuln_id>/attachments/ => \ + /v3/ws/<workspace_name>/vulns/<int:vuln_id>/attachment
    • +
    +
  • +
+

Changes in Faraday Professional:

+
    +
  • ADD vuln history in comments
  • +
  • MOD Enable PDF reports by default
  • +
  • MOD List executive report by format
  • +
  • ADD v3 API, which includes:
      +
    • All PUT 2FA methods change to POST:
        +
      • /v3/users/{user_id}/disable2fa
      • +
      • /v3/users/{user_id}/request2fa
      • +
      • /v3/2fa/confirm
      • +
      • /v3/2fa/disable
      • +
      • /v3/2fa/enable
      • +
      +
    • +
    +
  • +
+

Changes in Faraday Corporate:

+
    +
  • ADD category support and SSL to WHD
  • +
  • MOD Change integrations' endpoint for maintenance reasons
  • +
  • MOD Improve data of agent schedule properly set when agents are removed
  • +
  • FIX Run Agent schedule control less often
  • +
  • FIX cron generated with * in minutes
  • +
  • FIX error when running scheduled agents
  • +
  • FIX Agent schedule removed when a workspace is dissociated from agent
  • +
+

3.14.0 [Dec 23th, 2020]:

+
    +
  • ADD RESTless filter to multiples views, improving the searchs
  • +
  • ADD "extras" modal in options menu, linking to other Faraday resources
  • +
  • ADD import vulnerability templates command to faraday-manage
  • +
  • ADD generate nginx config command to faraday-manage
  • +
  • ADD vulnerabilities severities count to host
  • +
  • ADD Active Agent columns to workspace
  • +
  • ADD critical vulns count to workspace
  • +
  • ADD Remember me login option
  • +
  • ADD distinguish host flag
  • +
  • ADD a create_date field to comments
  • +
  • FIX to use new webargs version
  • +
  • FIX Custom Fields view in KB (Vulnerability Templates)
  • +
  • FIX bug on filter endpoint for vulnerabilities with offset and limit parameters
  • +
  • FIX bug raising 403 Forbidden HTTP error when the first workspace was not active
  • +
  • FIX bug when changing the token expiration change
  • +
  • FIX bug in Custom Fields type Choice when choice name is too long.
  • +
  • FIX Vulnerability Filter endpoint Performance improvement using joinedload. Removed several nplusone uses
  • +
  • MOD Updating the template.ini for new installations
  • +
  • MOD Improve SMTP configuration
  • +
  • MOD The agent now indicates how much time it had run (faraday-agent-dispatcher v1.4.0)
  • +
  • MOD Type "Vulnerability Web" cannot have "Host" type as a parent when creating data in bulk
  • +
  • MOD Expiration default time from 1 month to 12 hour
  • +
  • MOD Improve data reference when uploading a new report
  • +
  • MOD Refactor Knowledge Base's bulk create to take to take also multiple creation from vulns in status report.
  • +
  • MOD All HTTP OPTIONS endpoints are now public
  • +
  • MOD Change documentation and what's new links in about
  • +
  • REMOVE Flask static endpoint
  • +
  • REMOVE of our custom logger
  • +
+

Changes in Faraday Professional:

+
    +
  • ADD workspaces to users list
  • +
  • ADD possibility to assign multiple workspaces when creating or updating users
  • +
  • ADD possibility to avoid brute force in login by configuration limiting request/time
  • +
  • ADD copy vuln link button
  • +
  • ADD users list is ordered by status by default
  • +
  • FIX bug in Executive Report's regenerate button just downloading the older file
  • +
  • FIX executive reports sorting by date
  • +
  • FIX bug that prevent using ws in https
  • +
  • FIX bug in status-check, when try to authenticate using LDAP giving bad error messages.
  • +
  • MOD Improve expired license message
  • +
+

Changes in Faraday Corporate:

+
    +
  • ADD Gitlab integration
  • +
  • ADD OAuth authentication to JIRA integration
  • +
  • ADD LDAP Group for asset owner profile
  • +
  • ADD SolarWinds integration
  • +
  • FIX bug in Jira integration by setting 'Bug' as default issue type
  • +
  • FIX bug when saving Jira's custom fields in the database
  • +
  • FIX okta ldap integration to use roles from ldap
  • +
  • MOD Improve integrations logs
  • +
+

3.12 [Sep 3rd, 2020]:

+
    +
  • Now agents can upload data to multiples workspaces
  • +
  • Add agent and executor data to Activity Feed
  • +
  • Add session timeout configuration to server.ini configuration file
  • +
  • Add hostnames to already existing hosts when importing a report
  • +
  • Add new faraday background image
  • +
  • Display an error when uploading an invalid report
  • +
  • Use minimized JS libraries to improve page load time
  • +
  • Fix aspect ratio distortion in evidence tab of vulnerability preview
  • +
  • Fix broken Knowledge Base upload modal
  • +
  • Fix closing of websocket connections when communicating with Agents
  • +
  • Change Custom Fields names in exported CSV to make columns compatible with + faraday_csv plugin
  • +
  • Fix import CSV for vuln template: some values were overwritten with default values.
  • +
  • Catch errors in faraday-manage commands when the connection string is not + specified in the server.ini file
  • +
  • Fix bug that generated a session when using Token authentication
  • +
  • Fix bug that requested to the API when an invalid filter is used
  • +
  • Cleanup old sessions when a user logs in
  • +
  • Remove unmaintained Flask-Restless dependency
  • +
  • Remove pbkdf2_sha1 and plain password schemes. We only support bcrypt
  • +
+

Changes in Faraday Professional:

+
    +
  • Add create_time field to the context of vulns in grouped executive reports. + Its value is the oldest date in the group of vulnerabilities
  • +
  • Add group_vulns field to the context of vulns in grouped executive reports. + It contains a list of the vulnerabilities included in the group.
  • +
  • Add tasks information to executive reports
  • +
  • Add hosts' and services' tags to export CSV
  • +
  • Add tags support to bulk create API
  • +
  • Fix bug in dashboard's commands history view.
  • +
  • Fix bug rendering {{vuln.description}} in markdown executive reports
  • +
  • Fix bug importing tasks with special characters
  • +
  • Fix bug running libreoffice on MacOS
  • +
  • Fix missing evidence from generic markdown report
  • +
  • Save the real ip address of the user when the server is used behind a proxy
  • +
+

Changes in Faraday Corporate:

+
    +
  • Add Jinja2 templates to parse the vulnerability data to be sent to ticketing + tools (Jira and ServiceNow)
  • +
  • Fix server errors when using workflows
  • +
  • Fix vulnerability issuetracker column bug triggered when adding tags
  • +
  • Improve error messages for LDAP authentication in the status check command
  • +
+

3.11.2 [Aug 6th, 2020]:

+
    +
  • Fix missing evidence from generic reports with markdown
  • +
  • Fix JPG evidence in executive reports
  • +
  • Fix workspace comparasion
  • +
+

3.11.1 [Jun 3rd, 2020]:

+
    +
  • Fix missing shodan icon and invalid link in dashboard and hosts list
  • +
  • Upgrade marshmallow, webargs, werkzeug and flask-login dependencies to + latest versions in order to make packaging for distros easier
  • +
+

Changes in Faraday Professional:

+
    +
  • Fix import CSV for vuln templates (some values were overwritten with default values)
  • +
  • Add an endpoint to download logs
  • +
  • Improve password autocomplete behavior when editing users from the Web UI
  • +
  • UX improvements in users ediiton (don't close the modal then clicking out of + the modal dialog)
  • +
  • UX improvements in evidence uploading
  • +
+

Changes in Faraday Corporate:

+
    +
  • Update threadfix mappings of description, resolution, data and custom field + cvss_score. Only export confirmed vulns.
  • +
+

3.11 [Apr 22nd, 2020]:

+
    +
  • Move GTK client to another repository to improve release times.
  • +
  • Fix formula injection vulnerability when exporting vulnerability data to CSV. This was considered a low impact vulnerability.
  • +
  • Remove "--ssl" parameter. Read SSL information from the config file.
  • +
  • Add OpenAPI autogenerated documentation support
  • +
  • Show agent information in command history
  • +
  • Add bulk delete endpoint for hosts API
  • +
  • Add column with information to track agent execution data
  • +
  • Add tool attribute to vulnerability to avoid incorrectly showing "Web UI" as creator tool
  • +
  • Add sorting by target in credentials view
  • +
  • Add creator information when uploading reports or using de bulk create api
  • +
  • Add feature to disable rules in the searcher
  • +
  • Add API endpoint to export Faraday data to Metasploit XML format
  • +
  • Change websocket url route from / to /websockets
  • +
  • Use run date instead of creation date when plugins report specifies it
  • +
  • Improve knowledge base UX
  • +
  • Improve workspace table and status report table UX.
  • +
  • Improve format of exported CSV to include more fields
  • +
  • Sort results in count API endpoint
  • +
  • Limit description width in knowledge base
  • +
  • Change log date format to ISO 8601
  • +
  • Fix parsing server port config in server.ini
  • +
  • Fix bug when _rev was send to the hosts API
  • +
  • Send JSON response when you get a 500 or 404 error
  • +
  • Fix bug parsing invalid data in NullToBlankString
  • +
+

Changes in plugins (only available through Web UI, not in GTK client yet):

+

New plugins:

+
    +
  • Checkmarx
  • +
  • Faraday_csv (output of exported Faraday csv)
  • +
  • Qualyswebapp
  • +
  • Whitesource
  • +
+

Updated plugins:

+
    +
  • Acunetix
  • +
  • AppScan
  • +
  • Arachni
  • +
  • Nessus
  • +
  • Netspaker
  • +
  • Netspaker cloud
  • +
  • Nexpose
  • +
  • Openvas
  • +
  • QualysGuard
  • +
  • Retina
  • +
  • W3af
  • +
  • WPScan
  • +
  • Webinspect
  • +
  • Zap
  • +
+

Changes in Faraday Professional:

+
    +
  • Add methodologies API improvements
  • +
  • Add endpoint to update multiple tags on multiple vulns
  • +
  • Add new "markdown" custom field type
  • +
  • Disable markdown for custom fields of type "string" (if you need it, use + "markdown" instead)
  • +
  • Improve hosts view styles when table is empty
  • +
  • Improve Web UI first load time
  • +
  • Improve executive reports UX.
  • +
  • Fix bug when showing "data" field in grouped executive reports
  • +
  • Fix showing of vulnerabilities with unclassified severity in executive reports
  • +
  • Fix bug in executive report filters when vulnerability had attachments
  • +
  • Fix ordering by date in executive reports.
  • +
  • Fix bug when importing invalid tasks CSV
  • +
  • Fix bug when creating users with "asset owner" role
  • +
  • Don't show disabled users when creating a workspace
  • +
+

Changes in Faraday Corporate:

+
    +
  • Add run agent button in scheduling table
  • +
  • Add issuetracker_json vulnerability field to allow using issue tracker + data inside executive reports.
  • +
  • Add legend in scheduling table when there are not elements
  • +
  • Add a descriptive sentence to the action's name in workflows
  • +
  • Remove default user's credentials from ticketing tools configuration.
  • +
  • Fix error when loading LDAP config
  • +
+

3.10.2 [Jan 30th, 2020]:

+
    +
  • Fix Cross-Site Request Forgery (CSRF) vulnerability in all JSON API endpoints. +This was caused because a third-party library doesn't implement proper +Content-Type header validation. To mitigate the vulnerability, we set the +session cookie to have the SameSite: Lax property.
  • +
  • Fix Faraday Server logs were always in debug
  • +
  • Add update date column when exporting vulnerabilities to CSV
  • +
  • Fix unicode error when exporting vulnerabilities to CSV
  • +
+

Changes in Faraday Professional:

+
    +
  • Fix download report docx was not working when the user clicked on csv before docx
  • +
  • Add vulnerability status field in grouped executive reports
  • +
+

3.10.1 [Jan 10th, 2020]:

+
    +
  • Fix installation with pip install --no-binary :all: faradaysec
  • +
  • Force usage of webargs 5 (webargs 6 broke backwards compatibility)
  • +
  • Use latest version of faraday-plugins
  • +
  • Fix broken "Faraday Plugin" menu entry in the GTK client
  • +
  • Extract export csv to reuse for reports
  • +
+

Changes in Faraday Professional:

+
    +
  • Fix a bug when custom field is None or type int in executive reports
  • +
  • Fix new lines bug with markdown executive reports
  • +
  • Add nativeSeverity to ThreadFix export data
  • +
  • Fix reports borders in images within vulnerability description
  • +
+

Changes in Faraday Corporate:

+
    +
  • Bugfix allow to change the roles when using ldap with use_local_roles
  • +
+

3.10 [Dec 19th, 2019]:

+
    +
  • Use Python 3 instead of Python 2 in the Faraday Server
  • +
  • Add ability to manage agents with multiple executors
  • +
  • Agents can be run with custom arguments
  • +
  • Improved processing of uploaded reports. Now it is much faster!
  • +
  • Add custom fields of type choice
  • +
  • Fix vuln status transition in bulk create API (mark closed vulns as re-opened when they are triggered again)
  • +
  • Fix bug when using non-existent workspaces in Faraday GTK Client
  • +
  • Set service name as required in the Web UI
  • +
  • Validate the start date of a workspace is not greater than the end date
  • +
  • Fix command API when year is invalid
  • +
  • When SSL misconfigurations cause websockets to fails it doesn't block server from starting
  • +
  • Check for invalid service port number in the Web UI
  • +
  • Fix dashboard tooltips for vulnerability
  • +
  • Fix bug when GTK client lost connection to the server
  • +
  • Fix style issues in "Hosts by Service" modal of the dashboard
  • +
  • Add API for bulk delete of vulnerabilities
  • +
  • Add missing vuln attributes to exported CSV
  • +
  • faraday-manage support now displays the Operating System version
  • +
  • Notify when faraday-manage can't run becasue of PostgreSQL HBA config error
  • +
+

Changes in Faraday Professional:

+
    +
  • Add faraday-manage import-license command
  • +
  • Fix issue with users with dot (.)
  • +
  • Fix second factor login
  • +
  • Fix datetimeformat parsing on executive report templates, we now support for datetime strings
  • +
  • Generate a CSV file in addition to the DOCX generated in executive reports
  • +
  • Fix executive report generation when filtering by tags
  • +
  • Grouped executive reports can use vuln counter and hostnames
  • +
  • Fix vuln sorting in grouped executive reports
  • +
  • Fix bug in dates during workspace creation/edition
  • +
+

Changes in Faraday Corporate:

+
    +
  • Add support for OKTA LDAP interface
  • +
  • Deactivated workspaces not listed in Workspace Comparison
  • +
+

3.9.3 [Nov 12th, 2019]:

+
    +
  • Fix unicode error when exporting vulns to CSV
  • +
  • Add vuln attributes to CSV
  • +
  • Fix hostname parsing and add external ID to Qualys plugin
  • +
  • Fix search by tags on vulnerability view
  • +
  • Fix executive report filters, add missing URL decode
  • +
+

3.9 [Oct 3th, 2019]:

+
    +
  • Add agents feature for distributed plugin execution
  • +
  • Add an API endpoint to to perform a bulk create of many objects (hosts, + services, vulns, commands and credentials). This is used to avoid doing a lot + of API requests to upload data. Now one request should be enough
  • +
  • Major style and color changes to the Web UI
  • +
  • Add API token authentication method
  • +
  • Use server side stored sessions to properly invalidate cookies of logged out users
  • +
  • Add "New" button to create credentials without host or service assigned yet
  • +
  • Allow filtering hosts by its service's ports in the Web UI
  • +
  • Performance improvements in vulnerabilities and vulnerability templates API (they + were doing a lot of SQL queries because of a programming bug)
  • +
  • Require being in the faraday-manage group when running faraday from a .deb or .rpm package
  • +
  • Change the first page shown after the user logs in. Now it displays a workspace + selection dialog
  • +
  • Add API endpoint to import Vuln Templates from a CSV file
  • +
  • Create the exported CSV of the status report in the backend instead of in the +problem, which was much slower
  • +
  • Add API endpoint to import hosts from a CSV file
  • +
  • Add faraday-manage rename-user command to change a user's username
  • +
  • Allow resizing columns in Vulnerability Templates view
  • +
  • Avoid copying technical details when a vuln template is generated from the status report
  • +
  • Use exact matches when searching vulns by target
  • +
  • Add API endpoint to get which tools impacted in a host
  • +
  • Add pagination to activity feed
  • +
  • Add ordering for date and creator to vuln templates view
  • +
  • Modify tabs in vuln template, add Details tab
  • +
  • Add copy IP to clipboard button in hosts view
  • +
  • Add creator and create date columns to vuln template view
  • +
  • When a plugin creates a host with its IP set to a domain name, + resolve the IP address of that domain
  • +
  • Add support for logging in RFC5254 format
  • +
  • Add active filter in workspaces view. Only show active workspaces + in other parts of the Web UI
  • +
  • Enforce end date to be greater than start date in workspaces API
  • +
  • Fix bug in faraday-manage create-tables that incorrectly marked schema + migrations as applied
  • +
  • Fix bug in many plugins that loaded hostnames incorrectly (one hostname per chararcter)
  • +
  • Improve references parsing in OpenVAS plugin
  • +
  • Fix a bug in Nessus plugin when parsing reports without host_start
  • +
  • Fix bug hostname search is now working in status-report
  • +
  • Fix showing of services with large names in the Web UI
  • +
  • Fix broken select all hosts checkbox
  • +
  • Fix bug viewing an attachment/evidence when its filename contained whitespaces
  • +
  • Fix "Are you sure you want to quit Faraday?" dialog showing twice in GTK
  • +
+

Changes in Faraday Professional:

+
    +
  • Add new license schema checks
  • +
  • Add agents scheduling feature
  • +
  • Add new role asset owner
  • +
  • Markdown is enabled for new installs
  • +
  • Only require pandoc install when markdown is enabled
  • +
  • Add border size configuration for executive reports
  • +
  • Improve user table style
  • +
  • Improve UX for public workspaces in the Web UI
  • +
  • Allow filtering vulns when generating executive reports
  • +
  • Fix a bug on report generation that caused a broken .docx file and it was not possible to open with MS word
  • +
  • Fix bug when SIGTERM was send to the GTK client, one thread was not stopped
  • +
  • Fix content type when downloading vuln evidence
  • +
  • Fix reactivate user option
  • +
  • Fix severity dropdown display in vulnerability template modal
  • +
  • Refactor timeline stats generation
  • +
+

Changes in Faraday Corporate:

+
    +
  • Add new charts in Workspace Comparison
  • +
  • Improve pagination view of tables in the section Most Vulnerable Hosts of Workspace Comparison
  • +
  • Add vuln information through the issue description of ticketing tools
  • +
  • Add smtp setting
  • +
  • Fix bug in tags creation when no service was selected
  • +
+

3.8.1 [Jun 19th, 2019]:

+
    +
  • Add configurations for websocket ssl
  • +
  • Fix a bug on report generation that caused a broken .docx file and it was not possible to open with MS word
  • +
  • Add session timeout configuration to server.ini
  • +
  • Add configurations for websocket ssl
  • +
+

3.8 [Jun 4th, 2019]:

+
    +
  • Refactor the project to use absolute imports to make the installation easier +(with a setup.py file). This also was a first step to make our codebase +compatible with python 3.
  • +
  • Change the commands used to run faraday. ./faraday-server.py, + ./manage.py, ./faraday.py and bin/flugin are replaced for faraday-server, faraday-manage, + faraday-client and fplugin respectively
  • +
  • Changed suggested installation method. Now we provide binary executables with all python dependencies + embedded into them
  • +
  • Add admin panel to the Web UI to manage custom fields
  • +
  • Fix slow host list when creating vulns in a workspace with many hosts
  • +
  • Usability improvements in status report: change the way vulns are selected and confirmed
  • +
  • Improve workspace workspace creation from the Web UI
  • +
  • Fix attachment api when file was not found in .faraday/storage
  • +
  • Fix visualization of the fields Policy Violations and References.
  • +
  • Add a setting in server.ini to display the Vulnerability Cost widget of the Dashboard
  • +
  • Fix status report resize when the browser console closes.
  • +
  • Fix severity dropdown when creating vulnerability templates
  • +
  • Update OS icons in the Web UI.
  • +
  • Fix bug when using custom fields, we must use the field_name instead of the display_name
  • +
  • Prevent creation of custom fields with the same name
  • +
  • Add custom fields to vuln templates.
  • +
  • Fix user's menu visibily when vuln detail is open
  • +
  • Remove "show all" option in the status report pagination
  • +
  • The activity feed widget of the dashboard now displays the hostname of the + machine that runned each command
  • +
  • Add loading spinner in hosts report.
  • +
  • Fix "invalid dsn" bug in sql-shell
  • +
  • Fix hostnames bug in Nikto and Core Impact plugins
  • +
  • Change Openvas plugin: Low and Debug threats are not taken as vulnerabilities.
  • +
  • Add fplugin command to close vulns created after a certain time
  • +
  • Add list-plugins command to faraday-manage to see all available plugins
  • +
  • Fix a logging error in PluginBase class
  • +
  • Fix an error when using NexposePlugin from command line.
  • +
  • Add CSV parser to Dnsmap Plugin
  • +
  • Fix bug when creating web vulnerabilities in dirb plugin
  • +
  • Change Nexpose Severity Mappings.
  • +
+

Changes in Faraday Professional:

+
    +
  • Add feature to create comments and notifications in Faraday
  • +
  • Fix a bug that incorrectly cleared the tags of a vuln when it was being edited
  • +
  • Redesign account settings modal
  • +
  • Add template preview to executive reports view.
  • +
  • Add alert before closing executive report popup.
  • +
  • Fix validation on executive reporte when popup opens.
  • +
  • Skip adding images to executive reports if the image is invalid
  • +
  • Fix "Unknown" vuln count in executive reports view
  • +
  • Fix bug logging in users with role client
  • +
  • Add API token authentication method
  • +
  • Fix group by in status report
  • +
  • Fix tags vuln edit
  • +
  • Fix user assignation to tasks
  • +
  • Fix bug when changing the state of tasks
  • +
+

Changes in Faraday Corporate:

+
    +
  • Add --no_ldap option when running command "faraday-manage status_check" for skipping LDAP check
  • +
  • Fix bug when clicking in vulns in the "last vulns" dashboard widget
  • +
+

3.7.3 [May 3rd, 2019]:

+
    +
  • Add parser for connection string at PGCli connection
  • +
  • Fix bug when using custom fields, we must use the field_name instead of the display_name
  • +
  • Fix user's menu visibily when vuln detail is open.
  • +
  • Fix bug in status report that incorrectly showed standard vulns like if they were vulnwebs
  • +
  • Fix group by in status report.
  • +
  • Fix task state change.
  • +
+

3.7.2 [Apr 15th, 2019]:

+
    +
  • Fix status-report load when user clicks dashboard links.
  • +
  • Fix role client can't access status-report.
  • +
+

3.7 [Apr 3rd, 2019]:

+
    +
  • Add vulnerability preview to status report
  • +
  • Update Fierce Plugin. Import can be done from GTK console.
  • +
  • Update Goohost plugin and now Faraday imports Goohost .txt report.
  • +
  • Update plugin for support WPScan v-3.4.5
  • +
  • Update Qualysguard plugin to its 8.17.1.0.2 version
  • +
  • Update custom fields with Searcher
  • +
  • Update Recon-ng Plugin so that it accepts XML reports
  • +
  • Add postres version to status-change command
  • +
  • Couchdb configuration section will not be added anymore
  • +
  • Add unit test for config/default.xml
  • +
  • Add markdown in executive reports.
  • +
  • Add border to images. Improves images with white background in executive reports
  • +
  • Add datetime format of start date and end date from a workspace in Executive Report
  • +
  • Add error message when port is being used
  • +
  • Fix bug in vuln.type comparison inside the grouped report template
  • +
  • Hide icons and menus from the Web UI for role client
  • +
  • Fix bug in JIRA test cases
  • +
+

3.6 [Feb 21th, 2019]:

+
    +
  • Fix CSRF (Cross-Site Request Forgery) vulnerability in vulnerability attachments API. + This allowed an attacker to upload evidence to vulns. He/she required to know the + desired workspace name and vulnerability id so it complicated the things a bit. We + classified this vuln as a low impact one.
  • +
  • Readonly and disabled workspaces
  • +
  • Add fields 'impact', 'easeofresolution' and 'policyviolations' to vulnerability_template
  • +
  • Add pagination in 'Command history', 'Last Vulnerabilities', 'Activity logs' into dashboard
  • +
  • Add status_code field to web vulnerability
  • +
  • Preserve selection after bulk edition of vulnerabilities in the Web UI
  • +
  • Faraday's database will be created using UTF-8 encoding
  • +
  • Fix bug of "select a different workspace" from an empty list loop.
  • +
  • Fix bug when creating duplicate custom fields
  • +
  • Fix bug when loading in server.ini with extra configs
  • +
  • Fix ./manage.py command. It wasn't working since the last schema migration
  • +
  • ./manage.py createsuperuser command renamed to ./manage.py create-superuser
  • +
  • Fix bug when non-numeric vulnerability IDs were passed to the attachments API
  • +
  • Fix logic in search exploits
  • +
  • Add ability to 'Searcher' to execute rules in loop with dynamic variables
  • +
  • Send searcher alert with custom mail
  • +
  • Add gitlab-ci.yml file to execute test and pylint on gitlab runner
  • +
  • Fix 500 error when updating services and vulns with specific read-only parameters set
  • +
  • Fix SQLMap plugin to support newer versions of the tool
  • +
  • Improve service's parser for Lynis plugin
  • +
  • Fix bug when parsing URLs in Acunetix reports
  • +
  • Fix and update NetSparker Plugin
  • +
  • Fix bug in nessus plugin. It was trying to create a host without IP. Enabled logs on the server for plugin processing (use --debug)
  • +
  • Fix bug when parsing hostnames in Nessus reports
  • +
  • Fix SSLyze report automatic detection, so reports can be imported from the web ui
  • +
  • Update Dnsmap Plugin
  • +
+

Changes in Faraday Professional:

+
    +
  • Add workspace attributes to the available elements for executive reports
  • +
  • Solve incompatibility between docxtpl and python-docx
  • +
  • Fix bug that didn't list public workspaces to pentesters and clients when the user didn't have permissions for any private workspace
  • +
  • Fix bug with case insensitive logins
  • +
  • When showing evidence on the executive report you will no longer have the + name of the image bellow the picture
  • +
  • Fix 'Coverparagraph' error in Executire Report
  • +
  • Manage the availability of workspaces taking into account their associated users.
  • +
+

Changes in Faraday Corporate:

+
    +
  • Changes in Jira Integration
  • +
  • ServiceNow Integration
  • +
  • Use pagination for ldap to avoid memory errors
  • +
+

3.5 [Jan 16th, 2019]:

+
    +
  • Redesgin of new/edit vulnerability forms
  • +
  • Add new custom fields feature to vulnerabilities
  • +
  • Add ./manage.py migrate to perform alembic migrations
  • +
  • Faraday will use webargs==4.4.1 because webargs==5.0.0 fails with Python2
  • +
  • New system for online plugins using Threads, a few fixes for metasploit plugin online also.
  • +
  • Fix Command "python manage.py process-reports" now stops once all reports have been processed
  • +
  • Fix bug in query when it checks if a vulnerability or a workspace exists
  • +
  • Fix Once a workspace is created through the web UI, a folder with its name is created inside ~/.faraday/report/
  • +
  • The manage.py now has a new support funtionality that creates a .zip file with all the information faraday's support team will need to throubleshoot your issue
  • +
  • Status-check checks PostgreSQL encoding
  • +
  • Fix a bug when fail importation of reports, command duration say "In Progress" forever.
  • +
  • Fix confirmed bug in vulns API
  • +
  • Update websockets code to use latest lib version
  • +
  • bootstrap updated to v3.4.0
  • +
  • Manage.py support now throws a message once it finishes the process.
  • +
  • Update Lynis to its version 2.7.1
  • +
  • Updated arp-scan plugin, added support in the Host class for mac address which was deprecated before v3.0
  • +
  • OpenVAS Plugin now supports OpenVAS v-9.0.3
  • +
+

Changes in Faraday Professional:

+
    +
  • Add 2 Factor Authentication
  • +
  • Now you can re-activate an User in WEBUI
  • +
  • Show users "disabled/deleted" in WEB-UI list of users.
  • +
  • Enabled Security Tracking options for flask-security. Expanded User API and Users Frontend. Added current_ip
  • +
  • Update the GTK license check to the latest API.
  • +
  • Don't alter current selection when clicking on download or renerate buttons in executive report list
  • +
+

3.4 [December 6th, 2018]:

+
    +
  • In GTK, check active_workspace its not null
  • +
  • Add fbruteforce services fplugin
  • +
  • Attachments can be added to a vulnerability through the API.
  • +
  • Catch gaierror error on lynis plugin
  • +
  • Add OR and NOT with parenthesis support on status report search
  • +
  • Info API now is public
  • +
  • Web UI now detects Appscan plugin
  • +
  • Improve performance on the workspace using cusotm query
  • +
  • Workspaces can be set as active/disable in welcome page.
  • +
  • Change Nmap plugin, response field in VulnWeb now goes to Data field.
  • +
  • Update code to support latest SQLAlchemy version
  • +
  • Fix create_vuln fplugin bug that incorrectly reported duplicated vulns
  • +
  • Attachments on a vulnerability can be deleted through the API.
  • +
  • Improvement in the coverage of the tests.
  • +
  • The client can set a custom logo to Faraday
  • +
  • Centered checkboxes in user list page
  • +
  • Client or pentester can't activate/deactivate workspaces
  • +
  • In GTK, dialogs now check that user_info is not False
  • +
  • Add tags in Service object (Frontend and backend API)
  • +
  • Limit of users only takes the active ones
  • +
  • Improve error message when the license is not valid
  • +
  • Added new funtionality to status check, it now shows you user licence and general config information.
  • +
+

3.3 [Novemeber 14th, 2018]:

+
    +
  • Add workspace disable feature
  • +
  • Add mac vendor to host and services
  • +
  • Fix typos and add sorting in workspace name (workspace list view)
  • +
  • Improve warning when you try to select hosts instead of services as targets of a Vulnerability Web
  • +
  • Deleted old Nexpose plugin. Now Faraday uses Nexpose-Full.
  • +
  • Update sqlmap plugin
  • +
  • Add updated zap plugin
  • +
  • Add hostnames to nessus plugin
  • +
  • Python interpreter in SSLCheck plugin is not hardcoded anymore.
  • +
  • Fix importer key error when some data from couchdb didn't contain the "type" key
  • +
  • Fix AttributeError when importing vulns without exploitation from CouchDB
  • +
  • Fix KeyError in importer.py. This issue occurred during the import of Vulnerability Templates
  • +
  • Fix error when file config.xml doesn't exist as the moment of executing initdb
  • +
  • Improve invalid credentials warning by indicating the user to run Faraday GTK with --login option
  • +
  • Fix typos in VulnDB and add two new vulnerabilities (Default Credentials, Privilege Escalation)
  • +
  • Improved tests performance with new versions of the Faker library
  • +
  • abort() calls were checked and changed to flask.abort()
  • +
  • Add tags in Host object (Frontend and backend API)
  • +
  • Improve performance of executive reports on big workspaces
  • +
  • Fplugin exports workspace's information in XLSX format
  • +
  • Add refs property to vuln parent in grouped report
  • +
  • Update license code with the new portal
  • +
  • Made the url path using urlib instead of manual
  • +
  • Fixed bug when tags in json are integers
  • +
+

3.2 [October 17th, 2018]:

+
    +
  • Added logical operator AND to status report search
  • +
  • Restkit dependency removed.
  • +
  • Improvement on manage.py change-password
  • +
  • Add feature to show only unconfirmed vulns.
  • +
  • Add ssl information to manage.py status-check
  • +
  • Update wpscan plugin to support latest version.
  • +
  • Allow workspace names starting with numbers.
  • +
+

September 21, 2018:

+
    +
  • Fix bug: manage.py status_check
  • +
  • Fix bug: manage.py initdb
  • +
+

September 17, 2018:

+
    +
  • Fix get exploits API
  • +
  • New searcher feature
  • +
  • Added host_os column to status report
  • +
  • Fix and error while trying to execute server with --start
  • +
  • Added option --choose-password to initdb
  • +
  • Continous scan updated for Nessus 7
  • +
  • Refactor on server.config to remove globals
  • +
  • Added a directory for custom templates for executive reports (pro and corp)
  • +
  • Activity feed shows more results and allows to filter empty results
  • +
  • Allow ot create workspace that start with numbers
  • +
  • Added more variables to executive reports (pro and corp)
  • +
  • Fixed some value checking on tasks api (date field)
  • +
  • OpenVas plugin updated
  • +
  • Appscan plugin update
  • +
  • Added no confirmed vulns to report api
  • +
  • Fixed a bug on workspace API when the workspace already exists on database
  • +
  • Fix owner filter on status report
  • +
  • Fixes on import_csv fplugin when the api returned 409
  • +
  • Fixes on status_check
  • +
  • Fixed a bug on webui when workspace permission was changed (pro and corp)
  • +
  • Update nexpose plugin
  • +
  • uigrid library updated to latest version
  • +
  • Bug fix on plugin automatic detection
  • +
  • Fixed a bug on executive reports when multiple reports were scheduled
  • +
  • Avoid closing the executive report and new vuln modal when the form has data
  • +
  • Status report open new tab for evidence
  • +
  • added change_password to manage.py
  • +
  • Update wapiti plugin
  • +
  • Fixed vuln count on executive report (pro and corp)
  • +
  • Fixed css align in some tables
  • +
  • Fixed No ports available error on the client
  • +
+

August 17, 2018:

+
    +
  • Updated code to use Flask 1.0
  • +
  • Add threadfix integration (corp only)
  • +
  • Fix create_service fplugin
  • +
  • Executive report bug fix on tags
  • +
  • Persistence server bug fix on impact and ease of resolution
  • +
  • Fix unicode error bug on executive reports
  • +
  • Updated code to support latest Twisted version
  • +
  • Updated all requirements to use >=
  • +
  • Fix dry run on create_host fplugin
  • +
  • Fixed del_all_vulns_with and del_all_hosts
  • +
  • Improved executive reports status update refresh
  • +
  • Websocket port is configurable now
  • +
  • Change minimum font size in tag cloud
  • +
  • Fixed a problem with shodan icon on dashboard
  • +
  • Updated license check on deleted users
  • +
  • Users with role client was not able to change password, bug fixed
  • +
  • Updated code to support pip 10
  • +
  • Added ldap to status check
  • +
  • Credentials icon aligned
  • +
  • Deamon now allows to execute faraday sever in more than one port and more than one process for multiplexation
  • +
  • All views now check for permissions on workspace
  • +
  • Pull requests #229, #231, #239 and #240 are merged
  • +
  • Avoid polling deleted executive reports
  • +
  • Added documentation to project
  • +
  • Fix self xss on webshell
  • +
  • Add postgres locks check on status_check
  • +
  • Vuln counter fix when confirmed is on
  • +
+

July 26, 2018:

+
    +
  • Interface removed from model and from persistence server lib (fplugin)
  • +
  • Performance iprovements on the backend
  • +
  • Add quick change workspace name (from all views)
  • +
  • Changed the scope field of a workspace from a free text input to a list of targets
  • +
  • New faraday styles in all webui views
  • +
  • Add search by id for vulnerabilities
  • +
  • Add new plugin sslyze
  • +
  • Add new plugin wfuzz
  • +
  • Add xsssniper plugin
  • +
  • Fix W3af, Zap plugins
  • +
  • Add brutexss plugin
  • +
  • Allow to upload report file from external tools from the web
  • +
  • Fix sshcheck import file from GTK
  • +
  • Add reconng plugin
  • +
  • Add sublist3r plugin
  • +
  • Add HP Webinspect plugin
  • +
  • Add dirsearch plugin
  • +
  • Add ip360 plugin
  • +
  • CouchDB was replaced by PostgreSQL :)
  • +
  • Host object changed, now the name property is called ip
  • +
  • Interface object was removed
  • +
  • Note object was removed and replaced with Comment
  • +
  • Communication object was removed and replaced with Comment
  • +
  • Show credentials count in summarized report on the dashboard
  • +
  • Remove vuln template CWE fields, join it with references
  • +
  • Allow to search hosts by hostname, os and service name
  • +
  • Allow the user to specify the desired fields of the host list table
  • +
  • Add optional hostnames, services, MAC and description fields to the host list
  • +
  • Workspace names can be changed from the Web UI
  • +
  • Exploitation and severity fields only allow certain values. CWE CVEs were fixed to be valid. A script to convert custom CSVs was added.
  • +
  • Web UI path changed from /_ui/ to / (_ui has now a redirection to / for keeping backwards compatibility)
  • +
  • dirb plugin creates an informational vulnerability instead of a note.
  • +
  • Add confirmed column to exported csv from webui
  • +
  • Fixes in Arachni plugin
  • +
  • Add new parameters --keep-old and --keep-new for faraday CLI
  • +
  • Add new screenshot fplugin which takes a screenshot of the ip:ports of a given protocol
  • +
  • Add fix for net sparker regular and cloud fix on severity
  • +
  • Removed Chat feature (data is kept inside notes)
  • +
  • Add CVSS score to reference field in Nessus plugin.
  • +
  • Fix unicode characters bug in Netsparker plugin.
  • +
  • Fix qualys plugin.
  • +
  • Fix bugs with MACOS and GTK.
  • +
+

April 10, 2018:

+
    +
  • Fix bug with tornado version 5.0 and GTK client.
  • +
+

November 17, 2017:

+
    +
  • Fix bug with tags in models.
  • +
+

November 5, 2017:

+
    +
  • Added "Last modified" and "Created" in Hosts view
  • +
  • Fixed bug when trying to run Faraday as second process and closing the terminal (&!)
  • +
  • Fixed bug where it asked for dependencies eternally when you have a different version than the one required
  • +
  • Fixed small bug in the update_from_document method
  • +
  • Fixed bug, makes the python library dependencies specific to the desired version
  • +
  • Fixed GitHub language bar to reflect real code percentage
  • +
  • Merge PR #195: Create gentoo_requirements_extras.txt (New Github wiki page)
  • +
  • Merge PR #225: Add references to found vulnerabilities in nmap plugin
  • +
  • New plugin: Netsparker cloud
  • +
  • New plugin: Lynis (Winner of Faraday Challenge 2017)
  • +
  • New Fplugin: changes the status of all vulnerabilities of an specific workspace to closed
  • +
  • New Fplugin: combines the "create_interface" and "create_host" scripts into one (create_interface_and_host script)
  • +
  • New Fplugin: import_csv , now you can import Faraday objects from a CSV
  • +
+

August 11, 2017:

+
    +
  • Add check to the vuln creation modal for empty targets in the Web UI
  • +
+

August 9, 2017:

+

No changes

+

August 7, 2017:

+
    +
  • Updated Core Impact plugin to be compatible with 2016 version
  • +
  • Improved loading of fields request and website in Burp Plugin
  • +
  • Improved Nexpose Full plugin
  • +
  • Improved Acunetix plugin to avoid conflicts and missing imported data, and to correctly parse URLs and resolutions
  • +
+

July 19, 2017:

+
    +
  • Added the ability to select more than one target when creating a vuln in the Web UI
  • +
  • Merged PR #182 - problems with zonatransfer.me
  • +
  • Fixed bug in Download CSV of Status report with old versions of Firefox.
  • +
  • Fixed formula injection vulnerability in export to CSV feature
  • +
  • Fixed DOM-based XSS in the Top Services widget of the dashboard
  • +
  • Fix in AppScan plugin.
  • +
  • Fix HTML injection in Vulnerability template.
  • +
  • Add new plugin: Junit XML
  • +
  • Improved pagination in new vuln modal of status report
  • +
  • Added "Policy Violations" field for Vulnerabilities
  • +
+

May 24, 2017:

+
    +
  • Fixed bug when editing workspaces created in GTK
  • +
  • Improved host search in the WEB UI
  • +
  • Extended the config to support different searching engines in the WEB UI
  • +
  • Check that client and server versions match when connecting
  • +
  • Adds the 'v' and 'version' argument for both the server and the client
  • +
  • Fixed "refresh" button in the Web UI
  • +
  • Fix API on /ws/ with duration object None
  • +
  • Added a CRUD for Credentials to the Web UI
  • +
  • Bug fixes on the Burp Online Plugin
  • +
  • Added a script to connect with Reposify
  • +
  • Fixed Hostname import in Nessus Plugin
  • +
  • Make plugin methods log() and devlog() work again
  • +
  • Fixed bug in SQLMap plugin that made the client freeze
  • +
  • Improved SQLMap plugin to support more options and to show errors in GTK log console
  • +
  • Fixed bug when creating/updating Credentials
  • +
  • Improve plugins usage of vulnweb URL fields
  • +
  • Fixed order of Report Plugins in the GTK import list
  • +
+

March 17, 2017:

+
    +
  • Added link to name column in Hosts list
  • +
  • Created a requirements_extras.txt file to handle optional packages for specific features
  • +
  • Fixed bug in SQLMap plugin that made the client freeze
  • +
  • Fixed bug when creating/updating Credentials
  • +
  • Fixed bug in the WEB UI - menu explanation bubbles were hidden behind inputs
  • +
  • Fixed conflict resolution when the object was deleted from another client before resolving the conflict
  • +
  • Improved fplugin
  • +
  • Improved the installation process
  • +
  • Improved SQLMap plugin to support --tables and --columns options
  • +
  • Improved navigation in Web UI
  • +
  • Merged PR #137 - CScan improvements: bug fixing, change plugin format and removed unnecessary file output
  • +
  • Merged PR #173 - Hostnames: added hostnames to plugins
  • +
  • Merged PR #105 - OSint: added the possibility of using a DB other than Shodan
  • +
  • The Status Report now remembers the sorting column and order
  • +
+

February 8, 2017:

+
    +
  • Fixed max amount of vulns pagination bug in Web UI
  • +
  • Fixed Maltego plugin
  • +
+

January 30, 2017:

+
    +
  • Added an activity feed panel in the Dashboard.
  • +
  • Added AppScan plugin.
  • +
  • Improved Burp's Online plugin. Added fields and removed HTML tags.
  • +
  • Refactor remaining modules to be compatible with JS Strict Mode.
  • +
  • Fixed bug that prevented GTK from closing when user clicked CANCEL on WS creation.
  • +
  • Fixed size of Workspace creation dialog.
  • +
  • New cwe databases: English and Spanish.
  • +
  • Added Hping plugin.
  • +
  • Enhancements to Wpscan plugin.
  • +
+

November 10, 2016:

+
    +
  • New library to connect with Faraday Server.
  • +
  • Fixed Fplugin, now it uses the new library to communicate with the Server.
  • +
  • New field for Vulnerabilities: plugin creator and status.
  • +
  • Refactor in Faraday Core and GTK Client.
  • +
  • Bug fixing in Faraday Client and Server.
  • +
  • Added Faraday news notifications in GTK and Web UI.
  • +
  • New plugins: Dirb, Netdiscover, FruityWifi, Sentinel.
  • +
  • Improvements on the WPscan plugin.
  • +
  • Fixed Licenses search.
  • +
  • Refactor Licenses module to be compatible with JS Strict Mode.
  • +
+

September 19, 2016:

+
    +
  • Major refactor of Faraday Client: now we support massive workspaces (100.000+ hosts).
  • +
  • Fixed more than 10 minor bugs on the Web UI.
  • +
  • Fixed searching with spaces character on Web UI
  • +
  • Updated URL shown when starting Faraday.
  • +
  • Dashboard is now refreshed automatically every 60 seconds.
  • +
  • Fixed Propecia plugin.
  • +
  • New plugin: WPscan
  • +
  • Host Sidebar on GTK now adds information more intelligently and will never block the application.
  • +
  • Evidence screenshots in report generation is now bigger.
  • +
  • Help menu in GTK with links to interesting links.
  • +
  • Added Help section to WEB UI.
  • +
+

August 12, 2016:

+
    +
  • Added Faraday Server
  • +
  • Improved performance in web UI
  • +
  • Added some basic APIs to Faraday Server
  • +
  • Added licenses management section in web UI
  • +
  • Totally removed QT3, GTK is now the only GUI
  • +
  • Deprecated FileSystem databses: now Faraday works exclusively with Faraday Server and CouchDB
  • +
  • Added a button to go to the Faraday Web directly from GTK
  • +
  • Fixed bug when deleting objects from Faraday Web
  • +
  • Fixed bug where icons where not copied to correct folder on initialization
  • +
  • Fixed bug where current workspace wouldn't correspond to selected workspace on the sidebar on GTK
  • +
  • Fixed bug in 'Refresh Workspace' button on GTK
  • +
  • Fixed bug where Host Sidebar and Statusbar information wasn't correctly updated on GTK
  • +
  • Fixed bug in service editing
  • +
  • Fixed sqlmap plugin
  • +
  • Fixed metapsloit plugin
  • +
+

Jul 1, 2016:

+
    +
  • GTK is the default interface now.
  • +
  • Added new plugin : Ndiff.
  • +
  • Added new plugin : Netcat (Gnu netcat - OpenBSD netcat - Original netcat)
  • +
  • Added button to edit your host in the GTK interface.
  • +
  • Hosts sidebar now can be sorted by amout of vulnerabilities and OS.
  • +
  • Changes in installation: install.sh now installs only GTK, QT is considered deprecated.
  • +
  • Changes in installation: Faraday now runs with the last versions of Python modules.
  • +
  • Changes in installation: fixed names of packages in setup_server.sh
  • +
  • Usability: Enter key in GTK dialogs works as OK button
  • +
  • Improved handling of lost connection to CouchDB database
  • +
  • First steps towards deprecating Filesystem databases
  • +
  • Fixed a bug when workspace was changed
  • +
  • Fixed a bug with Import Reports Dialog in GTK GUI on OS X.
  • +
  • Fixed a bug with Ctrl+Shift+C and Ctrl+Shift+V in some desktops managers.
  • +
  • Fixed a bug with mapper of vulnerabilities.
  • +
+

Jun 13, 2016:

+
    +
  • Added Import Report dialog to Faraday GTK
  • +
  • Added a 'Loading workspace...' dialog to Faraday GTK
  • +
  • Added host sidebar to Faraday GTK
  • +
  • Added host information dialog to Faraday GTK with the full data about a host, its interfaces, services and vulnerabilities
  • +
  • Added support for run faraday from other directories.
  • +
  • Fixed log reapparing after being disabled if user created a new tab
  • +
  • Fixed bug regarding exception handling in Faraday GTK
  • +
  • Now Faraday GTK supports Ctrl+Shift+C / Ctrl+Shift+V to Copy/Paste
  • +
  • Faraday will now not crash if you suddenly lose connection to your CouchDB
  • +
+

May 23, 2016:

+
    +
  • Removed description from Hosts list in WEB UI
  • +
  • Fixed sort in Hosts list in WEB UI
  • +
  • Fixed ports sorting in Host view in WEB UI
  • +
  • Added search link for OS in Hosts list in WEB UI
  • +
  • Removed description from Services list in WEB UI
  • +
  • Added version to Services list in WEB UI
  • +
  • Modified false values in Hosts list in WEB UI
  • +
  • Added search links in Services list in WEB UI
  • +
  • Added scrollbar in Gtk Terminal.
  • +
  • Added workspace status in Gtk interface
  • +
  • Added conflict resolution support for the Gtk interface
  • +
  • Added search entry for workspaces in Gtk
  • +
  • Added support for 'exit' command inside Faraday's Gtk terminal
  • +
  • Improved handling of uncaught exceptions in Gtk interface
  • +
  • Improved text formatting in Gtk's log console
  • +
  • Fixed several small bugs in Faraday GTK
  • +
  • Added support for resize workspace bar.
  • +
  • Added a quote for imported reports in WEB UI.
  • +
  • Added support for a new type of report in Qualysguard plugin.
  • +
  • Fixed bugs in plugins: Acunetix - Nmap - Nikto.
  • +
+

Apr 29, 2016:

+
    +
  • Added Open services count to Hosts list in WEB UI
  • +
  • Improved zsh integration
  • +
  • Added GTK3 interface prototype
  • +
  • Added plugin detection through report name
  • +
  • Fixed an error in wcscan script
  • +
  • Fixed nikto plugin
  • +
  • Fixed openvas plugin
  • +
+

Apr 04, 2016

+
    +
  • Added cli mode (see wiki for usage instructions)
  • +
  • Support for multiple Faraday instances in the same host
  • +
  • Fixed bug for editing web vulns in bulk
  • +
  • Fixed bug for select all in web UI
  • +
  • Fixed bugs in Qualys, ZAP, nikto, w3af, openVas plugins
  • +
  • Added some new scripts and helpers
  • +
+

Feb 26, 2016:

+
    +
  • Fixed bug in pip debian
  • +
  • BugFix pip install.
  • +
  • Checks additionals about dependencies in installation.
  • +
  • Warning about a upgrade to experimental in debian installation.
  • +
  • Fixed small bug in CSV importing
  • +
  • Fixed styles for Status Report
  • +
  • Fixed bug on Status Report filter after editing
  • +
  • Added support for Kali Rolling Edition
  • +
  • Notify user when the current Workspace doesn't exist
  • +
  • Show all evidence files in Status Report
  • +
  • Added script to remove all vulns with a specific severity value (parameterized)
  • +
  • Fixed Arachni Plugin bugs
  • +
  • Added new version for Maltego Plugin
  • +
  • Added support for Mint 17
  • +
+

Dec 18, 2015:

+
    +
  • Immunity Canvas plugin added
  • +
  • Added Dig plugin
  • +
  • Added Traceroute plugin
  • +
  • Fixed bug in first run of Faraday with log path and API errors
  • +
  • Added parametrization for port configuration on APIs
  • +
  • Refactor Plugin Base to update active WS name in var
  • +
  • Refactor Plugins to use current WS in temp filename under $HOME/.faraday/data. Affected Plugins:
      +
    • amap
    • +
    • dnsmap
    • +
    • nmap
    • +
    • sslcheck
    • +
    • wcscan
    • +
    • webfuzzer
    • +
    • nikto
    • +
    +
  • +
  • Fixed bug get_installed_distributions from handler exceptions
  • +
  • Added Wiki information about running Faraday without configuring CouchDB
  • +
  • Fixed Unicode bug in Nexpose-full Plugin
  • +
  • Filter false-positives in Status Report
  • +
  • Fixed bug that prevented the use of "reports" and "cwe" strings in Workspace names
  • +
  • Added port to Service type target in new vuln modal
  • +
  • Added new scripts for faraday plugin:
      +
    • /bin/delAllVulnsWith.py - delete all vulns that match a regex
    • +
    • /bin/getAllbySrv.py - get all IP addresses that have defined open port
    • +
    • /bin/getAllIpsNotServices.py added - get all IPs from targets without services
    • +
    +
  • +
  • Fixed bug null last workspace
  • +
  • Fixed bugs in CSV export/import in QT
  • +
+

Oct 2, 2015:

+
    +
  • Continuous Scanning Tool cscan added to ./scripts/cscan
  • +
  • Fix for saving objects without parent
  • +
  • Hosts and Services views now have pagination and search
  • +
  • Updates version number on Faraday Start
  • +
  • Visual fixes on Firefox
  • +
  • Migrate graphs from D3.js to Chart.js
  • +
  • Added Services columns to Status Report
  • +
  • Added sections of Commercial versions
  • +
  • Converted references to links in Status Report. Support for CVE, CWE, Exploit Database and Open Source Vulnerability Database
  • +
  • Added Peepingtom, SSHdefaultscan and pasteAnalyzer plugins
  • +
  • Fixed Debian install
  • +
+

Sep 10, 2015:

+
    +
  • Adding filename path information of report imported in history command
  • +
  • Remove old couchdb upgrade process
  • +
  • Adding Iceweasel browser > 38.2.0 support
  • +
  • Adding more navigability in differents GUI Web (Dashboard/Services/Views)
  • +
  • Fixed bug copy clipboard offline (update path of ngClip dependeces)
  • +
  • Added class to set colors to severities in new/edit vuln view
  • +
  • Medusa, Hydra & Metasploit plug-in now added discovered weak credentials as a vulnerability
  • +
  • Nmap plug-in applyies a severity depending on the result of a NSE script
  • +
  • Fixed small bug for empty ease of resolution
  • +
  • Adding more time to generation shells QT
  • +
  • Added "Search in Shodan" links in different views (Status Report, Host View, Service View)
  • +
  • Removed required of name field service bulk edition
  • +
  • Added ng-disabled on Edit button if select more of 1 host on Host View WEB UI
  • +
  • Refactored GUI Web: + Icon added for Modal Error + OS, Creator, Date for modal-services-by-host.html + Fixed typo in Host Edit, the popup message was wrong + First version for in estilos.css for clear mode + Also, added hover to grey boxes in the Dashboard.
  • +
  • Added vulns count for Hosts in WEB UI
  • +
  • Updated w3af plugin to support report version 1.7.6
  • +
  • Ignored cwe database from updater and QT views
  • +
  • Plugin for Nexpose XML Export 2.0
  • +
  • Added masscan plugin (1.0.3)
  • +
+

Aug 19, 2015:

+
    +
  • Exported CSV contains filters and columns from Status Report in WEB UI
  • +
  • Vulnerability counter on Status Report in WEB UI
  • +
  • Added quick vuln edit and delete in WEB UI
  • +
  • Expanded Unit Tests for WEB UI
  • +
  • XML Cleaner
  • +
  • Kali 2.0 support
  • +
  • Improve plugins running status log (Adding log information on report importing)
  • +
  • Clean dev log on plugins
  • +
  • w3af plugin refactoring
  • +
  • Fix Debian ⅞.1 install support
  • +
+

Aug 05, 2015:

+
    +
  • Added CWE database and integration with vulns creation
  • +
  • Added ENTER shortcut on modals
  • +
  • Progress bar for workspace in the dashboard
  • +
  • Bug fixing in workspaces and status report components
  • +
  • Unit testing for vulns, status report and workspaces components
  • +
  • Debian 8.1 support
  • +
+

Jun 30, 2015:

+
    +
  • Added hosts CRUD
  • +
  • Added services CRUD
  • +
  • Fix ubuntu 15.04 installation bug
  • +
  • Small bug in burp plugin "Import new vulnerabilities" checkbox issue
  • +
  • Added an interactive visualization to calculate the value of a Workspace
  • +
  • Fixed several bugs in WEB UI
  • +
  • Added a URL filter functionality to the status report, allowing searches by fields
  • +
+

Apr 17, 2015:

+ +

Changes:

+
    +
  • Styles changes in WEB UI: fancy component selection, improved workspaces selection.
  • +
+

Bugfixes: +* Date on Workspace creation +* Tables in Firefox

+

Apr 7, 2015:

+

You can get the new version here: +* https://github.com/infobyte/faraday/archive/v1.0.9.tar.gz

+

Changes:

+
    +
  • Performance improvement in the dashboard
  • +
  • Fix bug OSX install
  • +
  • Bug fixes
  • +
+

Mar 9, 2015:

+

You can get the new version here:

+ +

Changes:

+
    +
  • WcScan script and plugin (scripts/wcscan.py)
  • +
  • New Dashboard D3 with AngularJS
  • +
  • Easy access to Vulnerability pages in the Status Report
  • +
  • Easy access to the Host pages on the dashboard
  • +
  • Creation and Editing capabilities for the Workspace from the UI Web
  • +
  • Support installation for the latest version of Debian/Ubuntu/Kali
  • +
  • sqlmap version 1.0-dev support updated
  • +
  • API Status Check in both ZSH & QT GUI
  • +
  • Field added for resolution of vulnerabilities classification with plug-ins updated to support the new function.
  • +
  • Field added for rating "ease of resolution" for vulnerabilities
  • +
  • +

    Adjustments for Resolution field

    +
  • +
  • +

    New Faraday plugin for Burp. Version 1.2 + -Corrections for the vulnerabilities duplication for the burp plugin + -New tab section to configure the new Vulnerabilities downloads for Faraday

    +
  • +
  • +

    Automated backup for couch database

    +
  • +
  • Ability to upload evidence of a vulnerability (as an attachment)
  • +
  • Ability to assign Vulnerability Impact (confidentiality, integrity, availability).
  • +
+

Dec 12, 2014:

+

You can get the new version here:

+ +

Changes:

+
    +
  • Improved Vulnerability Edition usability, selecting a vuln will load it's content.
  • +
  • ZSH UI now is showing notifications.
  • +
  • ZSH UI now is showing active workspace.
  • +
  • Faraday now asks confirmation on exit, If you have pending conflicts to solve it will show the number of each.
  • +
  • Vulnerability creation is now suported in the status report.
  • +
  • Introducing SSLCheck, a tool for verify bugs in SSL/TLS Certificates on remote hosts. This is integrated with Faraday with a plugin.
  • +
  • Shodan Plugin is now working with the new API.
  • +
  • Some cosmetic changes in the status report.
  • +
+

Bugfixes:

+
    +
  • Sorting collumns in the Status Report now is working.
  • +
  • Workspace icon is based on the type of the workspace.
  • +
  • Opening the reports in QT UI now opens the active workspace.
  • +
  • UI Web dates fixes, we were showing dates with a off-by-one error.
  • +
  • Vulnerability edition was missing 'critical' severity.
  • +
  • Objects merge bugfixing
  • +
  • Metadata recursive save fix
  • +
+

Nov 7, 2014:

+

You can get the new version here:

+ +

Changes:

+
    +
  • Status report modifications:
  • +
  • Web vulnerability edition support.
  • +
  • Variable columns in status report.
  • +
  • New field called "Data" with extra information about a vulnerability.
  • +
  • Bug fixes
  • +
+

Oct 17, 2014:

+ +

Status report now have edition capabilities +Introducing batch vulnerability edition and deletion. Now you can edit your status report.

+

Lots of bug fixes

+

Ubuntu 14.04 support fixes +Mac support fixes

+

Sep 26, 2014:

+ +

New Dashboard design with summarized information.

+

D3.js Fancy visualizations.

+

Vulnerability Status report.

+

Command run user/host identification.

+

Vulnerability Statistics.

+

Optimization Refactor.

+

Jun 06, 2014:

+ +

Notifications: Updating objets on faraday now results in a beautiful +notification in the QT ui.

+

Performance: Enhacing performance when lots of workspaces are available. +We now load each workspace whe it's needed instead of loading ahead the +full workspace list.

+

UI: Workspace split, now you can select the workspace to visualize. We +are now using bootstrap.

+

API: New operations on the Rest API (this is just for the following UI +modifications). Vulnerability update and delete operations.

+

May 14, 2014:

+ +

Improving (web interface, vulnerability classification)

+

Apr 30, 2014:

+ +

MacOS Support

+

Apr 04, 2014:

+ +

We are proud to present two new features that will enhace the Faraday experience. +Taking feedback from our users we took account that each of them had particular needs from their consoles (completion, size, fonts, so on so forth) and their need to be able to know what commands where run during an engagement.

+
1
+2
* A brand new ZSH based Terminal UI
+* The Command Run execution history
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Remote-PostgreSQL/index.html b/Remote-PostgreSQL/index.html new file mode 100644 index 00000000000..83ed539770d --- /dev/null +++ b/Remote-PostgreSQL/index.html @@ -0,0 +1,1059 @@ + + + + + + + + + + + + + + +Remote PostgreSQL - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Remote PostgreSQL configuration

+

Faraday uses a connection string stored in /home/faraday/.faraday/config/server.ini to connect to the database. +You can use faraday-manage initdb to configure a localhost database (same server as Faraday Server runs). +If you opt to use a remote database you will need to create a database role, database and create the schema.

+

Step 0: Install PostgreSQL

+

sudo apt install postgresql-12
+
+or +
sudo yum install postgresql-12
+

+

Step 1: Configure PostgreSQL for remote connection

+
+

Warning

+

Make sure you understand this step. Using the wrong settings could leave your database server insecure

+
+

First, open the hba_config file, to locate the file execute:

+
sudo -u postgres psql -c "show hba_file"
+
+

Add a line for the faraday-server

+
host    all             all             192.168.1.2/24            md5
+
+

Then, open /etc/postgresql/9.X/main/postgresql.conf

+

Allow to listen on the interface or use * for all interfaces:

+
listen_addresses = '*'
+
+

Step 2: Create PostgreSQL role

+

Login into the database server and execute:

+
createuser faraday_postgresql -P
+
+

Now, create the database:

+
createdb faraday
+
+

Step 3: Configure Faraday Server

+

Now on the Faraday Server instance, open the file /home/faraday/.faraday/config/server.ini and append the database configuration:

+
[database]
+connection_string = postgresql+psycopg2://faraday_postgresql:SECRET_PASSWORD@REMOTE_IP/faraday
+
+

Step 4: Create tables

+

Now you are ready to create the tables:

+
faraday-manage create-tables
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Report-v4/index.html b/Report-v4/index.html new file mode 100644 index 00000000000..7a698b9403d --- /dev/null +++ b/Report-v4/index.html @@ -0,0 +1,1126 @@ + + + + + + + + + + + + + + +What is Report - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Executive Report

+
+

The Executive Report feature lets you create (as the name implies) reports using the results obtained in each workspace. When an Executive Report is created, all the data from the Status Report is automatically processed and placed in a Word compatible document or PDF that can then be downloaded from Faraday

+

Managing Executive Reports

+

To manage your reports you need to access Faraday's Web UI and go to the report icon on the left panel and hit on Create New Report.

+

All the reports will be listed, including their information, status and link to download.

+

Making a report

+

To create a new report, click on New. A form will open asking for the following fields:

+
    +
  • +

    Title - this is the name that will be used to create the cover of the report.

    +
  • +
  • +

    Client Name - Client name to be used inside the report.

    +
  • +
  • +

    Template - select the template to use as a base for your report. Depending on the selected dataset the options will change.

    +
  • +
+

To edit a report, select it and click on the Edit button. A modal will appear allowing you to modify all the report fields. Save it and a brand new report will be generated, keeping the original version intact.

+

If, instead, you want a new report that is exactly like an existing one but with the current data of your workspace, you can click on the Regenerate button in the reports list. Reports can only be regenerated one at a time, so the regeneration buttons are disabled while this action is being performed.

+

Executive and Technical details tabs

+

The following are a sort of placeholder fields for information that's commonly added to most reports. They are text fields and can be used for any relevant information, not just for what they're named after:

+
    +
  • Summary
  • +
  • Conclusions
  • +
  • Recommendations
  • +
  • Scope
  • +
  • Objectives
  • +
+

Excecutive

+

Faraday processes all the information and spits out a shiny new report that is automatically available for download.

+

Report

+

Filtering

+

If you need a custom report that includes only some findings in the workspace, you can also use the filters to bring those specific vulnerabilities.

+

These filters can be mixed to create different outcomes.

+

Excecutive_report_for_test

+

Deleting a Report

+

From the Executive Report window, select the document and click on Delete. delete

+

Templates

+

We use Jinja2 to create Report Templates. Check this Article to get more information!

+

Datasets

+

Faraday provides two different datasets to create Executive Reports - generic and grouped.

+
+

The generic dataset provides one entry for each individual vulnerability with all of its fields readily available as a dictionary. The field parent contains an ID corresponding to the Vulnerability's parent (either a Host or a Service).

+
+
+

The grouped dataset groups vulnerabilities by name and description. If two or more vulnerabilities share the same name and description, they will be presented as one. The field parent contains a Python Dictionary-style object with the parent IDs as keys and a Python Dictionary-style object containing evidence_subdoc, data and target as values. Tags and references will be merged for vulnerabilities that are grouped and not separated by parent.

+
+
+

Custom Reports

+

Faraday has the ability to use a custom report, to do so, in the create reports section, there is a selector for a template. For a uploading the report as admin user click on "custom" and "upload template".

+

Select the file from your local and hit on open. A report will be generated with sample data to check on the report. Then select the report from the custom report view.

+
+

Info

+

Keep in mind that each template should be designed for a specific dataset and that these are not interchangeable. The default templates that come with your instance are located at +/home/faraday/.faraday/executive_reports_templates/

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/SAML-Auth0/index.html b/SAML-Auth0/index.html new file mode 100644 index 00000000000..2a3f383c2be --- /dev/null +++ b/SAML-Auth0/index.html @@ -0,0 +1,960 @@ + + + + + + + + + + + + + + +Auth0 integration - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

SAML with Auth0

+
+

Here are the steps to integrate SAML to Faraday using Auth0:

+

Step 1: Navigate to Auth0 website.

+

Step 2: Sing in with your admin account.

+

Step 3: Navigate to ApplicationsApplications in the left Menu.

+

Step 4: Click Create Application button.

+

Step 5: On the Create application page: +* Enter the name of the custom app. +* (Optional) Choose an application type.

+

Then click Create.

+

Step 6: In your new app page, go to the Addons tab and turn on the SAML2 WEB APP plugin.

+

The addon configuration page will pop up.

+

+

Step 7: On the Usage tab, you should copy the Issuer (Identity ID in Faraday settings) and the Identity Provider Login URL (SSO URL in Faraday settings). Also download the Identity Provider Certificate (IdP Certificate in Faraday settings). Paste them on Faraday's SAML configuration.

+

+

Step 8: Click on Settings tab. Here you should enter an Application Callback URL with following format: +* Application Callback URL: https:///_api/saml/acs

+

Then click Save

+

+

Step 9: Back in your new app page, go to the Settings tab and scroll down to the Application URIs section. There you should enter the Application Login URI, the Allowed Logout URLs, the Allowed Web Origins and the Allowed Origins (CORS) with the following format: +* Application Login URI: https:///_api/saml/login +* Allowed Logout URLs: https:///_api/saml/logout +* Allowed Web Origins: https:/// +* Allowed Origins (CORS): https:///

+

Then scroll all the way down and click Save Changes.

+

+

Step 10: Run this command at a Terminal:

+
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem
+
+

This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

+

For more information about configuring a custom SAML app in Auth0, please visit their documentation page about this topic.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/SAML-Azure/index.html b/SAML-Azure/index.html new file mode 100644 index 00000000000..5c51010ac4e --- /dev/null +++ b/SAML-Azure/index.html @@ -0,0 +1,960 @@ + + + + + + + + + + + + + + +Azure integration - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

SAML with Auth0

+
+

Here are the steps to integrate SAML to Faraday using Azure:

+

Step 1: Navigate to Microsoft Azure.

+

Step 2: Sing in with your admin account.

+

Step 3: Navigate to Entrepise Applications.

+

Step 4: Click New Application button.

+

Step 5: Click Create your own application button.

+

Step 6: On the What's the name of your app? field enter faraday.

+

Step 7: On the What are you looking to do with your application? selection enter Integrate any other application you don't find in the gallery (Non-gallery).

+

Then click Create.

+

Step 8: In your new app page, go to the Single sign-on.

+

Step 9: Click SAML button.

+

Step 9: Click Edit button in Basic SAML Configuration.

+

Step 10: In Identifier (Entity ID) field enter https:///_api/saml/metadata.xml and in Reply URL (Assertion Consumer Service URL) enter https:///_api/saml/acs.

+

Step 11: Click Save button.

+

Step 12: In the SAML Certificates download the Certificate (Base64).

+

Step 13: Now in faraday->settings->saml and follow the fields in the next way:

+
1
+2
+3
+4
+5
* Display Name = 'Farady'
+* Identity ID = The Microsoft Entra Identifier, ej https://sts.windows.net/xxxxx/
+* Attribute Identifier = The field of wicht you want to use as username in faraday
+* SSO URL = The login URL ej https://login.microsoftonline.com/xxxx/saml2
+* IDP Certificate = The content of the SAML Cetificate downloaded in step 12
+
+

Step 14: Run this command at a Terminal:

+
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem
+
+

This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/SAML-Google/index.html b/SAML-Google/index.html new file mode 100644 index 00000000000..5f8e66d4f5f --- /dev/null +++ b/SAML-Google/index.html @@ -0,0 +1,962 @@ + + + + + + + + + + + + + + +Google integration - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

SAML with Google

+
+

Here are the steps to integrate SAML to Faraday using Google:

+

Step 1: Navigate to Google admin website.

+

Step 2: Sign in using an account with super administrator privileges.

+

Step 3: In the Admin console go to MenuAppsWeb and mobile apps.

+

Step 4: Click Add appAdd custom SAML app.

+

+

Step 5: On the App Details page: +* Enter the name of the custom app. +* (Optional) Upload an app icon.

+

Then click Continue.

+

+

Step 6: From the Google Identity Provider details page copy the SSO URL, the Entity ID (Identity ID on Faraday's SAML configuration) and the IDP Certificate. Paste them on Faraday's SAML configuration.

+

Click on Continue.

+

+

Step 7: Run this command at a Terminal:

+
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem
+
+

This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

+

Step 8: In the Service Provider Details, enter an ASC URL, Entity ID and Start URL with following format: +* ASC URL: https:///_api/saml/acs +* Entity ID: https:///_api/saml/metadata.xml +* Start URL: https:///_api/saml/login

+

Finally, check the Signed response checkbox. Then configure your Name ID and click Continue.

+

+

Step 9: In Attributes mapping page you should select Primary email and define the App attribute as username.

+

Then click Finish.

+

+

Step 10: In the Admin console go to MenuAppsWeb and mobile apps. Select your SAML app and click User access.

+

+

Step 11: To turn on the service for everyone in your organization, click On for everyone, and then click Save.

+

+

For more information about configuring a custom SAML app in Google, please visit their support page about this topic.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/SAML-Okta/index.html b/SAML-Okta/index.html new file mode 100644 index 00000000000..826265f64ee --- /dev/null +++ b/SAML-Okta/index.html @@ -0,0 +1,955 @@ + + + + + + + + + + + + + + +Okta integration - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

SAML with OKTA

+
+

Here are the steps to integrate SAML to Faraday using OKTA:

+

Step 1: Navigate to OKTA's website.

+

Step 2: Log in into your developer account as a user with administrative privileges.

+

Step 3: In the Admin console go to ApplicationsApplications.

+

Step 4: Click Create App Integration.

+

Step 5: Select SAML 2.0 in the Sign-in method section. Click Next.

+

Step 6: On the General Settings page: +* Enter the name of your integration (e.g. Faraday). +* (Optional) Upload a logo.

+

Then click Next.

+

Step 7: On the Configure SAML tab, enter the Assertion Consumer Service (ACS) URL into the Single Sign On URL field and the Entity ID into the Audience Restriction field with the following format: +* Single Sign On URL: https:///_api/saml/acs +* Audience Restriction: https:///_api/saml/metadata.xml

+

After that, in the Attribute Statements section, define the Name of the attribute as username and the Value as user.email.

+

Then click Next.

+

+

Step 8: In the final creation step, you should select the options that suits your company and click Finish.

+

Step 9: On the General tab, in the Application area, you can access to the Identity Provider Configuration. There you should copy the Identity Provider Single Sign-On URL (SSO URL in Faraday settings), the Identity Provider Issuer (Identity ID in Faraday settings) and the X.509 Certificate (IdP Certificate in Faraday settings). Paste them on Faraday's SAML configuration.

+

Click on Save.

+

+

Step 10: Run this command at a Terminal:

+
openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem
+
+

This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

+

For more information about configuring a custom SAML app in Okta, please visit their documentation page about this topic.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/SAML/index.html b/SAML/index.html new file mode 100644 index 00000000000..1083b25fa49 --- /dev/null +++ b/SAML/index.html @@ -0,0 +1,1033 @@ + + + + + + + + + + + + + + +Faraday configuration - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

SAML

+
+

You can configure SAML single sing-on and keep using local users. But you can't use both LDAP and SAML users at the same time.

+

Configuration by command line

+

In order to configure SAML, run the following command:

+
faraday-manage settings -a update saml
+
+

Then update every field according to the configuration on-prem.

+
$ faraday-manage settings -a update saml
+Update settings for: saml
+enabled [False]:
+display_name [Identity Provider]:
+user_role [admin]:
+admin_group []:
+attribute_identifier []:
+sso_url [http://localhost/saml/login]:
+sp_certificate []:
+sp_private_key []:
+idp_certificate []:
+Do you confirm your changes on saml?
+[Y/n]:
+
+

Remember to restart the server after doing changes!

+
systemctl restart faraday-server
+
+

Configuration by UI Preferences

+

You can access to SAML configuration on the Authentication section in the menu of your Preferences.

+

+

Services available to integrate SAML to Faraday

+

Here is a list of services with a link to its articles:

+ +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Scheduling/index.html b/Scheduling/index.html new file mode 100644 index 00000000000..acd7bed7e46 --- /dev/null +++ b/Scheduling/index.html @@ -0,0 +1,1022 @@ + + + + + + + + + + + + + + +Scheduler - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Scheduler

+

Scheduling

+

In order to arrange or plan an event to take place at a particular time we've created Scheduler, it will allow to use the POSIX local format, the execution will be made by an agent.

+

To configure a schedule click on Automation button on the left navigation and then click on scheduler, to do a new schedule click on Create Schedule.

+

+

Provide a description, interval pattern, select a Tool to run, destination Workspace and click on the Accept button.

+

+

The POSIX cron format is the below:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FieldPossible ValuesSyntaxDescription
a - Minute0-597 * * * *The cron job is initiated every time the system clock shows 7 in the minute’s position.
b - Hour0-230 7 * * *The cron job runs any time the system clock shows 7am (7pm would be coded as 19).
c - Day0-310 0 7 * *The day of the month is 7 which means that the job runs every 7th day of the month.
d - Month0 = none and 12 = December0 0 0 7 *The numerical month is 7 which determines that the job runs only in July.
+

In addition to running the agents manually with their "Run" button, you can also schedule them to run periodically. This can be done from the web if you have our Corporate/Pro version:

+

+

or with simple cronjobs using faraday-cli if you are using the Community version

+

create an script.sh with this contents:

+
#!/bin/bash
+echo '{"target": "www.google.com"}' | faraday-cli agent run -a 1 -e nmap --stdin
+
+

Edit your crontab using the bellow command

+
crontab -e 
+1 0 * * 0 /pathtoyourscript/script.sh > /dev/null 2>&1
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Settings-v4/index.html b/Settings-v4/index.html new file mode 100644 index 00000000000..0f63350b099 --- /dev/null +++ b/Settings-v4/index.html @@ -0,0 +1,1065 @@ + + + + + + + + + + + + + + +Settings - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Settings

+

In order to make Faraday's usage smoother, we have created the Settings section. Here, you can create new Custom Fields, change the account settings, customize the output of the reports and edit Ticketing tools configuration.

+

To go into Settings, click on User's menu and then click on Settings:

+

+

As you can see, for now we have two sections: Custom Fields and Preferences.

+

Custom Fields

+

You can create/edit/delete a Custom Field from Settings. Let's create one as an example:

+

+

You must fill the following fields in order to create a Custom Field:

+
    +
  • +

    Name: the name of the field (must be unique).

    +
  • +
  • +

    Type: data type of the field, it can be: Integer, List, String, Markdown, Choice.

    +
  • +
+
+

Inside the Custom Fields menu you can view the list of all custom fields

+
+

Preferences

+

+

Within the Preferences menu you will be able to modify the configuration of different tabs, such asAccount, Report and Ticketing Tools

+

Account

+

Inside account menu you would be able to modify your password, enable Two Factor Authentification and log in into the last used Workspace

+

+

Report

+

On the Report menu you can customize the output of your reports

+

+

Ticketing Tools

+

Inside this menu you would be able to choose your preferred Ticketing Tool, this will provide you an extended follow up capabilities

+

+

Each Ticketing Tools has different configurations.

+ +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Tasks/index.html b/Tasks/index.html new file mode 100644 index 00000000000..58eb60451f6 --- /dev/null +++ b/Tasks/index.html @@ -0,0 +1,1010 @@ + + + + + + + + + + + + +Tasks - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Tasks

+

You can create your own custom Methodologies, add Tasks, tag them and keep track of your whole project directly from Faraday.

+

Faraday comes with Methodologies loaded by default that allow you to get to work quickly without having to create your own.

+

A few of our default Methodologies:

+

PCI DSS 11.2 +Hardware Top 10 +Mobile Security +Network Pentest +Owasp Top 10 +Loading a default Methodology +All default Methodology files are available at the bottom of this page. Download them, then use the "New" button and select the option "From template", give this new methodology a name and that's it!

+

You can download the methodologies at the bottom of this article.

+

+

Creating you own Methodology

+

Create a .csv file with the following fields:

+

name +description +Then, use the "Import" button and select your new .csv to load your custom Methodology to Faraday.

+

+

Downloading your preferred Methodology

+

Do you have a custom Methodology created from scratch? Click in "Download CSV for current Methodology" and you will download a .csv file with the information for it!

+

Kanban View

+

+

If you click on the Methodology name, you'll access the Kanban view for it.

+

You can use drag and drop to change the status of the different Tasks, or you can create a new one. You can also edit or delete a task.

+

Task

+

Methodologies contain Tasks, which include the following fields:

+
    +
  • Name
  • +
  • Description
  • +
  • Due date
  • +
  • Status
  • +
  • Users assigned
  • +
  • Tags
  • +
+

With that, you can assign a specific Task with a due date to a pentester. Also, tag a chunk of Tasks for a better appreciation in the Kanban view.

+

+ +

Methodology Hardware Top 10

+

Methodology Mobile Security

+

Methodology Network Pentest

+

Methodology OWASP Top 10

+

Methodology PCI DSS 6.5

+

Methodology PCI DSS 11.2

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Troubleshooting/index.html b/Troubleshooting/index.html new file mode 100644 index 00000000000..71bba40eba7 --- /dev/null +++ b/Troubleshooting/index.html @@ -0,0 +1,1374 @@ + + + + + + + + + + + + + +Troubleshooting - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Troubleshooting

+

Intro

+

This guide is intended to provide solutions for common problems. If your problem is not listed below, make sure to contact us!

+

Before moving on, verify that you are using the latest available version running the Client and the Server using --version or -v.

+

To get the latest available version visit GitHub

+

We recommend upgrading to the latest version before proceeding.

+

Also, to get a better understanding of most problems you can run the Faraday Client using --debug or -d option.

+

Traceback Troubleshooting

+

For traceback troubleshooting you need to open the Faraday logs and search for the string ERROR. +Logs are located on /home/faraday/.faraday/logs.

+

In this section we will show common errors and possible solutions. We recommend to search part of the error in this page and try to match the error with possible solutions.

+

Index

+ +

Answers

+

I can't access the Web GUI

+

Is Faraday Server running? Try running: +

$ faraday-manage status-check
+
+That will give some information about the state Faraday is in at the moment. +If the Server is not running try: +
$ faraday-server
+

+

Faraday is not importing my report

+

First let's make sure there is a Plugin to parse it so make sure your tool is listed in our Plugin List. Not there? Code your own or ask us to do it Community, Pro and Corp users

+

You can also try to force Faraday to process a report with a certain plugin. For example, let's say you have a Metasploit report that Faraday is not detecting. You can change the report so that it ends with _faraday_Metasploit (first letter of the plugin in uppercase), so it ends up as myreport_faraday_Metasploit.xml, and then copy it to /home/faraday/.faraday/reports/{workspacename} in the Client. This of course works for any plugin, not only Metasploit.

+

Keep in mind that Plugins don't run on the Server, so if you're trying to copy the report file, make sure you're doint it on the Client.

+

A plugin added too much information to my database

+

You can go to your Activity Feed in the Web GUI, filter the vulnerabilities by whichever parameter you'd like, select them all and then click on Delete to remove them form the database.

+

+

How to reset Faraday Server password

+

If you forgot the password, or you don't know your Faraday Server password, you can use the command faraday-manage to change it:

+
$ faraday-manage change-password
+
+

Can't access Faraday Server remotely

+

In your Server machine, go to /home/faraday/.faraday/config/server.ini and check if you're listening only on the localhost. +You should see something like this:

+
[faraday_server]
+port=5985
+bind_address=localhost
+
+

If your Clients are on different machines than the Server, then you'll need to change the bind_address to your private IP (or all your interfaces). For example:

+
bind_address=0.0.0.0
+
+

Updating Nginx configuration

+

Note: This only applies if you are using Nginx and https.

+

Please, make sure you have this settings on your Nginx config:

+
1
+2
proxy_pass http://localhost:5985/;
+proxy_redirect http:// $scheme://;
+
+

Error while backing up the database

+

If you get this error:

+

“pci_q1” failed: FATAL: role “root” does not exist

+

while trying to execute:

+

pg_dump <name of workspace> > <name of what I want the backup file to be>

+

Run:

+

sudo -u postgres -i

+

And then try again.

+

No ports available

+

If you see this traceback:

+

Traceback (most recent call last): +File "/usr/share/python-faraday/model/application.py", line 145, in start +CONF.getApiRestfulConInfoPort() +File "/usr/share/python-faraday/apis/rest/api.py", line 67, in startAPIs +raise Exception("No ports available!") +Exception: No ports available!

+

Go into the file user.xml locates in /home/USERNAME/.faraday/config/

+

~localhost~ +127.0.0.1 +9876 +9977

+

Change localhost for 127.0.0.1 and try again.

+

UnicodeEncodeError: 'ascii' codec can't encode character

+

If you see a Traceback that ends something like this:

+

UnicodeEncodeError: 'ascii' codec can't encode character u'\xf3' in position 1: ordinal not in range(128)

+

Go into your Faraday folder and run the following command:

+
1
$ faraday-manage sql-shell
+
+

Once inside the shell execute:

+

SHOW SERVER_ENCODING

+

If you are using symbols not supported by ASCII, you need to change database's encoding to UTF-8. +1. Dump your database +2. Drop your database, +3. Create new database with the different encoding +4. Reload your data.

+

Make sure the client encoding is set correctly during this process.

+

Database encoding incompatibility executing initdb

+

If you got the following error when running the command faraday-manage initdb:

+
ERROR: createdb: database creation failed: ERROR:  new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)
+HINT:  Use the same encoding as in the template database, or use template0 as template.
+
+

You can follow the instructions provided in this link.

+

Once you get the solution above, you can try to initialize the database once more:

+
faraday-manage initdb
+
+

Is your question not listed here? Contact us

+

SMTP is not being saved from the UI

+

For this is needed to update manually the configuration on the server side.

+
faraday-manage settings -a update smtp
+
+

properly set the configuration needed, actually faraday doesn't support accounts without password/user.

+

LDAP reconfigure after Faraday 3.15.0

+

As part of the constant grow there were introduced new security rules on LDAP and as a consequence when upgrading Faraday to 3.16 it LDAP needs to be reconfigured.

+

Steps to do it: +

faraday-manage settings -a update ldap
+

+

Then update every field according to the on-prem configuration . +

$ faraday-manage settings -a update ldap
+Update settings for: ldap
+enabled [False]:
+use_local_roles [True]:
+default_local_role [admin]:
+admin_group []:
+asset_owner_group []:
+client_group []:
+pentester_group []:
+disconnect_timeout [2.0]:
+server []:
+port [389]:
+use_ldaps [False]:
+use_start_tls [False]:
+domain []:
+domain_dn []:
+bind_format [CN]:
+bind_dn []:
+user_class [user]:
+user_attribute [sAMAccountName]:
+group_class [group]:
+paginated_fetch [False]:
+Do you confirm your changes on ldap?
+----------------------
+enabled: False
+use_local_roles: True
+default_local_role: admin
+admin_group:
+asset_owner_group:
+client_group:
+pentester_group:
+disconnect_timeout: 2.0
+server:
+port: 389
+use_ldaps: False
+use_start_tls: False
+domain:
+domain_dn:
+bind_format: CN
+bind_dn:
+user_class: user
+user_attribute: sAMAccountName
+group_class: group
+paginated_fetch: False
+[Y/n]:
+

+

my reports disappeaered after activating markdown

+

remember that markdown reports are stored at:

+

Generic: +

~/.faraday/executive_reports_templates/markdown_generic
+
+Grouped +
/.faraday/executive_reports_templates/markdown_grouped
+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Update/index.html b/Update/index.html new file mode 100644 index 00000000000..a9ed1b260d1 --- /dev/null +++ b/Update/index.html @@ -0,0 +1,972 @@ + + + + + + + + + + + + + + +Update - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Update Guide for Ubuntu/Debian/Kali

+

Requirements:

+
    +
  • Previous install of Faraday 4.6.2 or bellow
  • +
  • Redis
  • +
  • Postgres
  • +
+

Upgrading Faraday

+

Step 1 - Downloading Faraday Installer

+

Download the Faraday installer (.deb or .rpm) from:

+ +

Step 2 - Upgrading the package

+

Go to your Download directory and run the following command:

+
# For .deb
+sudo apt-get install ./faraday-server_amd64.deb
+
+

This process will take charge of installing and migrating all the data to the new version of Faraday.

+

Step 3 - Migrating References (from previous versions to 5.0.0 only)

+

As part of migrating the data on references faraday run:

+
faraday-manage move-references -a true
+
+

Step 4 - Migrating Host Stats (from previous versions to 5.1.1 only)

+

As part of migrating the data on references faraday run:

+
faraday-manage sync-hosts-stats
+
+

Importing License

+
faraday-manage import-license
+
+

Or, in isolated servers, download the license file from the portal and place it in /home/faraday/.faraday/doc/. Remove old license files from the doc folder when renewing the license:

+
tar xvf {license file}.tar.gz
+
+

Post Upgrade

+

Check process and status:

+
sudo systemctl status faraday-server
+sudo systemctl enable faraday-server
+
+sudo systemctl status faraday-worker
+sudo systemctl enable faraday-worker
+
+sudo systemctl status faraday-worker-reports
+sudo systemctl enable faraday-worker-reports
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Upload-Report/index.html b/Upload-Report/index.html new file mode 100644 index 00000000000..46ffa0af63e --- /dev/null +++ b/Upload-Report/index.html @@ -0,0 +1,999 @@ + + + + + + + + + + + + +Upload Report - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Upload Report

+

This wiki will help you to learn the different ways that Faraday has to import a report.

+

Through the Web UI.

+
    +
  • Go to the tab Status Report and click on the button:
  • +
  • Click on Select File in order to select the report that you are going to upload.
  • +
  • Once you have selected the report, click on Upload File and your file will be uploaded.
  • +
+

Through Faraday-Cli

+

Faraday-Cli must be running in each case.

+

Faraday-Cli (Community)

+

It's possible to use Faraday in Command-Line Interface (CLI) mode, allowing you to process your reports in batch. So lets say you want to process the XML output of an nmap scan located in /tmp/nmap_scan.xml and send the results to a workspace called project_one. The way to do it using CLI mode would be to run:

+
1
$ faraday-client --cli --workspace project_one --report /tmp/nmap_scan.xml
+
+

Cli (Professional and Corporate versions)

+

If you're using a Professional or Corporate version, you'll probably need to run Faraday as a certain user, with permissions to access your workspaces. You can pass your credentials using a simple json file that contains both your username and password. You have a template in the directory of your Faraday installation called credentials.json, but you are allowed to use any path and filename for this json file. The structure is this:

+
1
+2
+3
+4
{
+    "username": "your_user_here",
+    "password": "your_password_here"
+}
+
+

And then run Faraday:

+
1
$ faraday-client --cli --workspace project_one --report /tmp/nmap_scan.xml --creds-file /path/to/file/credentials.json
+
+

Through the API

+

In order to see information about uploading a report through the API, follow this link.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Users/index.html b/Users/index.html new file mode 100644 index 00000000000..f2c52ebb4c9 --- /dev/null +++ b/Users/index.html @@ -0,0 +1,974 @@ + + + + + + + + + + + + +Users - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Users

+
+

As part of the Faraday Server setup procedure, an administrator user is automatically generated. The default username for this administrator account is "faraday," and a random password is generated during the setup process. Make sure to securely store this randomly generated password to facilitate any future password changes if required.

+
+

Info

+
+

In case you intend to modify your password, you can execute the command "faraday-manage change-password."

+

For user management tasks, initiate a session in the Faraday Web UI. Subsequently, click on the Faraday slider menu situated on the left pane on the users icon. From there a users section will be displayed.

+

+

Roles

+

Faraday supports four types of Roles with different levels of access to the application.

+
    +
  • +

    Admin: This role lets the administrator manipulate options regarding users, workspaces, vulnerabilities, reports, etc.

    +
  • +
  • +

    Pentester: This role is allowed to access permitted workspaces and create, edit or erase vulnerabilities.

    +
  • +
  • +

    Asset Owner: This role is similar to the Client role, but can modify Vulnerabilities' Status and add Comments, so it's useful for people working in remediation.

    +
  • +
  • +

    Client: This role is allowed to access permitted workspaces without being able to modify anything.

    +
  • +
+

+

LDAP/AD Integration

+

You can also enhance your User management inside Faraday with our LDAP/Active Directory integration. +More information available here.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Using-custom-fields-from-the-API/index.html b/Using-custom-fields-from-the-API/index.html new file mode 100644 index 00000000000..e47006046fd --- /dev/null +++ b/Using-custom-fields-from-the-API/index.html @@ -0,0 +1,1091 @@ + + + + + + + + + + + + +Custom Attributes usage with Faraday API - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Custom Attributes usage with Faraday API

+

Custom Attributes allows you to extend the vulnerability's model by adding more fields. Custom Attributes type can be int, str or list. +You can learn more about Custom Attributes creation on this wiki page.

+

In this small tutorial, we are going to use Python's library Requests and Faraday's API to authenticate, create a vulnerability and modify its Custom Attributes.

+

Step 1: Authentication

+

To authenticate in Faraday, we are going to use a function called faraday_authentication(). This function will return an authenticated request session.

+
def faraday_authentication(host, username, password):
+    """
+       @host: Faraday server host, e.g: http://127.0.0.1:5985
+       @username: Faraday username
+       @password: username's password
+
+       Return requests session object
+    """
+    session = requests.Session()
+    headers = {
+        'Content-Type': 'application/json', # Very important! send this content-type header!!
+    }
+    data = '{"email":username,"password": password}'
+    response = s.post('{0}/_api/login'.format(host), headers=headers, data=data)
+    assert response.status_code == 200
+    return session
+
+

Step 2: Create Custom Attributes

+

In order to create a new Custom Attribute, follow the steps specified in this wiki page.

+

Step 3: Create a vulnerability from the API

+

Before using the API, you need to understand how to send the data to the server. Faraday Server accepts JSON. Assuming that you created a custom attribute with the following data: +Field name: cvss, +Display name: CVSS and assuming that this vulnerability has as CVSS, the score "4", the JSON format for creating this vulnerability is the following:

+
{
+  "metadata": {
+    "update_time": 1549569790.632,
+    "update_user": "",
+    "update_action": 0,
+    "creator": "UI Web",
+    "create_time": 1549569790.632,
+    "update_controller_action": "UI Web New",
+    "owner": "faraday"
+  },
+  "obj_id": "",
+  "owner": "faraday",
+  "parent": 24,
+  "parent_type": "Host",
+  "type": "Vulnerability",
+  "ws": "demo_workspace",
+  "confirmed": true,
+  "data": "",
+  "desc": "Test",
+  "easeofresolution": null,
+  "impact": {
+    "accountability": false,
+    "availability": false,
+    "confidentiality": false,
+    "integrity": false
+  },
+  "name": "dsadsadsa",
+  "owned": false,
+  "policyviolations": [],
+  "refs": [],
+  "resolution": "",
+  "severity": "unclassified",
+  "issuetracker": "",
+  "status": "opened",
+  "custom_fields": {
+    "CVSS" : "4"
+  },
+  "_attachments": {},
+  "description": "",
+  "protocol": "",
+  "version": ""
+}
+
+

Important +* Note that we have a key called "custom_fields" (which contains our custom attributes) with its display name and its value: +

"custom_fields": {
+  "CVSS" : "4"
+}
+

+
    +
  • Two important fields that we need to understand are parent_id and parent_type. In the JSON above, we specified them as follow: +
     "parent_type" : "Host"
    + "parent_id" : "24" 
    +
    +This mean that in our database we have a Host with id 24. If you don't specify this two fields, you will get an invalid response.
  • +
+

You can learn more about the API Server by following this link

+

Code sample for creating a vulnerability

+

Now, let's see a code sample that will create a new vulnerability called Test inside a workspace named demo_workspace. As vuln_payload we will use the JSON that we specified above:

+
faraday_host = 'http://127.0.0.1:5985'
+session = faraday_authentication(faraday_host, 'faraday', 'secret')
+vulnerability_url = '{0}//_api/v3/ws/demo_workspace/vulns/386/'.format(faraday_host)
+vuln_payload = '{"metadata":{"update_time":1549569790.632,"update_user":"","update_action":0,"creator":"UI Web","create_time":1549569790.632,"update_controller_action":"UI Web New","owner":"faraday"},"obj_id":"","owner":"faraday","parent":24,"parent_type":"Host","type":"Vulnerability","ws":"demo_workspace","confirmed":true,"data":"","desc":"dsadsadsa","easeofresolution":null,"impact":{"accountability":false,"availability":false,"confidentiality":false,"integrity":false},"name":"Test","owned":false,"policyviolations":[],"refs":[],"resolution":"","severity":"unclassified","issuetracker":"","status":"opened","custom_fields":{"CVSS" : "4"},"_attachments":{},"description":"","protocol":"","version":""}'
+response = session.post(vulnerability_url, json=vuln_payload)
+
+

The server is going to answer with the created vulnerability and it will return status code "201" (if the creation was successfull) or "409" (if there was any conflict). In our case it returned the status code "201" and a JSON with the response.

+

We can get the vulnerability id by getting the key "id" from the JSON response. In this case, the vulnerability id is _386.

+

Important: If you didn't create the Custom Attribute (see step 2), it will not be seen in the vulnerability. Remember to create the custom attribute first.

+

Getting the vulnerability by its ID using the API

+

Now you can do a GET request on the following url to see the vulnerability in JSON format. Note that we are using the same id as the one we get above (386):

+

http://localhost:5985/_api/v3/ws/demo_workspace/vulns/386/

+

Step 4: Update Custom Attributes

+

In the next example, we are going to update the Custom Attribute "CVSS" located in the vulnerability 386. The new value will be "5".

+

Note: When you update a vulnerability, you need to send the full JSON body of the vulnerability.

+
faraday_host = 'http://127.0.0.1:5985'
+session = faraday_authentication(faraday_host, 'faraday', 'secret')
+vulnerability_url = '{0}/_api/v3/ws/demo_workspace/vulns/386/'.format(faraday_host)
+vuln_payload = '{"metadata":{"update_time":1549569790.632,"update_user":"","update_action":0,"creator":"UI Web","create_time":1549569790.632,"update_controller_action":"UI Web New","owner":"faraday"},"obj_id":"","owner":"faraday","parent":24,"parent_type":"Host","type":"Vulnerability","ws":"demo_workspace","confirmed":true,"data":"","desc":"dsadsadsa","easeofresolution":null,"impact":{"accountability":false,"availability":false,"confidentiality":false,"integrity":false},"name":"Test","owned":false,"policyviolations":[],"refs":[],"resolution":"","severity":"unclassified","issuetracker":"","status":"opened","custom_fields":"CVSS": "5","_attachments":{},"description":"","protocol":"","version":""}'
+response = session.put(vulnerability_url, json=vuln_payload)
+
+

Note that we have changed the value of "CVSS" on the JSON: +``` +"custom_fields": { + "CVSS" : "5" +}

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Vulnerability-Templates-KB/index.html b/Vulnerability-Templates-KB/index.html new file mode 100644 index 00000000000..2913184fc50 --- /dev/null +++ b/Vulnerability-Templates-KB/index.html @@ -0,0 +1,963 @@ + + + + + + + + + + + + + + +Vulnerability KB - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

KB Vulnerability Templates

+

Find yourself writing the same descriptions over and over again? Tired of typos coming up in your reports? Faraday provides a simple solution: unify criteria for naming vulnerabilities and save time and effort to yourself and your team.

+
+

Write vulns once and use them forever!

+
+

Faraday Server allows you to import your own CWE Vulnerabilities DB for you to use as templates. Is a simple CSV made using Open Source projects based in the CWE standard and allows you to create vulnerabilities without worrying about finding references, description, etc.

+

Populate your KB

+

Import csv file

+

Download our CWE example:

+ +

Navigate into Vulnerability > Vuln Template tab in your Faraday Instance Web UI and click on the Add Template Button:

+

+

A dropdown will appear and select Import From File.

+

Adding a Template from Vuln

+

You can also create templates manually from a vuln. In the Web UI, select a vuln and select Create template from the dropdown menu. +

+

You will get a list of the existing templates in your installation

+

Adding a Template manually

+

Navigate into Vulenrabilty > Vuln Template tab in your Faraday Instance Web UI and click on the Add Template button:

+

You will get a form to generate the template.

+

Usage

+

Creating Vuln from Template

+

Click on new Vulnerability, on the name parameter Templates can be selected easily to select a Template form the name search.

+

You can also duplicate vulnerabilities easily by saving them as a template and later on importing the template.

+
+

Note

+

Name, Description and Resolution fields are replaced with the information stored in the templates database.

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Vulns/index.html b/Vulns/index.html new file mode 100644 index 00000000000..f6699cacc9f --- /dev/null +++ b/Vulns/index.html @@ -0,0 +1,1404 @@ + + + + + + + + + + + + + + +Vulnerability Management - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Vulnerability Management

+

To view a full list of yours findings you can access the Vulns view by clicking the Vulnerabilities button on the left menu.

+

+

The Vulns View provides several options including vulnerability search, filtering and management.

+

Personalize this view by adding or removing columns in the Edit Column Order view, where you can select or deselect them from their checkboxes. You can access this view by clicking this button in the top right corner.

+

Also, you can drag & drop some labels of columns and change their order on the table.

+

+

These changes will be persisted in your browser from session to session, so you only have to apply them once.

+

There are many ways to add vulnerabilities into Faraday, create them manually, import scan reports, with supported tools, Faraday Agents or using Faraday API.

+

Import Scan Reports

+

You can upload a scan report of your favorite tool to Faraday and have a nice look at your findings through the Vulns View. You can see a list of the tools that Faraday supports by clicking on this link

+

+

In order to upload a report to Faraday, follow these instructions:

+
    +
  • Click on the button + Add Vulnerability.
  • +
  • Click on the button Import from file and a prompt will be displayed.
  • +
  • Click on Browse in order to select the report that you are going to upload, or just drag and drop the file into the box.
  • +
  • Once you have selected the report, click on Upload and your file will be uploaded.
  • +
  • Refresh the view with the top bar refresh icon.
  • +
+

Create a Vulnerability

+

To create vulnerabilities manually, you can go to the Vulns View page and click the + Add Vulnerability button and then click on Manual Creation. You should see a dialog similar to this:

+

+

The image above shows the tab General that allows you to specify the name, description and severity of your vulnerability. Also, you can specify the ease of resolution, an external ID, its impact, a resolution, its policy violations and references.

+

You also have another tabs in order to add more information to your vulnerability:

+
    +
  • +

    Technical Details: allows you to add the field data to your vulnerability. If you're creating a web vulnerability, you add information about request and response.

    +
  • +
  • +

    Custom Fields: allows you to add information to a field that you have created. For more information about Custom Fields, you can check it here.

    +
  • +
  • +

    Assets: when you fill at least the three mandatory fields of the General tab (name, description and severity), the Assets tab becomes available. Here you can select from a select box 1 to N targets (in order to create 1 to N vulnerabilities), or type a new target if it's not yet in the list.

    +
  • +
  • +

    Evidence: allows you to add an evidence to the vulnerability. It can be a PNG or JPG image.

    +
  • +
+

Make sure you select a host (and a service if the vulnerability applies to it), a name and a description. These fields are mandatory to create a vulnerability

+

Edit Vulnerabilities

+

You can edit the vulnerabilities that you have created or imported. You have multiple ways to edit them.

+

From Vuln Preview

+

You can see a preview of the vulnerability by click on the vuln's name. From here you can edit your vulnerability, and it will be saved automatically.

+

+

As you can see in the image above, there is a new tab named Comments where you can leave comments and mention other users to notify them about important events in real time. For more information about Comments, you can check it here

+

Edit Button

+

If you click on the Edit icon, the vulnerability edit mode will open

+

+

Once you finish updating click on SAVE at the end of the section you are changing.

+

Edit Multiple Vulnerabilities

+

You can select and edit multiple vulnerabilities with just one click. Next to the edit button, you will find a three dotted button that will show a dropdown with the multiple values that you can edit at once or actions like, Create vulnerability templates (KB)

+

Delete Vulnerabilities

+

Select one or more vulnerabilities and click Delete icon

+

+

Confirmed Vulnerabilities

+

You can filter your vulnerabilities by confirmed, unconfirmed by clicking on the Flag icon button:

+

+

Tags

+

Tags allow you to organize your vulnerabilities by letting you make and edit categories: environment, technology, state, language, projects, etc. +You can also use Tags for Reports, allowing you to filter which vulnerabilities you want to generate a report for.

+

How to Tag Vulnerabilities

+

Select the vulnerabilities that you want to tag.

+

+

Click on the "Tags" icon and select if you have a preset tag or Create tag button if you need a new one.

+

+

If you are going to create one just put a relevant name and a dialogue will be displayed.

+

+

Now the vulnerability has tags that you can use for filtering, searching or reporting

+

+

Search and Filter Vulnerabilities

+

Vulns View allows you to filter vulnerabilities, so you can have a better workflow.

+

You can search or filter your data by specifying a keyword or multiple keywords.

+

Field values are not case-sensitive

+

How To Filter

+

In order to perform a search, first click on the search bar and follow these steps:

+
    +
  1. Select if you want to filter by Vulnerabilities or Assets.
  2. +
  3. Enter the name of the field (e.g. severity) and select from the list displayed.
  4. +
  5. Select the connector type that you need to perform the wanted filter (these connectors vary according to the field selected).
  6. +
  7. Finally, type your query or select an option from the list displayed, according to the field and connector selected.
  8. +
  9. Repeat steps 2 to 4 if you want to filter by more than one field.
  10. +
+

Examples:

+

+

You can also click on blue fields of the vulnerability like Service, Hostnames, Target, Owner, etc. to trigger a search on the specific field

+

Filter Fields

+

Now, let's take a look at which fields are available for filtering with an example. All of them are searched through the search field

+
    +
  • Name | = | TCP timestamps
  • +
  • Description | contains | Vulnerability testing
  • +
  • Severity | = | Medium
  • +
  • Target | = | 127.0.0.1
  • +
  • Service name | contains | https
  • +
  • Service port | >= | 5000
  • +
  • Ease of Resolution | = | Moderate
  • +
  • Status | != | Closed
  • +
  • Resolution | contains | Resolution for testing vuln
  • +
  • Data | contains | Search and filter
  • +
  • Request | contains | json
  • +
  • Response | = | OK
  • +
  • Method | = | POST
  • +
  • Path | = | Vulnerability Path
  • +
  • Creator command id | != | 1
  • +
  • Type | = | Vulnerability Web
  • +
  • Confirmed | = | True
  • +
  • ID | = | 57448
  • +
  • Tag | = | my_tag
  • +
+

From the Vulns view you will be able to find the information using the tags parameter
+For example: tags:"MY TAG" as shown in the image below

+

+

Saved Filters and Quick Filters

+

The filters that you create from the search bar, you can save them in order to use them in other opportunities.

+

You can access to these saved filters from the filters button in the top right corner.

+

When you click that button, a dialog opens, in addition to selecting a saved filter, you will be able to select from a varied list of quick filters, as shown in the image below.

+

+

Download a Filtered Workspace

+

You can download a csv file of the filtered workspace (or the full workspace if no filters applied). In order to do so, you have to click on the Download Filtered Workspace button located next to the filters button in the top right corner.

+

Context Menu

+

A new feature in Faraday is the Context Menu, which you can access by right-clicking on the Vulns view.

+

Single selection context menu

+

If you have a single vulnerability selected you will access to the single selection context menu. It should be noted that if you don't have any vulnerability selected yet, the vulnerability of the row where you perform the right click will be selected in order to be used by the context menu.

+

This menu allows the user to execute some actions in a faster manner, such as:

+

+
    +
  • Filter By
  • +
  • Name: creates and executes a filter of the form Name | contains | {name_of_selected_vuln}.
  • +
  • Service name: creates and executes a filter of the form Service name | = | {service_name_of_selected_vuln}.
  • +
  • Target: creates and executes a filter of the form Target | = | {target_of_selected_vuln}.
  • +
  • Date: creates and executes a filter of the form Creation Date | = | {creation_date_of_selected_vuln}.
  • +
  • Status: creates and executes a filter of the form Status | = | {status_of_selected_vuln}.
  • +
  • Tags: creates and executes a filter for each tag the selected vulnerability has, of the form Tag | = | {tag_of_selected_vuln}.
  • +
  • Copy Link: copies to the clipboard the link of the detailed view of the selected vulnerability.
  • +
  • Copy Api Call Link: copies to the clipboard the path of the selected vulnerability in order to be managed through Faraday API.
  • +
  • Edit: enables the edition of some fields of the selected vulnerability:
  • +
  • Name
  • +
  • Data
  • +
  • Description
  • +
  • Resolution
  • +
  • References
  • +
  • Impact
  • +
  • Policy violation
  • +
  • Ease of resolution
  • +
  • Tag: enables the addition of a created tag to the selected vulnerability and the creation of a new tag.
  • +
  • Severity: allows you to select a new severity for the selected vulnerability.
  • +
  • Status: allows you to select a new status for the selected vulnerability.
  • +
  • Add Comment: allows you to add a comment on the selected vulnerability.
  • +
  • Add Evidence: allows you to add an evidence on the selected vulnerability.
  • +
  • Create Template: allows you to create a vulnerability template from the selected vulnerability.
  • +
  • Delete: deletes the selected vulnerability.
  • +
+

Multiple selection context menu

+

If you selected more than one vulnerability, you will access to the multiple selection context menu. It's a shortened version of the regular context menu:

+

+
    +
  • Edit: enables the bulk edition of some fields of the selected vulnerabilities:
  • +
  • Name
  • +
  • Data
  • +
  • Description
  • +
  • Resolution
  • +
  • References
  • +
  • Impact
  • +
  • Policy violation
  • +
  • Confirm/False positive
  • +
  • Ease of resolution
  • +
  • Tag: enables the addition of a created tag to the selected vulnerabilities and the creation of a new tag.
  • +
  • Severity: allows you to select a new severity for the selected vulnerabilities.
  • +
  • Status: allows you to select a new status for the selected vulnerabilities.
  • +
  • Create Template: allows you to create a vulnerability template from each of the selected vulnerabilities.
  • +
  • Bulk Delete: performs a bulk delete of the selected vulnerabilities.
  • +
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/Workspaces/index.html b/Workspaces/index.html new file mode 100644 index 00000000000..e51b01f704c --- /dev/null +++ b/Workspaces/index.html @@ -0,0 +1,1072 @@ + + + + + + + + + + + + + + +Workspaces - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Workspaces

+

Information is organized into various Workspaces. Each Workspace contains a pentest team's assignments and all the intel that is discovered.

+

The workspaces are used to hold the information re-collected from the different tools and/ or commands used in the "actions" for each Penetration Test. Each workspace integrates all the results from pentesters from a given project in the Web console allowing you to identify and manage your information in one place.

+

How to Manage Workspaces

+

To manage your workspaces you need to access your Faraday Web UI and click on the Faraday Logo on the left top of the screen and then on Wokspaces

+

+

A list of workspaces and summary are displayed where you can create, edit or delete them

+

+

Create a Workspace

+

From the workspaces window click on + Add Workspace button and complete below

+
    +
  • Workspace Name
  • +
  • Start Date/ End Date
  • +
  • Description
  • +
  • Make Workspace public (all users can see it)
  • +
  • Assign Users
  • +
+

+

Edit a Workspace

+

From the workspace window select the workspace and click on Edit icon

+

+

Delete a Workspace

+

From the workspaces window select the workspace and click on Delete trash icon

+

+

Read Only Workspaces

+

You can make a workspace READ ONLY from the Workspace View (padlock icon)
+When the padlock icon is closed, the workspace became READ ONLY
+Once a workspace is READ ONLY, you can't add/modify/delete Vulnerablities, Hosts or Services.
+You need click on the padlock (padlock open) to put the Workspace in write mode

+
+

The amount of Workspaces allowed will depend on your license type, workspaces in READ ONLY state has not limits.

+
+

+

Active Workspaces

+
+

Note:
+If you click on the green ACTIVE icon of a workspace, it will disapear from the list, basically making it Archived
+You need to click Show archived to displayed them, click on ACTIVE icon again to work on them

+
+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/agents-v4/index.html b/agents-v4/index.html new file mode 100644 index 00000000000..760d5693626 --- /dev/null +++ b/agents-v4/index.html @@ -0,0 +1,1207 @@ + + + + + + + + + + + + + + +Agents - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Agents

+

Easier integrations with Faraday Agents

+

Integrating systems is a challenging yet essential task in the lifecycle of any software product. Developers often encounter unfamiliar languages, undocumented APIs, or new paradigms when attempting to integrate with external tools. Consequently, many product teams opt not to offer integration capabilities.

+

In the case of Faraday, we recognize that seamless integrations with other security tools are crucial for our product. However, we realized that our existing Plugin system didn't provide the expected ease of use for developing integrations. It required a certain level of interactivity, such as executing commands from the console or importing a report, which made it cumbersome for periodic usage. Additionally, the reliance on our Python API posed difficulties for developers when integrating with tools that weren't programmed in Python.

+

To address this challenge, we made the decision to introduce the Agents feature in the latest release of Faraday (v3.9). Recognizing its significance as a core feature, we are thrilled to offer it in both the Community and commercial versions of our product.

+

Architecture

+

+

Overview of the Agents Feature

+

An Agent represents a process running continuously in a machine (not necessary the same running the Faraday Server). When a user decides to run an Agent (typically done through the Faraday Web UI), it will execute a code and send data back to a Workspace.

+

+

The image displayed showcases a workspace featuring several customized agents. These agents perform various tasks, such as utilizing nmap to discover hosts within the network, employing sublist3r to identify subdomains, and retrieving data from our services hosted on Heroku.

+

Beyond manually executing the agents using their respective "Run" buttons, it is also possible to schedule them for periodic execution. However, please note that this scheduling capability is exclusively available through the web interface for users of our Corporate version.

+
+

Now you can Run an Agent for a single use!

+
+

+

+

or with simple cronjobs if you are using the Community or Paid version.

+

Agents technical details

+

To simplify integrations with Faraday, we have developed the Faraday Agent Dispatcher. This project acts as a communication middleware between the Faraday Server and your custom agents.

+

To create integrations, you can build an Executor script that outputs data in JSON format to the standard output. This script handles tasks like retrieving host information, vulnerabilities, and more. The Dispatcher abstracts the complexities of APIs and communication protocols, allowing you to focus on generating the necessary JSON data. By leveraging the standard output for data transfer, the Dispatcher seamlessly handles the integration process. For further insight into the project's concept, you can refer to the explanation provided by one of our developers here.

+

This flexible approach enables you to employ a wide range of programming languages for your integrations. As long as the language supports standard output printing, you can develop agents in languages like Python, Bash, or even unconventional choices like Brainfuck.

+

We offer official executors that are pre-configured and require minimal setup. Alternatively, you have the option to create and execute custom executors tailored to your specific requirements. For detailed instructions on developing and running custom executors, refer to our custom executor documentation!

+

How to start using agents

+

Lets try with an example with Nmap to check the Faraday Agents capabilities both as a custom executor, and run an official one.

+

First of all you must install the Faraday Dispatcher inside the server you want to run the Agent on. You can do so running one of the following commands:

+
$ git clone https://github.com/infobyte/faraday_agent_dispatcher
+
+
$ git clone https://github.com/infobyte/faraday_agent_parameter__types
+
+

$ pip3 install faraday_agent_dispatcher
+
+After this, you can setup the agent through the Web UI by clicking the tab Create Agent, a windows like this will be displayed

+

+

Once you choose your desired configuration, you'll be able to select the tools that need to be run

+

+

+

After selecting the tools, you'll be able to download the dispatcher.yaml

+

+

Please follow the instruccions depending on what you are working with, in this case we are using Python, so in order to make this work the dispatcher.yaml must be placed in the following folder

+
$HOME/.faraday/config
+
+

Now you would be able to run the agent in your server

+

+

If you have done this correctly, the new agent will be displayed in the Agent view

+

+

Or you can just do it in the manual way running the configuration wizard:

+
$ faraday-dispatcher config-wizard
+
+
Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: A
+Section: server
+host [127.0.0.1]: server.faradaysec.com
+ssl [True]:
+ssl_port [443]:
+ssl_cert []:
+Trying to save with empty value
+workspace [workspace]:
+Section: tokens
+registration [ACorrectTokenHas25CharLen]: ImalA8Cg1L6Z5Qbx2u9CFAsob
+Section: agent
+agent_name [agent]: nmap
+Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: E
+The actual configured executors are: []
+Do you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Name: nmap
+Is a custom executor? (Y, N) [N]: Y
+Command to execute [exit 1]: python3 /home/faraday/faraday_agent_dispatcher/static/executors/official/nmap.py
+Max data sent to server [65536]:
+The actual nmap executor's environment variables are: []
+Do you want to [A]dd, [M]odify or [D]elete an environment variable? Do you want to [Q]uit? (A, M, D, Q) [Q]:
+The actual nmap executor's arguments are: []
+Do you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Argument name: port_list
+Is mandatory? (Y, N): Y
+The actual nmap executor's arguments are: ['port_list']
+Do you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Argument name: target
+Is mandatory? (Y, N): Y
+The actual nmap executor's arguments are: ['port_list', 'target']
+Do you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: Q
+The actual configured executors are: ['nmap']
+Do you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Name: nmapOfficial
+Is a custom executor? (Y, N) [N]:
+The executors are:
+1: wpscan.py
+2: sublist3r.sh
+3: nmap.py
+4: nikto2.py
+5: nessus.py
++: Next page
+Q: Don't choose
+Choose one: 3
+Max data sent to server [65536]:
+The actual configured executors are: ['nmap', 'nmapOfficial']
+Do you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]:
+Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]:
+
+

All the information you added with the configuration wizard should appear on a new dispatcher.ini file at your /.faraday/config/ directory:

+
$ cat  $HOME/.faraday/config/dispatcher.yaml
+[server]
+host = server.faradaysec.com
+ssl = True
+api_port = 443
+websocket_port = 443
+ssl_cert =
+workspace = agent_workspaces
+[tokens]
+registration = ImalA8Cg1L6Z5Qbx2u9CFAsob
+[agent]
+agent_name = nmap
+executors = nmap,nmapOfficial
+[nmap]
+cmd = python3 /Users/famato/dev/faraday_agent_dispatcher/contrib/nmap.py
+max_size = 65536
+[nmap_params]
+port_list = True
+target = True
+[nmap_varenvs]
+[nmapOfficial]
+max_size = 65536
+repo_executor = nmap.py
+[nmapOfficial_params]
+port_list = True
+target = True
+[nmapOfficial_varenvs]
+
+

Now you have to run the dispatcher to register the Agent on your Faraday Server:

+

$ faraday-dispatcher run
+
+
2020-05-11 21:14:01,061 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:91 - register()]  token_registration_url: https://server.faradaysec.com:443/_api/v2/ws/agent_workspaces/agent_registration/
+2020-05-11 21:14:01,977 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:115 - register()]  Registered successfully
+2020-05-11 21:14:02,639 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:150 - connect()]  Connection to Faraday server succeeded
+

+

After this, you’ll see your new Agent on the Web UI. The last step is that you just run the nmap Agent:

+

+

And the Dispatcher log will give you details about this action: +

2022-02-03 15:59:29,676 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:153 - register()]  token_registration_url: https://pro-staging.app3.faradaysec.com:443/_api/v3/agent_registration
+2022-02-03 15:59:30,479 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:192 - register()]  Registered successfully
+2022-02-03 15:59:31,434 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:235 - connect()]  Connection to Faraday server succeeded
+2022-02-03 16:10:11,385 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:256 - run_once()]  Parsing data: {"execution_id": 9, "agent_id": 3, "workspace": "my_workspace", "action": "RUN", "executor": "nmap", "args": {"TARGET": "127.0.0.1"}}
+2022-02-03 16:10:11,419 - faraday_agent_dispatcher - INFO {MainThread} [metadata_utils.py:59 - check_commands()]  Dependency check ended. Ready to go
+2022-02-03 16:10:11,419 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:415 - run_once()]  Running nmap executor
+{"hosts": [{"ip": "127.0.0.1", "os": "unknown", "hostnames": ["localhost"], "description": "", "mac": "00:00:00:00:00:00", "credentials": [], "services": [], "vulnerabilities": [], "tags": []}], "command": {"tool": "Nmap", "command": "Nmap", "params": "", "user": "", "hostname": "", "start_date": "2022-02-03T19:10:11.665787", "duration": 46861, "import_source": "report"}}
+stderr sent empty data, 
+2022-02-03 16:10:13,246 - faraday_agent_dispatcher - INFO {MainThread} [executor_helper.py:118 - processing()]  Data sent to bulk create
+2022-02-03 16:10:14,021 - faraday_agent_dispatcher - INFO {MainThread} [executor_helper.py:148 - end_f()]  Data sent to bulk create
+stdout sent empty data, 
+2022-02-03 16:10:14,021 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:456 - run_once()]  Executor nmap finished successfully
+

+

Right after the Agent executes these actions, return to your Workspace and you can review all the information that was found. +Now you are ready to deploy your own Faraday Agents through your network! +The Dispatcher README file has more detailed documentation to run and build your Agents. Also, we recommend you to check our examples and official executors to get an idea of what a custom integration looks like.

+

What's Next

+

Recently we added Appscan, Qualys and Tenable.io compatibility! try them out!

+

We are committed to enhancing the features and usability of Agents while continuously adding new executors to the Dispatcher repository. In upcoming releases, our focus will also be on providing select Agents with read access to their Workspace. This access will enable them to leverage existing data for uncovering more valuable information.

+
+

We hope you enjoy this feature and find it useful!

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/agents/index.html b/agents/index.html new file mode 100644 index 00000000000..b9ba82b481e --- /dev/null +++ b/agents/index.html @@ -0,0 +1,1128 @@ + + + + + + + + + + + + +Agents - Faraday + + + + + + + + + + + + + + + +
+ + Skip to content + +
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Agents

+

Easier integrations with Faraday Agents

+

Integrating systems is an elusive but mandatory job in any software product's life. Developers have to deal with languages they don't know, undocumented APIs or new paradigms. This leads to the fact that many product teams decide not to open the possibility to integrate to them.

+

In Faraday’s case, we are aware that integrations with other security tools are a critical part of our product. However, we’ve realized that our existing Plugin system wasn’t as easy as we expected to develop some integrations: it required some level of interactivity (either running a command from the console or importing a report), so it was hard to use on a periodic basis. It also forced integration developers to use our Python API, even when the tool to integrate with wasn’t programmed in Python, making it harder for the developer.

+

To solve this problem, we decided to implement the Agents feature in the already released Faraday v3.9. Since we expect this to be a core feature of our product, it will be available both in Community and commercial versions!.

+

Architecture

+

+

Overview of the Agents Feature

+

An Agent represents a process running continuously in a machine (not necessary the same running the Faraday Server). When a user decides to run an Agent (typically done through the Faraday Web UI), it will execute a code and send data back to a Workspace.

+

+

In the image above, you can see a workspace with many custom agents. They're in charge of finding hosts in the network with nmap, finding subdomains with sublist3r, and provision data from our Heroku-hosted services.

+

In addition to running the agents manually with their "Run" button, you can also schedule them to run periodically. This can be done from the web if you have our Corporate version:

+
+

Now you can Run an Agent for a single use!

+
+

+

+

or with simple cronjobs if you are using the Community or Paid version.

+

Agents technical details

+

To make integrations with Faraday as easy as possible, we developed a project we called Faraday Agent Dispatcher that is in charge of handling the communication between the Faraday Server and your own agents.

+

The only thing you’ll need to build your own integrations is a script (we call it an Executor) that prints to standard output all the data you want to send to Faraday (hosts info, vulnerabilities, etc.) encoded in JSON. There is no need to use complex APIs or communication methods, as all of this is abstracted by the Dispatcher. You just need to print JSON to standard out, and the Dispatcher will handle the rest! If you want to know a little bit about the idea behind build this project, one of our developers explain a little about it.

+

This also means that you could use virtually any programming language you want to build your integrations, as long as they support printing data to standard output. We've already made agents in Python, Bash, and even a Brainfuckone!

+

We have some official executors, which are ready to go with minimum configuration. If you want to develop and run your own executor, you can configure a custom one!

+

How to start using agents

+

Lets try with an example with Nmap to check the Faraday Agents’ capabilities both as a custom executor, and run an official one. +First of all you have to get your Agent’s token. On your Web UI go to Settings > Agents.

+

+
+

Your token is: ImalA8Cg1L6Z5Qbx2u9CFAsob

+
+

Now you must install the Faraday Dispatcher inside the server you want to run the Agent on. You can do so running one of the following commands:

+
$ git clone https://github.com/infobyte/faraday_agent_dispatcher
+
+
$ git clone https://github.com/infobyte/faraday_agent_parameter__types
+
+
$ pip3 install faraday_agent_dispatcher
+
+

After this, you need to run the configuration wizard:

+
$ faraday-dispatcher config-wizard
+
+
Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: A
+Section: server
+host [127.0.0.1]: server.faradaysec.com
+ssl [True]:
+ssl_port [443]:
+ssl_cert []:
+Trying to save with empty value
+workspace [workspace]:
+Section: tokens
+registration [ACorrectTokenHas25CharLen]: ImalA8Cg1L6Z5Qbx2u9CFAsob
+Section: agent
+agent_name [agent]: nmap
+Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: E
+The actual configured executors are: []
+Do you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Name: nmap
+Is a custom executor? (Y, N) [N]: Y
+Command to execute [exit 1]: python3 /home/faraday/faraday_agent_dispatcher/static/executors/official/nmap.py
+Max data sent to server [65536]:
+The actual nmap executor's environment variables are: []
+Do you want to [A]dd, [M]odify or [D]elete an environment variable? Do you want to [Q]uit? (A, M, D, Q) [Q]:
+The actual nmap executor's arguments are: []
+Do you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Argument name: port_list
+Is mandatory? (Y, N): Y
+The actual nmap executor's arguments are: ['port_list']
+Do you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Argument name: target
+Is mandatory? (Y, N): Y
+The actual nmap executor's arguments are: ['port_list', 'target']
+Do you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: Q
+The actual configured executors are: ['nmap']
+Do you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A
+Name: nmapOfficial
+Is a custom executor? (Y, N) [N]:
+The executors are:
+1: wpscan.py
+2: sublist3r.sh
+3: nmap.py
+4: nikto2.py
+5: nessus.py
++: Next page
+Q: Don't choose
+Choose one: 3
+Max data sent to server [65536]:
+The actual configured executors are: ['nmap', 'nmapOfficial']
+Do you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]:
+Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]:
+
+

All the information you added with the configuration wizard should appear on a new dispatcher.ini file at your /.faraday/config/ directory:

+
$ cat  $HOME/.faraday/config/dispatcher.ini
+[server]
+host = server.faradaysec.com
+ssl = True
+api_port = 443
+websocket_port = 443
+ssl_cert =
+workspace = agent_workspaces
+[tokens]
+registration = ImalA8Cg1L6Z5Qbx2u9CFAsob
+[agent]
+agent_name = nmap
+executors = nmap,nmapOfficial
+[nmap]
+cmd = python3 /Users/famato/dev/faraday_agent_dispatcher/contrib/nmap.py
+max_size = 65536
+[nmap_params]
+port_list = True
+target = True
+[nmap_varenvs]
+[nmapOfficial]
+max_size = 65536
+repo_executor = nmap.py
+[nmapOfficial_params]
+port_list = True
+target = True
+[nmapOfficial_varenvs]
+
+

Now you have to run the dispatcher to register the Agent on your Faraday Server:

+

$ faraday-dispatcher run
+
+
2020-05-11 21:14:01,061 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:91 - register()]  token_registration_url: https://server.faradaysec.com:443/_api/v2/ws/agent_workspaces/agent_registration/
+2020-05-11 21:14:01,977 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:115 - register()]  Registered successfully
+2020-05-11 21:14:02,639 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:150 - connect()]  Connection to Faraday server succeeded
+

+

After this, you’ll see your new Agent on the Web UI:

+

+

The last step is that you just run the nmap Agent:

+

+

And the Dispatcher log will give you details about this action: +

2020-05-11 21:16:33,691 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:260 - run_once()]  Running nmap executor
+{"hosts": [{"ip": "127.0.0.1", "os": "unknown", "hostnames": ["localhost"], "description": "", "mac": "00:00:00:00:00:00", "credentials": [], "services": [{"name": "http", "protocol": "tcp", "port": 80, "status": "open", "version": "", "description": "http", "credentials": [], "vulnerabilities": []}, {"name": "https", "protocol": "tcp", "port": 443, "status": "open", "version": "", "description": "https", "credentials": [], "vulnerabilities": []}], "vulnerabilities": []}], "command": {"tool": "Nmap", "command": "Nmap", "params": "", "user": "", "hostname": "", "start_date": "2020-05-11T21:16:33.867017", "duration": 1029, "import_source": "report"}}
+stderr sent empty data,
+2020-05-11 21:16:34,596 - faraday_agent_dispatcher - INFO {MainThread} [executor_helper.py:97 - processing()]  Data sent to bulk create
+stdout sent empty data,
+2020-05-11 21:16:34,596 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:281 - run_once()]  Executor nmap
+finished successfully
+

+

Right after the Agent executes these actions, return to your Workspace and you can review all the information that was found. +Now you are ready to deploy your own Faraday Agents through your network! +The Dispatcher README file has more detailed documentation to run and build your Agents. Also, we recommend you to check our examples and official executors to get an idea of what a custom integration looks like.

+

What's Next

+

We will continue to improve Agents’ features, usability, and adding new executors into the Dispatcher repository. +In the next few releases we would also like to give some Agents read access to their Workspace, so they can benefit from the existing data in order to find more valuable information.

+
+

We hope you enjoy this feature and find it useful!

+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/api-swagger/index.html b/api-swagger/index.html new file mode 100644 index 00000000000..59c76a77a2c --- /dev/null +++ b/api-swagger/index.html @@ -0,0 +1,927 @@ + + + + + + + + + + + + + + +Openapi - Faraday + + + + + + + + + + + + + + + +
+
+
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Openapi

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/api-swagger/swagger-1ced0780.html b/api-swagger/swagger-1ced0780.html new file mode 100644 index 00000000000..87349691eb2 --- /dev/null +++ b/api-swagger/swagger-1ced0780.html @@ -0,0 +1,120 @@ + + + + + + Swagger UI + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/assets/images/favicon.png b/assets/images/favicon.png new file mode 100644 index 00000000000..1cf13b9f9d9 Binary files /dev/null and b/assets/images/favicon.png differ diff --git a/assets/javascripts/bundle.bd41221c.min.js b/assets/javascripts/bundle.bd41221c.min.js new file mode 100644 index 00000000000..70bcbf19a05 --- /dev/null +++ b/assets/javascripts/bundle.bd41221c.min.js @@ -0,0 +1,29 @@ +"use strict";(()=>{var _i=Object.create;var br=Object.defineProperty;var Ai=Object.getOwnPropertyDescriptor;var Ci=Object.getOwnPropertyNames,Ft=Object.getOwnPropertySymbols,ki=Object.getPrototypeOf,vr=Object.prototype.hasOwnProperty,eo=Object.prototype.propertyIsEnumerable;var Zr=(e,t,r)=>t in e?br(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,F=(e,t)=>{for(var r in t||(t={}))vr.call(t,r)&&Zr(e,r,t[r]);if(Ft)for(var r of Ft(t))eo.call(t,r)&&Zr(e,r,t[r]);return e};var to=(e,t)=>{var r={};for(var o in e)vr.call(e,o)&&t.indexOf(o)<0&&(r[o]=e[o]);if(e!=null&&Ft)for(var o of Ft(e))t.indexOf(o)<0&&eo.call(e,o)&&(r[o]=e[o]);return r};var gr=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var Hi=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Ci(t))!vr.call(e,n)&&n!==r&&br(e,n,{get:()=>t[n],enumerable:!(o=Ai(t,n))||o.enumerable});return e};var jt=(e,t,r)=>(r=e!=null?_i(ki(e)):{},Hi(t||!e||!e.__esModule?br(r,"default",{value:e,enumerable:!0}):r,e));var ro=(e,t,r)=>new Promise((o,n)=>{var i=c=>{try{a(r.next(c))}catch(p){n(p)}},s=c=>{try{a(r.throw(c))}catch(p){n(p)}},a=c=>c.done?o(c.value):Promise.resolve(c.value).then(i,s);a((r=r.apply(e,t)).next())});var no=gr((xr,oo)=>{(function(e,t){typeof xr=="object"&&typeof oo!="undefined"?t():typeof define=="function"&&define.amd?define(t):t()})(xr,function(){"use strict";function e(r){var o=!0,n=!1,i=null,s={text:!0,search:!0,url:!0,tel:!0,email:!0,password:!0,number:!0,date:!0,month:!0,week:!0,time:!0,datetime:!0,"datetime-local":!0};function a(C){return!!(C&&C!==document&&C.nodeName!=="HTML"&&C.nodeName!=="BODY"&&"classList"in C&&"contains"in C.classList)}function c(C){var ct=C.type,Ne=C.tagName;return!!(Ne==="INPUT"&&s[ct]&&!C.readOnly||Ne==="TEXTAREA"&&!C.readOnly||C.isContentEditable)}function p(C){C.classList.contains("focus-visible")||(C.classList.add("focus-visible"),C.setAttribute("data-focus-visible-added",""))}function l(C){C.hasAttribute("data-focus-visible-added")&&(C.classList.remove("focus-visible"),C.removeAttribute("data-focus-visible-added"))}function f(C){C.metaKey||C.altKey||C.ctrlKey||(a(r.activeElement)&&p(r.activeElement),o=!0)}function u(C){o=!1}function h(C){a(C.target)&&(o||c(C.target))&&p(C.target)}function w(C){a(C.target)&&(C.target.classList.contains("focus-visible")||C.target.hasAttribute("data-focus-visible-added"))&&(n=!0,window.clearTimeout(i),i=window.setTimeout(function(){n=!1},100),l(C.target))}function A(C){document.visibilityState==="hidden"&&(n&&(o=!0),Z())}function Z(){document.addEventListener("mousemove",J),document.addEventListener("mousedown",J),document.addEventListener("mouseup",J),document.addEventListener("pointermove",J),document.addEventListener("pointerdown",J),document.addEventListener("pointerup",J),document.addEventListener("touchmove",J),document.addEventListener("touchstart",J),document.addEventListener("touchend",J)}function te(){document.removeEventListener("mousemove",J),document.removeEventListener("mousedown",J),document.removeEventListener("mouseup",J),document.removeEventListener("pointermove",J),document.removeEventListener("pointerdown",J),document.removeEventListener("pointerup",J),document.removeEventListener("touchmove",J),document.removeEventListener("touchstart",J),document.removeEventListener("touchend",J)}function J(C){C.target.nodeName&&C.target.nodeName.toLowerCase()==="html"||(o=!1,te())}document.addEventListener("keydown",f,!0),document.addEventListener("mousedown",u,!0),document.addEventListener("pointerdown",u,!0),document.addEventListener("touchstart",u,!0),document.addEventListener("visibilitychange",A,!0),Z(),r.addEventListener("focus",h,!0),r.addEventListener("blur",w,!0),r.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&r.host?r.host.setAttribute("data-js-focus-visible",""):r.nodeType===Node.DOCUMENT_NODE&&(document.documentElement.classList.add("js-focus-visible"),document.documentElement.setAttribute("data-js-focus-visible",""))}if(typeof window!="undefined"&&typeof document!="undefined"){window.applyFocusVisiblePolyfill=e;var t;try{t=new CustomEvent("focus-visible-polyfill-ready")}catch(r){t=document.createEvent("CustomEvent"),t.initCustomEvent("focus-visible-polyfill-ready",!1,!1,{})}window.dispatchEvent(t)}typeof document!="undefined"&&e(document)})});var zr=gr((kt,Vr)=>{/*! + * clipboard.js v2.0.11 + * https://clipboardjs.com/ + * + * Licensed MIT © Zeno Rocha + */(function(t,r){typeof kt=="object"&&typeof Vr=="object"?Vr.exports=r():typeof define=="function"&&define.amd?define([],r):typeof kt=="object"?kt.ClipboardJS=r():t.ClipboardJS=r()})(kt,function(){return function(){var e={686:function(o,n,i){"use strict";i.d(n,{default:function(){return Li}});var s=i(279),a=i.n(s),c=i(370),p=i.n(c),l=i(817),f=i.n(l);function u(D){try{return document.execCommand(D)}catch(M){return!1}}var h=function(M){var O=f()(M);return u("cut"),O},w=h;function A(D){var M=document.documentElement.getAttribute("dir")==="rtl",O=document.createElement("textarea");O.style.fontSize="12pt",O.style.border="0",O.style.padding="0",O.style.margin="0",O.style.position="absolute",O.style[M?"right":"left"]="-9999px";var I=window.pageYOffset||document.documentElement.scrollTop;return O.style.top="".concat(I,"px"),O.setAttribute("readonly",""),O.value=D,O}var Z=function(M,O){var I=A(M);O.container.appendChild(I);var W=f()(I);return u("copy"),I.remove(),W},te=function(M){var O=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body},I="";return typeof M=="string"?I=Z(M,O):M instanceof HTMLInputElement&&!["text","search","url","tel","password"].includes(M==null?void 0:M.type)?I=Z(M.value,O):(I=f()(M),u("copy")),I},J=te;function C(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?C=function(O){return typeof O}:C=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},C(D)}var ct=function(){var M=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},O=M.action,I=O===void 0?"copy":O,W=M.container,K=M.target,Ce=M.text;if(I!=="copy"&&I!=="cut")throw new Error('Invalid "action" value, use either "copy" or "cut"');if(K!==void 0)if(K&&C(K)==="object"&&K.nodeType===1){if(I==="copy"&&K.hasAttribute("disabled"))throw new Error('Invalid "target" attribute. Please use "readonly" instead of "disabled" attribute');if(I==="cut"&&(K.hasAttribute("readonly")||K.hasAttribute("disabled")))throw new Error(`Invalid "target" attribute. You can't cut text from elements with "readonly" or "disabled" attributes`)}else throw new Error('Invalid "target" value, use a valid Element');if(Ce)return J(Ce,{container:W});if(K)return I==="cut"?w(K):J(K,{container:W})},Ne=ct;function Pe(D){"@babel/helpers - typeof";return typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?Pe=function(O){return typeof O}:Pe=function(O){return O&&typeof Symbol=="function"&&O.constructor===Symbol&&O!==Symbol.prototype?"symbol":typeof O},Pe(D)}function xi(D,M){if(!(D instanceof M))throw new TypeError("Cannot call a class as a function")}function Xr(D,M){for(var O=0;O0&&arguments[0]!==void 0?arguments[0]:{};this.action=typeof W.action=="function"?W.action:this.defaultAction,this.target=typeof W.target=="function"?W.target:this.defaultTarget,this.text=typeof W.text=="function"?W.text:this.defaultText,this.container=Pe(W.container)==="object"?W.container:document.body}},{key:"listenClick",value:function(W){var K=this;this.listener=p()(W,"click",function(Ce){return K.onClick(Ce)})}},{key:"onClick",value:function(W){var K=W.delegateTarget||W.currentTarget,Ce=this.action(K)||"copy",It=Ne({action:Ce,container:this.container,target:this.target(K),text:this.text(K)});this.emit(It?"success":"error",{action:Ce,text:It,trigger:K,clearSelection:function(){K&&K.focus(),window.getSelection().removeAllRanges()}})}},{key:"defaultAction",value:function(W){return hr("action",W)}},{key:"defaultTarget",value:function(W){var K=hr("target",W);if(K)return document.querySelector(K)}},{key:"defaultText",value:function(W){return hr("text",W)}},{key:"destroy",value:function(){this.listener.destroy()}}],[{key:"copy",value:function(W){var K=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{container:document.body};return J(W,K)}},{key:"cut",value:function(W){return w(W)}},{key:"isSupported",value:function(){var W=arguments.length>0&&arguments[0]!==void 0?arguments[0]:["copy","cut"],K=typeof W=="string"?[W]:W,Ce=!!document.queryCommandSupported;return K.forEach(function(It){Ce=Ce&&!!document.queryCommandSupported(It)}),Ce}}]),O}(a()),Li=Mi},828:function(o){var n=9;if(typeof Element!="undefined"&&!Element.prototype.matches){var i=Element.prototype;i.matches=i.matchesSelector||i.mozMatchesSelector||i.msMatchesSelector||i.oMatchesSelector||i.webkitMatchesSelector}function s(a,c){for(;a&&a.nodeType!==n;){if(typeof a.matches=="function"&&a.matches(c))return a;a=a.parentNode}}o.exports=s},438:function(o,n,i){var s=i(828);function a(l,f,u,h,w){var A=p.apply(this,arguments);return l.addEventListener(u,A,w),{destroy:function(){l.removeEventListener(u,A,w)}}}function c(l,f,u,h,w){return typeof l.addEventListener=="function"?a.apply(null,arguments):typeof u=="function"?a.bind(null,document).apply(null,arguments):(typeof l=="string"&&(l=document.querySelectorAll(l)),Array.prototype.map.call(l,function(A){return a(A,f,u,h,w)}))}function p(l,f,u,h){return function(w){w.delegateTarget=s(w.target,f),w.delegateTarget&&h.call(l,w)}}o.exports=c},879:function(o,n){n.node=function(i){return i!==void 0&&i instanceof HTMLElement&&i.nodeType===1},n.nodeList=function(i){var s=Object.prototype.toString.call(i);return i!==void 0&&(s==="[object NodeList]"||s==="[object HTMLCollection]")&&"length"in i&&(i.length===0||n.node(i[0]))},n.string=function(i){return typeof i=="string"||i instanceof String},n.fn=function(i){var s=Object.prototype.toString.call(i);return s==="[object Function]"}},370:function(o,n,i){var s=i(879),a=i(438);function c(u,h,w){if(!u&&!h&&!w)throw new Error("Missing required arguments");if(!s.string(h))throw new TypeError("Second argument must be a String");if(!s.fn(w))throw new TypeError("Third argument must be a Function");if(s.node(u))return p(u,h,w);if(s.nodeList(u))return l(u,h,w);if(s.string(u))return f(u,h,w);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function p(u,h,w){return u.addEventListener(h,w),{destroy:function(){u.removeEventListener(h,w)}}}function l(u,h,w){return Array.prototype.forEach.call(u,function(A){A.addEventListener(h,w)}),{destroy:function(){Array.prototype.forEach.call(u,function(A){A.removeEventListener(h,w)})}}}function f(u,h,w){return a(document.body,u,h,w)}o.exports=c},817:function(o){function n(i){var s;if(i.nodeName==="SELECT")i.focus(),s=i.value;else if(i.nodeName==="INPUT"||i.nodeName==="TEXTAREA"){var a=i.hasAttribute("readonly");a||i.setAttribute("readonly",""),i.select(),i.setSelectionRange(0,i.value.length),a||i.removeAttribute("readonly"),s=i.value}else{i.hasAttribute("contenteditable")&&i.focus();var c=window.getSelection(),p=document.createRange();p.selectNodeContents(i),c.removeAllRanges(),c.addRange(p),s=c.toString()}return s}o.exports=n},279:function(o){function n(){}n.prototype={on:function(i,s,a){var c=this.e||(this.e={});return(c[i]||(c[i]=[])).push({fn:s,ctx:a}),this},once:function(i,s,a){var c=this;function p(){c.off(i,p),s.apply(a,arguments)}return p._=s,this.on(i,p,a)},emit:function(i){var s=[].slice.call(arguments,1),a=((this.e||(this.e={}))[i]||[]).slice(),c=0,p=a.length;for(c;c{"use strict";/*! + * escape-html + * Copyright(c) 2012-2013 TJ Holowaychuk + * Copyright(c) 2015 Andreas Lubbe + * Copyright(c) 2015 Tiancheng "Timothy" Gu + * MIT Licensed + */var Va=/["'&<>]/;qn.exports=za;function za(e){var t=""+e,r=Va.exec(t);if(!r)return t;var o,n="",i=0,s=0;for(i=r.index;i0&&i[i.length-1])&&(p[0]===6||p[0]===2)){r=0;continue}if(p[0]===3&&(!i||p[1]>i[0]&&p[1]=e.length&&(e=void 0),{value:e&&e[o++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}function V(e,t){var r=typeof Symbol=="function"&&e[Symbol.iterator];if(!r)return e;var o=r.call(e),n,i=[],s;try{for(;(t===void 0||t-- >0)&&!(n=o.next()).done;)i.push(n.value)}catch(a){s={error:a}}finally{try{n&&!n.done&&(r=o.return)&&r.call(o)}finally{if(s)throw s.error}}return i}function z(e,t,r){if(r||arguments.length===2)for(var o=0,n=t.length,i;o1||a(u,h)})})}function a(u,h){try{c(o[u](h))}catch(w){f(i[0][3],w)}}function c(u){u.value instanceof ot?Promise.resolve(u.value.v).then(p,l):f(i[0][2],u)}function p(u){a("next",u)}function l(u){a("throw",u)}function f(u,h){u(h),i.shift(),i.length&&a(i[0][0],i[0][1])}}function so(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var t=e[Symbol.asyncIterator],r;return t?t.call(e):(e=typeof ue=="function"?ue(e):e[Symbol.iterator](),r={},o("next"),o("throw"),o("return"),r[Symbol.asyncIterator]=function(){return this},r);function o(i){r[i]=e[i]&&function(s){return new Promise(function(a,c){s=e[i](s),n(a,c,s.done,s.value)})}}function n(i,s,a,c){Promise.resolve(c).then(function(p){i({value:p,done:a})},s)}}function k(e){return typeof e=="function"}function pt(e){var t=function(o){Error.call(o),o.stack=new Error().stack},r=e(t);return r.prototype=Object.create(Error.prototype),r.prototype.constructor=r,r}var Wt=pt(function(e){return function(r){e(this),this.message=r?r.length+` errors occurred during unsubscription: +`+r.map(function(o,n){return n+1+") "+o.toString()}).join(` + `):"",this.name="UnsubscriptionError",this.errors=r}});function Ve(e,t){if(e){var r=e.indexOf(t);0<=r&&e.splice(r,1)}}var Ie=function(){function e(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._finalizers=null}return e.prototype.unsubscribe=function(){var t,r,o,n,i;if(!this.closed){this.closed=!0;var s=this._parentage;if(s)if(this._parentage=null,Array.isArray(s))try{for(var a=ue(s),c=a.next();!c.done;c=a.next()){var p=c.value;p.remove(this)}}catch(A){t={error:A}}finally{try{c&&!c.done&&(r=a.return)&&r.call(a)}finally{if(t)throw t.error}}else s.remove(this);var l=this.initialTeardown;if(k(l))try{l()}catch(A){i=A instanceof Wt?A.errors:[A]}var f=this._finalizers;if(f){this._finalizers=null;try{for(var u=ue(f),h=u.next();!h.done;h=u.next()){var w=h.value;try{co(w)}catch(A){i=i!=null?i:[],A instanceof Wt?i=z(z([],V(i)),V(A.errors)):i.push(A)}}}catch(A){o={error:A}}finally{try{h&&!h.done&&(n=u.return)&&n.call(u)}finally{if(o)throw o.error}}}if(i)throw new Wt(i)}},e.prototype.add=function(t){var r;if(t&&t!==this)if(this.closed)co(t);else{if(t instanceof e){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._finalizers=(r=this._finalizers)!==null&&r!==void 0?r:[]).push(t)}},e.prototype._hasParent=function(t){var r=this._parentage;return r===t||Array.isArray(r)&&r.includes(t)},e.prototype._addParent=function(t){var r=this._parentage;this._parentage=Array.isArray(r)?(r.push(t),r):r?[r,t]:t},e.prototype._removeParent=function(t){var r=this._parentage;r===t?this._parentage=null:Array.isArray(r)&&Ve(r,t)},e.prototype.remove=function(t){var r=this._finalizers;r&&Ve(r,t),t instanceof e&&t._removeParent(this)},e.EMPTY=function(){var t=new e;return t.closed=!0,t}(),e}();var Er=Ie.EMPTY;function Dt(e){return e instanceof Ie||e&&"closed"in e&&k(e.remove)&&k(e.add)&&k(e.unsubscribe)}function co(e){k(e)?e():e.unsubscribe()}var ke={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1};var lt={setTimeout:function(e,t){for(var r=[],o=2;o0},enumerable:!1,configurable:!0}),t.prototype._trySubscribe=function(r){return this._throwIfClosed(),e.prototype._trySubscribe.call(this,r)},t.prototype._subscribe=function(r){return this._throwIfClosed(),this._checkFinalizedStatuses(r),this._innerSubscribe(r)},t.prototype._innerSubscribe=function(r){var o=this,n=this,i=n.hasError,s=n.isStopped,a=n.observers;return i||s?Er:(this.currentObservers=null,a.push(r),new Ie(function(){o.currentObservers=null,Ve(a,r)}))},t.prototype._checkFinalizedStatuses=function(r){var o=this,n=o.hasError,i=o.thrownError,s=o.isStopped;n?r.error(i):s&&r.complete()},t.prototype.asObservable=function(){var r=new j;return r.source=this,r},t.create=function(r,o){return new vo(r,o)},t}(j);var vo=function(e){se(t,e);function t(r,o){var n=e.call(this)||this;return n.destination=r,n.source=o,n}return t.prototype.next=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.next)===null||n===void 0||n.call(o,r)},t.prototype.error=function(r){var o,n;(n=(o=this.destination)===null||o===void 0?void 0:o.error)===null||n===void 0||n.call(o,r)},t.prototype.complete=function(){var r,o;(o=(r=this.destination)===null||r===void 0?void 0:r.complete)===null||o===void 0||o.call(r)},t.prototype._subscribe=function(r){var o,n;return(n=(o=this.source)===null||o===void 0?void 0:o.subscribe(r))!==null&&n!==void 0?n:Er},t}(v);var St={now:function(){return(St.delegate||Date).now()},delegate:void 0};var Ot=function(e){se(t,e);function t(r,o,n){r===void 0&&(r=1/0),o===void 0&&(o=1/0),n===void 0&&(n=St);var i=e.call(this)||this;return i._bufferSize=r,i._windowTime=o,i._timestampProvider=n,i._buffer=[],i._infiniteTimeWindow=!0,i._infiniteTimeWindow=o===1/0,i._bufferSize=Math.max(1,r),i._windowTime=Math.max(1,o),i}return t.prototype.next=function(r){var o=this,n=o.isStopped,i=o._buffer,s=o._infiniteTimeWindow,a=o._timestampProvider,c=o._windowTime;n||(i.push(r),!s&&i.push(a.now()+c)),this._trimBuffer(),e.prototype.next.call(this,r)},t.prototype._subscribe=function(r){this._throwIfClosed(),this._trimBuffer();for(var o=this._innerSubscribe(r),n=this,i=n._infiniteTimeWindow,s=n._buffer,a=s.slice(),c=0;c0?e.prototype.requestAsyncId.call(this,r,o,n):(r.actions.push(this),r._scheduled||(r._scheduled=ut.requestAnimationFrame(function(){return r.flush(void 0)})))},t.prototype.recycleAsyncId=function(r,o,n){var i;if(n===void 0&&(n=0),n!=null?n>0:this.delay>0)return e.prototype.recycleAsyncId.call(this,r,o,n);var s=r.actions;o!=null&&((i=s[s.length-1])===null||i===void 0?void 0:i.id)!==o&&(ut.cancelAnimationFrame(o),r._scheduled=void 0)},t}(zt);var yo=function(e){se(t,e);function t(){return e!==null&&e.apply(this,arguments)||this}return t.prototype.flush=function(r){this._active=!0;var o=this._scheduled;this._scheduled=void 0;var n=this.actions,i;r=r||n.shift();do if(i=r.execute(r.state,r.delay))break;while((r=n[0])&&r.id===o&&n.shift());if(this._active=!1,i){for(;(r=n[0])&&r.id===o&&n.shift();)r.unsubscribe();throw i}},t}(qt);var de=new yo(xo);var L=new j(function(e){return e.complete()});function Kt(e){return e&&k(e.schedule)}function _r(e){return e[e.length-1]}function Je(e){return k(_r(e))?e.pop():void 0}function Ae(e){return Kt(_r(e))?e.pop():void 0}function Qt(e,t){return typeof _r(e)=="number"?e.pop():t}var dt=function(e){return e&&typeof e.length=="number"&&typeof e!="function"};function Yt(e){return k(e==null?void 0:e.then)}function Bt(e){return k(e[ft])}function Gt(e){return Symbol.asyncIterator&&k(e==null?void 0:e[Symbol.asyncIterator])}function Jt(e){return new TypeError("You provided "+(e!==null&&typeof e=="object"?"an invalid object":"'"+e+"'")+" where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.")}function Di(){return typeof Symbol!="function"||!Symbol.iterator?"@@iterator":Symbol.iterator}var Xt=Di();function Zt(e){return k(e==null?void 0:e[Xt])}function er(e){return ao(this,arguments,function(){var r,o,n,i;return Ut(this,function(s){switch(s.label){case 0:r=e.getReader(),s.label=1;case 1:s.trys.push([1,,9,10]),s.label=2;case 2:return[4,ot(r.read())];case 3:return o=s.sent(),n=o.value,i=o.done,i?[4,ot(void 0)]:[3,5];case 4:return[2,s.sent()];case 5:return[4,ot(n)];case 6:return[4,s.sent()];case 7:return s.sent(),[3,2];case 8:return[3,10];case 9:return r.releaseLock(),[7];case 10:return[2]}})})}function tr(e){return k(e==null?void 0:e.getReader)}function N(e){if(e instanceof j)return e;if(e!=null){if(Bt(e))return Ni(e);if(dt(e))return Vi(e);if(Yt(e))return zi(e);if(Gt(e))return Eo(e);if(Zt(e))return qi(e);if(tr(e))return Ki(e)}throw Jt(e)}function Ni(e){return new j(function(t){var r=e[ft]();if(k(r.subscribe))return r.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}function Vi(e){return new j(function(t){for(var r=0;r=2;return function(o){return o.pipe(e?g(function(n,i){return e(n,i,o)}):ce,ye(1),r?Qe(t):jo(function(){return new or}))}}function $r(e){return e<=0?function(){return L}:x(function(t,r){var o=[];t.subscribe(S(r,function(n){o.push(n),e=2,!0))}function le(e){e===void 0&&(e={});var t=e.connector,r=t===void 0?function(){return new v}:t,o=e.resetOnError,n=o===void 0?!0:o,i=e.resetOnComplete,s=i===void 0?!0:i,a=e.resetOnRefCountZero,c=a===void 0?!0:a;return function(p){var l,f,u,h=0,w=!1,A=!1,Z=function(){f==null||f.unsubscribe(),f=void 0},te=function(){Z(),l=u=void 0,w=A=!1},J=function(){var C=l;te(),C==null||C.unsubscribe()};return x(function(C,ct){h++,!A&&!w&&Z();var Ne=u=u!=null?u:r();ct.add(function(){h--,h===0&&!A&&!w&&(f=Pr(J,c))}),Ne.subscribe(ct),!l&&h>0&&(l=new it({next:function(Pe){return Ne.next(Pe)},error:function(Pe){A=!0,Z(),f=Pr(te,n,Pe),Ne.error(Pe)},complete:function(){w=!0,Z(),f=Pr(te,s),Ne.complete()}}),N(C).subscribe(l))})(p)}}function Pr(e,t){for(var r=[],o=2;oe.next(document)),e}function R(e,t=document){return Array.from(t.querySelectorAll(e))}function P(e,t=document){let r=me(e,t);if(typeof r=="undefined")throw new ReferenceError(`Missing element: expected "${e}" to be present`);return r}function me(e,t=document){return t.querySelector(e)||void 0}function Re(){var e,t,r,o;return(o=(r=(t=(e=document.activeElement)==null?void 0:e.shadowRoot)==null?void 0:t.activeElement)!=null?r:document.activeElement)!=null?o:void 0}var la=T(d(document.body,"focusin"),d(document.body,"focusout")).pipe(be(1),q(void 0),m(()=>Re()||document.body),B(1));function vt(e){return la.pipe(m(t=>e.contains(t)),Y())}function Vo(e,t){return T(d(e,"mouseenter").pipe(m(()=>!0)),d(e,"mouseleave").pipe(m(()=>!1))).pipe(t?be(t):ce,q(!1))}function Ue(e){return{x:e.offsetLeft,y:e.offsetTop}}function zo(e){return T(d(window,"load"),d(window,"resize")).pipe(Me(0,de),m(()=>Ue(e)),q(Ue(e)))}function ir(e){return{x:e.scrollLeft,y:e.scrollTop}}function et(e){return T(d(e,"scroll"),d(window,"resize")).pipe(Me(0,de),m(()=>ir(e)),q(ir(e)))}function qo(e,t){if(typeof t=="string"||typeof t=="number")e.innerHTML+=t.toString();else if(t instanceof Node)e.appendChild(t);else if(Array.isArray(t))for(let r of t)qo(e,r)}function E(e,t,...r){let o=document.createElement(e);if(t)for(let n of Object.keys(t))typeof t[n]!="undefined"&&(typeof t[n]!="boolean"?o.setAttribute(n,t[n]):o.setAttribute(n,""));for(let n of r)qo(o,n);return o}function ar(e){if(e>999){let t=+((e-950)%1e3>99);return`${((e+1e-6)/1e3).toFixed(t)}k`}else return e.toString()}function gt(e){let t=E("script",{src:e});return H(()=>(document.head.appendChild(t),T(d(t,"load"),d(t,"error").pipe(b(()=>Ar(()=>new ReferenceError(`Invalid script: ${e}`))))).pipe(m(()=>{}),_(()=>document.head.removeChild(t)),ye(1))))}var Ko=new v,ma=H(()=>typeof ResizeObserver=="undefined"?gt("https://unpkg.com/resize-observer-polyfill"):$(void 0)).pipe(m(()=>new ResizeObserver(e=>{for(let t of e)Ko.next(t)})),b(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function pe(e){return{width:e.offsetWidth,height:e.offsetHeight}}function Ee(e){return ma.pipe(y(t=>t.observe(e)),b(t=>Ko.pipe(g(({target:r})=>r===e),_(()=>t.unobserve(e)),m(()=>pe(e)))),q(pe(e)))}function xt(e){return{width:e.scrollWidth,height:e.scrollHeight}}function sr(e){let t=e.parentElement;for(;t&&(e.scrollWidth<=t.scrollWidth&&e.scrollHeight<=t.scrollHeight);)t=(e=t).parentElement;return t?e:void 0}var Qo=new v,fa=H(()=>$(new IntersectionObserver(e=>{for(let t of e)Qo.next(t)},{threshold:0}))).pipe(b(e=>T(qe,$(e)).pipe(_(()=>e.disconnect()))),B(1));function yt(e){return fa.pipe(y(t=>t.observe(e)),b(t=>Qo.pipe(g(({target:r})=>r===e),_(()=>t.unobserve(e)),m(({isIntersecting:r})=>r))))}function Yo(e,t=16){return et(e).pipe(m(({y:r})=>{let o=pe(e),n=xt(e);return r>=n.height-o.height-t}),Y())}var cr={drawer:P("[data-md-toggle=drawer]"),search:P("[data-md-toggle=search]")};function Bo(e){return cr[e].checked}function Be(e,t){cr[e].checked!==t&&cr[e].click()}function We(e){let t=cr[e];return d(t,"change").pipe(m(()=>t.checked),q(t.checked))}function ua(e,t){switch(e.constructor){case HTMLInputElement:return e.type==="radio"?/^Arrow/.test(t):!0;case HTMLSelectElement:case HTMLTextAreaElement:return!0;default:return e.isContentEditable}}function da(){return T(d(window,"compositionstart").pipe(m(()=>!0)),d(window,"compositionend").pipe(m(()=>!1))).pipe(q(!1))}function Go(){let e=d(window,"keydown").pipe(g(t=>!(t.metaKey||t.ctrlKey)),m(t=>({mode:Bo("search")?"search":"global",type:t.key,claim(){t.preventDefault(),t.stopPropagation()}})),g(({mode:t,type:r})=>{if(t==="global"){let o=Re();if(typeof o!="undefined")return!ua(o,r)}return!0}),le());return da().pipe(b(t=>t?L:e))}function ve(){return new URL(location.href)}function st(e,t=!1){if(G("navigation.instant")&&!t){let r=E("a",{href:e.href});document.body.appendChild(r),r.click(),r.remove()}else location.href=e.href}function Jo(){return new v}function Xo(){return location.hash.slice(1)}function Zo(e){let t=E("a",{href:e});t.addEventListener("click",r=>r.stopPropagation()),t.click()}function ha(e){return T(d(window,"hashchange"),e).pipe(m(Xo),q(Xo()),g(t=>t.length>0),B(1))}function en(e){return ha(e).pipe(m(t=>me(`[id="${t}"]`)),g(t=>typeof t!="undefined"))}function At(e){let t=matchMedia(e);return nr(r=>t.addListener(()=>r(t.matches))).pipe(q(t.matches))}function tn(){let e=matchMedia("print");return T(d(window,"beforeprint").pipe(m(()=>!0)),d(window,"afterprint").pipe(m(()=>!1))).pipe(q(e.matches))}function Ur(e,t){return e.pipe(b(r=>r?t():L))}function Wr(e,t){return new j(r=>{let o=new XMLHttpRequest;return o.open("GET",`${e}`),o.responseType="blob",o.addEventListener("load",()=>{o.status>=200&&o.status<300?(r.next(o.response),r.complete()):r.error(new Error(o.statusText))}),o.addEventListener("error",()=>{r.error(new Error("Network error"))}),o.addEventListener("abort",()=>{r.complete()}),typeof(t==null?void 0:t.progress$)!="undefined"&&(o.addEventListener("progress",n=>{var i;if(n.lengthComputable)t.progress$.next(n.loaded/n.total*100);else{let s=(i=o.getResponseHeader("Content-Length"))!=null?i:0;t.progress$.next(n.loaded/+s*100)}}),t.progress$.next(5)),o.send(),()=>o.abort()})}function De(e,t){return Wr(e,t).pipe(b(r=>r.text()),m(r=>JSON.parse(r)),B(1))}function rn(e,t){let r=new DOMParser;return Wr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/html")),B(1))}function on(e,t){let r=new DOMParser;return Wr(e,t).pipe(b(o=>o.text()),m(o=>r.parseFromString(o,"text/xml")),B(1))}function nn(){return{x:Math.max(0,scrollX),y:Math.max(0,scrollY)}}function an(){return T(d(window,"scroll",{passive:!0}),d(window,"resize",{passive:!0})).pipe(m(nn),q(nn()))}function sn(){return{width:innerWidth,height:innerHeight}}function cn(){return d(window,"resize",{passive:!0}).pipe(m(sn),q(sn()))}function pn(){return Q([an(),cn()]).pipe(m(([e,t])=>({offset:e,size:t})),B(1))}function pr(e,{viewport$:t,header$:r}){let o=t.pipe(X("size")),n=Q([o,r]).pipe(m(()=>Ue(e)));return Q([r,t,n]).pipe(m(([{height:i},{offset:s,size:a},{x:c,y:p}])=>({offset:{x:s.x-c,y:s.y-p+i},size:a})))}function ba(e){return d(e,"message",t=>t.data)}function va(e){let t=new v;return t.subscribe(r=>e.postMessage(r)),t}function ln(e,t=new Worker(e)){let r=ba(t),o=va(t),n=new v;n.subscribe(o);let i=o.pipe(ee(),oe(!0));return n.pipe(ee(),$e(r.pipe(U(i))),le())}var ga=P("#__config"),Et=JSON.parse(ga.textContent);Et.base=`${new URL(Et.base,ve())}`;function we(){return Et}function G(e){return Et.features.includes(e)}function ge(e,t){return typeof t!="undefined"?Et.translations[e].replace("#",t.toString()):Et.translations[e]}function Te(e,t=document){return P(`[data-md-component=${e}]`,t)}function ne(e,t=document){return R(`[data-md-component=${e}]`,t)}function xa(e){let t=P(".md-typeset > :first-child",e);return d(t,"click",{once:!0}).pipe(m(()=>P(".md-typeset",e)),m(r=>({hash:__md_hash(r.innerHTML)})))}function mn(e){if(!G("announce.dismiss")||!e.childElementCount)return L;if(!e.hidden){let t=P(".md-typeset",e);__md_hash(t.innerHTML)===__md_get("__announce")&&(e.hidden=!0)}return H(()=>{let t=new v;return t.subscribe(({hash:r})=>{e.hidden=!0,__md_set("__announce",r)}),xa(e).pipe(y(r=>t.next(r)),_(()=>t.complete()),m(r=>F({ref:e},r)))})}function ya(e,{target$:t}){return t.pipe(m(r=>({hidden:r!==e})))}function fn(e,t){let r=new v;return r.subscribe(({hidden:o})=>{e.hidden=o}),ya(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))}function Ct(e,t){return t==="inline"?E("div",{class:"md-tooltip md-tooltip--inline",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"})):E("div",{class:"md-tooltip",id:e,role:"tooltip"},E("div",{class:"md-tooltip__inner md-typeset"}))}function un(e,t){if(t=t?`${t}_annotation_${e}`:void 0,t){let r=t?`#${t}`:void 0;return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("a",{href:r,class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}else return E("aside",{class:"md-annotation",tabIndex:0},Ct(t),E("span",{class:"md-annotation__index",tabIndex:-1},E("span",{"data-md-annotation-id":e})))}function dn(e){return E("button",{class:"md-clipboard md-icon",title:ge("clipboard.copy"),"data-clipboard-target":`#${e} > code`})}function Dr(e,t){let r=t&2,o=t&1,n=Object.keys(e.terms).filter(c=>!e.terms[c]).reduce((c,p)=>[...c,E("del",null,p)," "],[]).slice(0,-1),i=we(),s=new URL(e.location,i.base);G("search.highlight")&&s.searchParams.set("h",Object.entries(e.terms).filter(([,c])=>c).reduce((c,[p])=>`${c} ${p}`.trim(),""));let{tags:a}=we();return E("a",{href:`${s}`,class:"md-search-result__link",tabIndex:-1},E("article",{class:"md-search-result__article md-typeset","data-md-score":e.score.toFixed(2)},r>0&&E("div",{class:"md-search-result__icon md-icon"}),r>0&&E("h1",null,e.title),r<=0&&E("h2",null,e.title),o>0&&e.text.length>0&&e.text,e.tags&&e.tags.map(c=>{let p=a?c in a?`md-tag-icon md-tag--${a[c]}`:"md-tag-icon":"";return E("span",{class:`md-tag ${p}`},c)}),o>0&&n.length>0&&E("p",{class:"md-search-result__terms"},ge("search.result.term.missing"),": ",...n)))}function hn(e){let t=e[0].score,r=[...e],o=we(),n=r.findIndex(l=>!`${new URL(l.location,o.base)}`.includes("#")),[i]=r.splice(n,1),s=r.findIndex(l=>l.scoreDr(l,1)),...c.length?[E("details",{class:"md-search-result__more"},E("summary",{tabIndex:-1},E("div",null,c.length>0&&c.length===1?ge("search.result.more.one"):ge("search.result.more.other",c.length))),...c.map(l=>Dr(l,1)))]:[]];return E("li",{class:"md-search-result__item"},p)}function bn(e){return E("ul",{class:"md-source__facts"},Object.entries(e).map(([t,r])=>E("li",{class:`md-source__fact md-source__fact--${t}`},typeof r=="number"?ar(r):r)))}function Nr(e){let t=`tabbed-control tabbed-control--${e}`;return E("div",{class:t,hidden:!0},E("button",{class:"tabbed-button",tabIndex:-1,"aria-hidden":"true"}))}function vn(e){return E("div",{class:"md-typeset__scrollwrap"},E("div",{class:"md-typeset__table"},e))}function Ea(e){let t=we(),r=new URL(`../${e.version}/`,t.base);return E("li",{class:"md-version__item"},E("a",{href:`${r}`,class:"md-version__link"},e.title))}function gn(e,t){return e=e.filter(r=>{var o;return!((o=r.properties)!=null&&o.hidden)}),E("div",{class:"md-version"},E("button",{class:"md-version__current","aria-label":ge("select.version")},t.title),E("ul",{class:"md-version__list"},e.map(Ea)))}var wa=0;function Ta(e,t){document.body.append(e);let{width:r}=pe(e);e.style.setProperty("--md-tooltip-width",`${r}px`),e.remove();let o=sr(t),n=typeof o!="undefined"?et(o):$({x:0,y:0}),i=T(vt(t),Vo(t)).pipe(Y());return Q([i,n]).pipe(m(([s,a])=>{let{x:c,y:p}=Ue(t),l=pe(t),f=t.closest("table");return f&&t.parentElement&&(c+=f.offsetLeft+t.parentElement.offsetLeft,p+=f.offsetTop+t.parentElement.offsetTop),{active:s,offset:{x:c-a.x+l.width/2-r/2,y:p-a.y+l.height+8}}}))}function Ge(e){let t=e.title;if(!t.length)return L;let r=`__tooltip_${wa++}`,o=Ct(r,"inline"),n=P(".md-typeset",o);return n.innerHTML=t,H(()=>{let i=new v;return i.subscribe({next({offset:s}){o.style.setProperty("--md-tooltip-x",`${s.x}px`),o.style.setProperty("--md-tooltip-y",`${s.y}px`)},complete(){o.style.removeProperty("--md-tooltip-x"),o.style.removeProperty("--md-tooltip-y")}}),T(i.pipe(g(({active:s})=>s)),i.pipe(be(250),g(({active:s})=>!s))).subscribe({next({active:s}){s?(e.insertAdjacentElement("afterend",o),e.setAttribute("aria-describedby",r),e.removeAttribute("title")):(o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t))},complete(){o.remove(),e.removeAttribute("aria-describedby"),e.setAttribute("title",t)}}),i.pipe(Me(16,de)).subscribe(({active:s})=>{o.classList.toggle("md-tooltip--active",s)}),i.pipe(_t(125,de),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:s})=>s)).subscribe({next(s){s?o.style.setProperty("--md-tooltip-0",`${-s}px`):o.style.removeProperty("--md-tooltip-0")},complete(){o.style.removeProperty("--md-tooltip-0")}}),Ta(o,e).pipe(y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))}).pipe(ze(ie))}function Sa(e,t){let r=H(()=>Q([zo(e),et(t)])).pipe(m(([{x:o,y:n},i])=>{let{width:s,height:a}=pe(e);return{x:o-i.x+s/2,y:n-i.y+a/2}}));return vt(e).pipe(b(o=>r.pipe(m(n=>({active:o,offset:n})),ye(+!o||1/0))))}function xn(e,t,{target$:r}){let[o,n]=Array.from(e.children);return H(()=>{let i=new v,s=i.pipe(ee(),oe(!0));return i.subscribe({next({offset:a}){e.style.setProperty("--md-tooltip-x",`${a.x}px`),e.style.setProperty("--md-tooltip-y",`${a.y}px`)},complete(){e.style.removeProperty("--md-tooltip-x"),e.style.removeProperty("--md-tooltip-y")}}),yt(e).pipe(U(s)).subscribe(a=>{e.toggleAttribute("data-md-visible",a)}),T(i.pipe(g(({active:a})=>a)),i.pipe(be(250),g(({active:a})=>!a))).subscribe({next({active:a}){a?e.prepend(o):o.remove()},complete(){e.prepend(o)}}),i.pipe(Me(16,de)).subscribe(({active:a})=>{o.classList.toggle("md-tooltip--active",a)}),i.pipe(_t(125,de),g(()=>!!e.offsetParent),m(()=>e.offsetParent.getBoundingClientRect()),m(({x:a})=>a)).subscribe({next(a){a?e.style.setProperty("--md-tooltip-0",`${-a}px`):e.style.removeProperty("--md-tooltip-0")},complete(){e.style.removeProperty("--md-tooltip-0")}}),d(n,"click").pipe(U(s),g(a=>!(a.metaKey||a.ctrlKey))).subscribe(a=>{a.stopPropagation(),a.preventDefault()}),d(n,"mousedown").pipe(U(s),ae(i)).subscribe(([a,{active:c}])=>{var p;if(a.button!==0||a.metaKey||a.ctrlKey)a.preventDefault();else if(c){a.preventDefault();let l=e.parentElement.closest(".md-annotation");l instanceof HTMLElement?l.focus():(p=Re())==null||p.blur()}}),r.pipe(U(s),g(a=>a===o),Ye(125)).subscribe(()=>e.focus()),Sa(e,t).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Oa(e){return e.tagName==="CODE"?R(".c, .c1, .cm",e):[e]}function Ma(e){let t=[];for(let r of Oa(e)){let o=[],n=document.createNodeIterator(r,NodeFilter.SHOW_TEXT);for(let i=n.nextNode();i;i=n.nextNode())o.push(i);for(let i of o){let s;for(;s=/(\(\d+\))(!)?/.exec(i.textContent);){let[,a,c]=s;if(typeof c=="undefined"){let p=i.splitText(s.index);i=p.splitText(a.length),t.push(p)}else{i.textContent=a,t.push(i);break}}}}return t}function yn(e,t){t.append(...Array.from(e.childNodes))}function lr(e,t,{target$:r,print$:o}){let n=t.closest("[id]"),i=n==null?void 0:n.id,s=new Map;for(let a of Ma(t)){let[,c]=a.textContent.match(/\((\d+)\)/);me(`:scope > li:nth-child(${c})`,e)&&(s.set(c,un(c,i)),a.replaceWith(s.get(c)))}return s.size===0?L:H(()=>{let a=new v,c=a.pipe(ee(),oe(!0)),p=[];for(let[l,f]of s)p.push([P(".md-typeset",f),P(`:scope > li:nth-child(${l})`,e)]);return o.pipe(U(c)).subscribe(l=>{e.hidden=!l,e.classList.toggle("md-annotation-list",l);for(let[f,u]of p)l?yn(f,u):yn(u,f)}),T(...[...s].map(([,l])=>xn(l,t,{target$:r}))).pipe(_(()=>a.complete()),le())})}function En(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return En(t)}}function wn(e,t){return H(()=>{let r=En(e);return typeof r!="undefined"?lr(r,e,t):L})}var Tn=jt(zr());var La=0;function Sn(e){if(e.nextElementSibling){let t=e.nextElementSibling;if(t.tagName==="OL")return t;if(t.tagName==="P"&&!t.children.length)return Sn(t)}}function _a(e){return Ee(e).pipe(m(({width:t})=>({scrollable:xt(e).width>t})),X("scrollable"))}function On(e,t){let{matches:r}=matchMedia("(hover)"),o=H(()=>{let n=new v,i=n.pipe($r(1));n.subscribe(({scrollable:c})=>{c&&r?e.setAttribute("tabindex","0"):e.removeAttribute("tabindex")});let s=[];if(Tn.default.isSupported()&&(e.closest(".copy")||G("content.code.copy")&&!e.closest(".no-copy"))){let c=e.closest("pre");c.id=`__code_${La++}`;let p=dn(c.id);c.insertBefore(p,e),G("content.tooltips")&&s.push(Ge(p))}let a=e.closest(".highlight");if(a instanceof HTMLElement){let c=Sn(a);if(typeof c!="undefined"&&(a.classList.contains("annotate")||G("content.code.annotate"))){let p=lr(c,e,t);s.push(Ee(a).pipe(U(i),m(({width:l,height:f})=>l&&f),Y(),b(l=>l?p:L)))}}return _a(e).pipe(y(c=>n.next(c)),_(()=>n.complete()),m(c=>F({ref:e},c)),$e(...s))});return G("content.lazy")?yt(e).pipe(g(n=>n),ye(1),b(()=>o)):o}function Aa(e,{target$:t,print$:r}){let o=!0;return T(t.pipe(m(n=>n.closest("details:not([open])")),g(n=>e===n),m(()=>({action:"open",reveal:!0}))),r.pipe(g(n=>n||!o),y(()=>o=e.open),m(n=>({action:n?"open":"close"}))))}function Mn(e,t){return H(()=>{let r=new v;return r.subscribe(({action:o,reveal:n})=>{e.toggleAttribute("open",o==="open"),n&&e.scrollIntoView()}),Aa(e,t).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}var Ln=".node circle,.node ellipse,.node path,.node polygon,.node rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}marker{fill:var(--md-mermaid-edge-color)!important}.edgeLabel .label rect{fill:#0000}.label{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.label foreignObject{line-height:normal;overflow:visible}.label div .edgeLabel{color:var(--md-mermaid-label-fg-color)}.edgeLabel,.edgeLabel rect,.label div .edgeLabel{background-color:var(--md-mermaid-label-bg-color)}.edgeLabel,.edgeLabel rect{fill:var(--md-mermaid-label-bg-color);color:var(--md-mermaid-edge-color)}.edgePath .path,.flowchart-link{stroke:var(--md-mermaid-edge-color);stroke-width:.05rem}.edgePath .arrowheadPath{fill:var(--md-mermaid-edge-color);stroke:none}.cluster rect{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}.cluster span{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}g #flowchart-circleEnd,g #flowchart-circleStart,g #flowchart-crossEnd,g #flowchart-crossStart,g #flowchart-pointEnd,g #flowchart-pointStart{stroke:none}g.classGroup line,g.classGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.classGroup text{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.classLabel .box{fill:var(--md-mermaid-label-bg-color);background-color:var(--md-mermaid-label-bg-color);opacity:1}.classLabel .label{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node .divider{stroke:var(--md-mermaid-node-fg-color)}.relation{stroke:var(--md-mermaid-edge-color)}.cardinality{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.cardinality text{fill:inherit!important}defs #classDiagram-compositionEnd,defs #classDiagram-compositionStart,defs #classDiagram-dependencyEnd,defs #classDiagram-dependencyStart,defs #classDiagram-extensionEnd,defs #classDiagram-extensionStart{fill:var(--md-mermaid-edge-color)!important;stroke:var(--md-mermaid-edge-color)!important}defs #classDiagram-aggregationEnd,defs #classDiagram-aggregationStart{fill:var(--md-mermaid-label-bg-color)!important;stroke:var(--md-mermaid-edge-color)!important}g.stateGroup rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}g.stateGroup .state-title{fill:var(--md-mermaid-label-fg-color)!important;font-family:var(--md-mermaid-font-family)}g.stateGroup .composit{fill:var(--md-mermaid-label-bg-color)}.nodeLabel,.nodeLabel p{color:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.node circle.state-end,.node circle.state-start,.start-state{fill:var(--md-mermaid-edge-color);stroke:none}.end-state-inner,.end-state-outer{fill:var(--md-mermaid-edge-color)}.end-state-inner,.node circle.state-end{stroke:var(--md-mermaid-label-bg-color)}.transition{stroke:var(--md-mermaid-edge-color)}[id^=state-fork] rect,[id^=state-join] rect{fill:var(--md-mermaid-edge-color)!important;stroke:none!important}.statediagram-cluster.statediagram-cluster .inner{fill:var(--md-default-bg-color)}.statediagram-cluster rect{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.statediagram-state rect.divider{fill:var(--md-default-fg-color--lightest);stroke:var(--md-default-fg-color--lighter)}defs #statediagram-barbEnd{stroke:var(--md-mermaid-edge-color)}.attributeBoxEven,.attributeBoxOdd{fill:var(--md-mermaid-node-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityBox{fill:var(--md-mermaid-label-bg-color);stroke:var(--md-mermaid-node-fg-color)}.entityLabel{fill:var(--md-mermaid-label-fg-color);font-family:var(--md-mermaid-font-family)}.relationshipLabelBox{fill:var(--md-mermaid-label-bg-color);fill-opacity:1;background-color:var(--md-mermaid-label-bg-color);opacity:1}.relationshipLabel{fill:var(--md-mermaid-label-fg-color)}.relationshipLine{stroke:var(--md-mermaid-edge-color)}defs #ONE_OR_MORE_END *,defs #ONE_OR_MORE_START *,defs #ONLY_ONE_END *,defs #ONLY_ONE_START *,defs #ZERO_OR_MORE_END *,defs #ZERO_OR_MORE_START *,defs #ZERO_OR_ONE_END *,defs #ZERO_OR_ONE_START *{stroke:var(--md-mermaid-edge-color)!important}defs #ZERO_OR_MORE_END circle,defs #ZERO_OR_MORE_START circle{fill:var(--md-mermaid-label-bg-color)}.actor{fill:var(--md-mermaid-sequence-actor-bg-color);stroke:var(--md-mermaid-sequence-actor-border-color)}text.actor>tspan{fill:var(--md-mermaid-sequence-actor-fg-color);font-family:var(--md-mermaid-font-family)}line{stroke:var(--md-mermaid-sequence-actor-line-color)}.actor-man circle,.actor-man line{fill:var(--md-mermaid-sequence-actorman-bg-color);stroke:var(--md-mermaid-sequence-actorman-line-color)}.messageLine0,.messageLine1{stroke:var(--md-mermaid-sequence-message-line-color)}.note{fill:var(--md-mermaid-sequence-note-bg-color);stroke:var(--md-mermaid-sequence-note-border-color)}.loopText,.loopText>tspan,.messageText,.noteText>tspan{stroke:none;font-family:var(--md-mermaid-font-family)!important}.messageText{fill:var(--md-mermaid-sequence-message-fg-color)}.loopText,.loopText>tspan{fill:var(--md-mermaid-sequence-loop-fg-color)}.noteText>tspan{fill:var(--md-mermaid-sequence-note-fg-color)}#arrowhead path{fill:var(--md-mermaid-sequence-message-line-color);stroke:none}.loopLine{fill:var(--md-mermaid-sequence-loop-bg-color);stroke:var(--md-mermaid-sequence-loop-border-color)}.labelBox{fill:var(--md-mermaid-sequence-label-bg-color);stroke:none}.labelText,.labelText>span{fill:var(--md-mermaid-sequence-label-fg-color);font-family:var(--md-mermaid-font-family)}.sequenceNumber{fill:var(--md-mermaid-sequence-number-fg-color)}rect.rect{fill:var(--md-mermaid-sequence-box-bg-color);stroke:none}rect.rect+text.text{fill:var(--md-mermaid-sequence-box-fg-color)}defs #sequencenumber{fill:var(--md-mermaid-sequence-number-bg-color)!important}";var qr,ka=0;function Ha(){return typeof mermaid=="undefined"||mermaid instanceof Element?gt("https://unpkg.com/mermaid@10.7.0/dist/mermaid.min.js"):$(void 0)}function _n(e){return e.classList.remove("mermaid"),qr||(qr=Ha().pipe(y(()=>mermaid.initialize({startOnLoad:!1,themeCSS:Ln,sequence:{actorFontSize:"16px",messageFontSize:"16px",noteFontSize:"16px"}})),m(()=>{}),B(1))),qr.subscribe(()=>ro(this,null,function*(){e.classList.add("mermaid");let t=`__mermaid_${ka++}`,r=E("div",{class:"mermaid"}),o=e.textContent,{svg:n,fn:i}=yield mermaid.render(t,o),s=r.attachShadow({mode:"closed"});s.innerHTML=n,e.replaceWith(r),i==null||i(s)})),qr.pipe(m(()=>({ref:e})))}var An=E("table");function Cn(e){return e.replaceWith(An),An.replaceWith(vn(e)),$({ref:e})}function $a(e){let t=e.find(r=>r.checked)||e[0];return T(...e.map(r=>d(r,"change").pipe(m(()=>P(`label[for="${r.id}"]`))))).pipe(q(P(`label[for="${t.id}"]`)),m(r=>({active:r})))}function kn(e,{viewport$:t,target$:r}){let o=P(".tabbed-labels",e),n=R(":scope > input",e),i=Nr("prev");e.append(i);let s=Nr("next");return e.append(s),H(()=>{let a=new v,c=a.pipe(ee(),oe(!0));Q([a,Ee(e)]).pipe(U(c),Me(1,de)).subscribe({next([{active:p},l]){let f=Ue(p),{width:u}=pe(p);e.style.setProperty("--md-indicator-x",`${f.x}px`),e.style.setProperty("--md-indicator-width",`${u}px`);let h=ir(o);(f.xh.x+l.width)&&o.scrollTo({left:Math.max(0,f.x-16),behavior:"smooth"})},complete(){e.style.removeProperty("--md-indicator-x"),e.style.removeProperty("--md-indicator-width")}}),Q([et(o),Ee(o)]).pipe(U(c)).subscribe(([p,l])=>{let f=xt(o);i.hidden=p.x<16,s.hidden=p.x>f.width-l.width-16}),T(d(i,"click").pipe(m(()=>-1)),d(s,"click").pipe(m(()=>1))).pipe(U(c)).subscribe(p=>{let{width:l}=pe(o);o.scrollBy({left:l*p,behavior:"smooth"})}),r.pipe(U(c),g(p=>n.includes(p))).subscribe(p=>p.click()),o.classList.add("tabbed-labels--linked");for(let p of n){let l=P(`label[for="${p.id}"]`);l.replaceChildren(E("a",{href:`#${l.htmlFor}`,tabIndex:-1},...Array.from(l.childNodes))),d(l.firstElementChild,"click").pipe(U(c),g(f=>!(f.metaKey||f.ctrlKey)),y(f=>{f.preventDefault(),f.stopPropagation()})).subscribe(()=>{history.replaceState({},"",`#${l.htmlFor}`),l.click()})}return G("content.tabs.link")&&a.pipe(Le(1),ae(t)).subscribe(([{active:p},{offset:l}])=>{let f=p.innerText.trim();if(p.hasAttribute("data-md-switching"))p.removeAttribute("data-md-switching");else{let u=e.offsetTop-l.y;for(let w of R("[data-tabs]"))for(let A of R(":scope > input",w)){let Z=P(`label[for="${A.id}"]`);if(Z!==p&&Z.innerText.trim()===f){Z.setAttribute("data-md-switching",""),A.click();break}}window.scrollTo({top:e.offsetTop-u});let h=__md_get("__tabs")||[];__md_set("__tabs",[...new Set([f,...h])])}}),a.pipe(U(c)).subscribe(()=>{for(let p of R("audio, video",e))p.pause()}),$a(n).pipe(y(p=>a.next(p)),_(()=>a.complete()),m(p=>F({ref:e},p)))}).pipe(ze(ie))}function Hn(e,{viewport$:t,target$:r,print$:o}){return T(...R(".annotate:not(.highlight)",e).map(n=>wn(n,{target$:r,print$:o})),...R("pre:not(.mermaid) > code",e).map(n=>On(n,{target$:r,print$:o})),...R("pre.mermaid",e).map(n=>_n(n)),...R("table:not([class])",e).map(n=>Cn(n)),...R("details",e).map(n=>Mn(n,{target$:r,print$:o})),...R("[data-tabs]",e).map(n=>kn(n,{viewport$:t,target$:r})),...R("[title]",e).filter(()=>G("content.tooltips")).map(n=>Ge(n)))}function Ra(e,{alert$:t}){return t.pipe(b(r=>T($(!0),$(!1).pipe(Ye(2e3))).pipe(m(o=>({message:r,active:o})))))}function $n(e,t){let r=P(".md-typeset",e);return H(()=>{let o=new v;return o.subscribe(({message:n,active:i})=>{e.classList.toggle("md-dialog--active",i),r.textContent=n}),Ra(e,t).pipe(y(n=>o.next(n)),_(()=>o.complete()),m(n=>F({ref:e},n)))})}function Pa({viewport$:e}){if(!G("header.autohide"))return $(!1);let t=e.pipe(m(({offset:{y:n}})=>n),Ke(2,1),m(([n,i])=>[nMath.abs(i-n.y)>100),m(([,[n]])=>n),Y()),o=We("search");return Q([e,o]).pipe(m(([{offset:n},i])=>n.y>400&&!i),Y(),b(n=>n?r:$(!1)),q(!1))}function Rn(e,t){return H(()=>Q([Ee(e),Pa(t)])).pipe(m(([{height:r},o])=>({height:r,hidden:o})),Y((r,o)=>r.height===o.height&&r.hidden===o.hidden),B(1))}function Pn(e,{header$:t,main$:r}){return H(()=>{let o=new v,n=o.pipe(ee(),oe(!0));o.pipe(X("active"),je(t)).subscribe(([{active:s},{hidden:a}])=>{e.classList.toggle("md-header--shadow",s&&!a),e.hidden=a});let i=fe(R("[title]",e)).pipe(g(()=>G("content.tooltips")),re(s=>Ge(s)));return r.subscribe(o),t.pipe(U(n),m(s=>F({ref:e},s)),$e(i.pipe(U(n))))})}function Ia(e,{viewport$:t,header$:r}){return pr(e,{viewport$:t,header$:r}).pipe(m(({offset:{y:o}})=>{let{height:n}=pe(e);return{active:o>=n}}),X("active"))}function In(e,t){return H(()=>{let r=new v;r.subscribe({next({active:n}){e.classList.toggle("md-header__title--active",n)},complete(){e.classList.remove("md-header__title--active")}});let o=me(".md-content h1");return typeof o=="undefined"?L:Ia(o,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))})}function Fn(e,{viewport$:t,header$:r}){let o=r.pipe(m(({height:i})=>i),Y()),n=o.pipe(b(()=>Ee(e).pipe(m(({height:i})=>({top:e.offsetTop,bottom:e.offsetTop+i})),X("bottom"))));return Q([o,n,t]).pipe(m(([i,{top:s,bottom:a},{offset:{y:c},size:{height:p}}])=>(p=Math.max(0,p-Math.max(0,s-c,i)-Math.max(0,p+c-a)),{offset:s-i,height:p,active:s-i<=c})),Y((i,s)=>i.offset===s.offset&&i.height===s.height&&i.active===s.active))}function Fa(e){let t=__md_get("__palette")||{index:e.findIndex(o=>matchMedia(o.getAttribute("data-md-color-media")).matches)},r=Math.max(0,Math.min(t.index,e.length-1));return $(...e).pipe(re(o=>d(o,"change").pipe(m(()=>o))),q(e[r]),m(o=>({index:e.indexOf(o),color:{media:o.getAttribute("data-md-color-media"),scheme:o.getAttribute("data-md-color-scheme"),primary:o.getAttribute("data-md-color-primary"),accent:o.getAttribute("data-md-color-accent")}})),B(1))}function jn(e){let t=R("input",e),r=E("meta",{name:"theme-color"});document.head.appendChild(r);let o=E("meta",{name:"color-scheme"});document.head.appendChild(o);let n=At("(prefers-color-scheme: light)");return H(()=>{let i=new v;return i.subscribe(s=>{if(document.body.setAttribute("data-md-color-switching",""),s.color.media==="(prefers-color-scheme)"){let a=matchMedia("(prefers-color-scheme: light)"),c=document.querySelector(a.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");s.color.scheme=c.getAttribute("data-md-color-scheme"),s.color.primary=c.getAttribute("data-md-color-primary"),s.color.accent=c.getAttribute("data-md-color-accent")}for(let[a,c]of Object.entries(s.color))document.body.setAttribute(`data-md-color-${a}`,c);for(let a=0;a{let s=Te("header"),a=window.getComputedStyle(s);return o.content=a.colorScheme,a.backgroundColor.match(/\d+/g).map(c=>(+c).toString(16).padStart(2,"0")).join("")})).subscribe(s=>r.content=`#${s}`),i.pipe(Oe(ie)).subscribe(()=>{document.body.removeAttribute("data-md-color-switching")}),Fa(t).pipe(U(n.pipe(Le(1))),at(),y(s=>i.next(s)),_(()=>i.complete()),m(s=>F({ref:e},s)))})}function Un(e,{progress$:t}){return H(()=>{let r=new v;return r.subscribe(({value:o})=>{e.style.setProperty("--md-progress-value",`${o}`)}),t.pipe(y(o=>r.next({value:o})),_(()=>r.complete()),m(o=>({ref:e,value:o})))})}var Kr=jt(zr());function ja(e){e.setAttribute("data-md-copying","");let t=e.closest("[data-copy]"),r=t?t.getAttribute("data-copy"):e.innerText;return e.removeAttribute("data-md-copying"),r.trimEnd()}function Wn({alert$:e}){Kr.default.isSupported()&&new j(t=>{new Kr.default("[data-clipboard-target], [data-clipboard-text]",{text:r=>r.getAttribute("data-clipboard-text")||ja(P(r.getAttribute("data-clipboard-target")))}).on("success",r=>t.next(r))}).pipe(y(t=>{t.trigger.focus()}),m(()=>ge("clipboard.copied"))).subscribe(e)}function Dn(e,t){return e.protocol=t.protocol,e.hostname=t.hostname,e}function Ua(e,t){let r=new Map;for(let o of R("url",e)){let n=P("loc",o),i=[Dn(new URL(n.textContent),t)];r.set(`${i[0]}`,i);for(let s of R("[rel=alternate]",o)){let a=s.getAttribute("href");a!=null&&i.push(Dn(new URL(a),t))}}return r}function mr(e){return on(new URL("sitemap.xml",e)).pipe(m(t=>Ua(t,new URL(e))),he(()=>$(new Map)))}function Wa(e,t){if(!(e.target instanceof Element))return L;let r=e.target.closest("a");if(r===null)return L;if(r.target||e.metaKey||e.ctrlKey)return L;let o=new URL(r.href);return o.search=o.hash="",t.has(`${o}`)?(e.preventDefault(),$(new URL(r.href))):L}function Nn(e){let t=new Map;for(let r of R(":scope > *",e.head))t.set(r.outerHTML,r);return t}function Vn(e){for(let t of R("[href], [src]",e))for(let r of["href","src"]){let o=t.getAttribute(r);if(o&&!/^(?:[a-z]+:)?\/\//i.test(o)){t[r]=t[r];break}}return $(e)}function Da(e){for(let o of["[data-md-component=announce]","[data-md-component=container]","[data-md-component=header-topic]","[data-md-component=outdated]","[data-md-component=logo]","[data-md-component=skip]",...G("navigation.tabs.sticky")?["[data-md-component=tabs]"]:[]]){let n=me(o),i=me(o,e);typeof n!="undefined"&&typeof i!="undefined"&&n.replaceWith(i)}let t=Nn(document);for(let[o,n]of Nn(e))t.has(o)?t.delete(o):document.head.appendChild(n);for(let o of t.values()){let n=o.getAttribute("name");n!=="theme-color"&&n!=="color-scheme"&&o.remove()}let r=Te("container");return Fe(R("script",r)).pipe(b(o=>{let n=e.createElement("script");if(o.src){for(let i of o.getAttributeNames())n.setAttribute(i,o.getAttribute(i));return o.replaceWith(n),new j(i=>{n.onload=()=>i.complete()})}else return n.textContent=o.textContent,o.replaceWith(n),L}),ee(),oe(document))}function zn({location$:e,viewport$:t,progress$:r}){let o=we();if(location.protocol==="file:")return L;let n=mr(o.base);$(document).subscribe(Vn);let i=d(document.body,"click").pipe(je(n),b(([c,p])=>Wa(c,p)),le()),s=d(window,"popstate").pipe(m(ve),le());i.pipe(ae(t)).subscribe(([c,{offset:p}])=>{history.replaceState(p,""),history.pushState(null,"",c)}),T(i,s).subscribe(e);let a=e.pipe(X("pathname"),b(c=>rn(c,{progress$:r}).pipe(he(()=>(st(c,!0),L)))),b(Vn),b(Da),le());return T(a.pipe(ae(e,(c,p)=>p)),e.pipe(X("pathname"),b(()=>e),X("hash")),e.pipe(Y((c,p)=>c.pathname===p.pathname&&c.hash===p.hash),b(()=>i),y(()=>history.back()))).subscribe(c=>{var p,l;history.state!==null||!c.hash?window.scrollTo(0,(l=(p=history.state)==null?void 0:p.y)!=null?l:0):(history.scrollRestoration="auto",Zo(c.hash),history.scrollRestoration="manual")}),e.subscribe(()=>{history.scrollRestoration="manual"}),d(window,"beforeunload").subscribe(()=>{history.scrollRestoration="auto"}),t.pipe(X("offset"),be(100)).subscribe(({offset:c})=>{history.replaceState(c,"")}),a}var Qn=jt(Kn());function Yn(e){let t=e.separator.split("|").map(n=>n.replace(/(\(\?[!=<][^)]+\))/g,"").length===0?"\uFFFD":n).join("|"),r=new RegExp(t,"img"),o=(n,i,s)=>`${i}${s}`;return n=>{n=n.replace(/[\s*+\-:~^]+/g," ").trim();let i=new RegExp(`(^|${e.separator}|)(${n.replace(/[|\\{}()[\]^$+*?.-]/g,"\\$&").replace(r,"|")})`,"img");return s=>(0,Qn.default)(s).replace(i,o).replace(/<\/mark>(\s+)]*>/img,"$1")}}function Ht(e){return e.type===1}function fr(e){return e.type===3}function Bn(e,t){let r=ln(e);return T($(location.protocol!=="file:"),We("search")).pipe(He(o=>o),b(()=>t)).subscribe(({config:o,docs:n})=>r.next({type:0,data:{config:o,docs:n,options:{suggest:G("search.suggest")}}})),r}function Gn({document$:e}){let t=we(),r=De(new URL("../versions.json",t.base)).pipe(he(()=>L)),o=r.pipe(m(n=>{let[,i]=t.base.match(/([^/]+)\/?$/);return n.find(({version:s,aliases:a})=>s===i||a.includes(i))||n[0]}));r.pipe(m(n=>new Map(n.map(i=>[`${new URL(`../${i.version}/`,t.base)}`,i]))),b(n=>d(document.body,"click").pipe(g(i=>!i.metaKey&&!i.ctrlKey),ae(o),b(([i,s])=>{if(i.target instanceof Element){let a=i.target.closest("a");if(a&&!a.target&&n.has(a.href)){let c=a.href;return!i.target.closest(".md-version")&&n.get(c)===s?L:(i.preventDefault(),$(c))}}return L}),b(i=>{let{version:s}=n.get(i);return mr(new URL(i)).pipe(m(a=>{let p=ve().href.replace(t.base,"");return a.has(p.split("#")[0])?new URL(`../${s}/${p}`,t.base):new URL(i)}))})))).subscribe(n=>st(n,!0)),Q([r,o]).subscribe(([n,i])=>{P(".md-header__topic").appendChild(gn(n,i))}),e.pipe(b(()=>o)).subscribe(n=>{var s;let i=__md_get("__outdated",sessionStorage);if(i===null){i=!0;let a=((s=t.version)==null?void 0:s.default)||"latest";Array.isArray(a)||(a=[a]);e:for(let c of a)for(let p of n.aliases.concat(n.version))if(new RegExp(c,"i").test(p)){i=!1;break e}__md_set("__outdated",i,sessionStorage)}if(i)for(let a of ne("outdated"))a.hidden=!1})}function Ka(e,{worker$:t}){let{searchParams:r}=ve();r.has("q")&&(Be("search",!0),e.value=r.get("q"),e.focus(),We("search").pipe(He(i=>!i)).subscribe(()=>{let i=ve();i.searchParams.delete("q"),history.replaceState({},"",`${i}`)}));let o=vt(e),n=T(t.pipe(He(Ht)),d(e,"keyup"),o).pipe(m(()=>e.value),Y());return Q([n,o]).pipe(m(([i,s])=>({value:i,focus:s})),B(1))}function Jn(e,{worker$:t}){let r=new v,o=r.pipe(ee(),oe(!0));Q([t.pipe(He(Ht)),r],(i,s)=>s).pipe(X("value")).subscribe(({value:i})=>t.next({type:2,data:i})),r.pipe(X("focus")).subscribe(({focus:i})=>{i&&Be("search",i)}),d(e.form,"reset").pipe(U(o)).subscribe(()=>e.focus());let n=P("header [for=__search]");return d(n,"click").subscribe(()=>e.focus()),Ka(e,{worker$:t}).pipe(y(i=>r.next(i)),_(()=>r.complete()),m(i=>F({ref:e},i)),B(1))}function Xn(e,{worker$:t,query$:r}){let o=new v,n=Yo(e.parentElement).pipe(g(Boolean)),i=e.parentElement,s=P(":scope > :first-child",e),a=P(":scope > :last-child",e);We("search").subscribe(l=>a.setAttribute("role",l?"list":"presentation")),o.pipe(ae(r),Ir(t.pipe(He(Ht)))).subscribe(([{items:l},{value:f}])=>{switch(l.length){case 0:s.textContent=f.length?ge("search.result.none"):ge("search.result.placeholder");break;case 1:s.textContent=ge("search.result.one");break;default:let u=ar(l.length);s.textContent=ge("search.result.other",u)}});let c=o.pipe(y(()=>a.innerHTML=""),b(({items:l})=>T($(...l.slice(0,10)),$(...l.slice(10)).pipe(Ke(4),jr(n),b(([f])=>f)))),m(hn),le());return c.subscribe(l=>a.appendChild(l)),c.pipe(re(l=>{let f=me("details",l);return typeof f=="undefined"?L:d(f,"toggle").pipe(U(o),m(()=>f))})).subscribe(l=>{l.open===!1&&l.offsetTop<=i.scrollTop&&i.scrollTo({top:l.offsetTop})}),t.pipe(g(fr),m(({data:l})=>l)).pipe(y(l=>o.next(l)),_(()=>o.complete()),m(l=>F({ref:e},l)))}function Qa(e,{query$:t}){return t.pipe(m(({value:r})=>{let o=ve();return o.hash="",r=r.replace(/\s+/g,"+").replace(/&/g,"%26").replace(/=/g,"%3D"),o.search=`q=${r}`,{url:o}}))}function Zn(e,t){let r=new v,o=r.pipe(ee(),oe(!0));return r.subscribe(({url:n})=>{e.setAttribute("data-clipboard-text",e.href),e.href=`${n}`}),d(e,"click").pipe(U(o)).subscribe(n=>n.preventDefault()),Qa(e,t).pipe(y(n=>r.next(n)),_(()=>r.complete()),m(n=>F({ref:e},n)))}function ei(e,{worker$:t,keyboard$:r}){let o=new v,n=Te("search-query"),i=T(d(n,"keydown"),d(n,"focus")).pipe(Oe(ie),m(()=>n.value),Y());return o.pipe(je(i),m(([{suggest:a},c])=>{let p=c.split(/([\s-]+)/);if(a!=null&&a.length&&p[p.length-1]){let l=a[a.length-1];l.startsWith(p[p.length-1])&&(p[p.length-1]=l)}else p.length=0;return p})).subscribe(a=>e.innerHTML=a.join("").replace(/\s/g," ")),r.pipe(g(({mode:a})=>a==="search")).subscribe(a=>{switch(a.type){case"ArrowRight":e.innerText.length&&n.selectionStart===n.value.length&&(n.value=e.innerText);break}}),t.pipe(g(fr),m(({data:a})=>a)).pipe(y(a=>o.next(a)),_(()=>o.complete()),m(()=>({ref:e})))}function ti(e,{index$:t,keyboard$:r}){let o=we();try{let n=Bn(o.search,t),i=Te("search-query",e),s=Te("search-result",e);d(e,"click").pipe(g(({target:c})=>c instanceof Element&&!!c.closest("a"))).subscribe(()=>Be("search",!1)),r.pipe(g(({mode:c})=>c==="search")).subscribe(c=>{let p=Re();switch(c.type){case"Enter":if(p===i){let l=new Map;for(let f of R(":first-child [href]",s)){let u=f.firstElementChild;l.set(f,parseFloat(u.getAttribute("data-md-score")))}if(l.size){let[[f]]=[...l].sort(([,u],[,h])=>h-u);f.click()}c.claim()}break;case"Escape":case"Tab":Be("search",!1),i.blur();break;case"ArrowUp":case"ArrowDown":if(typeof p=="undefined")i.focus();else{let l=[i,...R(":not(details) > [href], summary, details[open] [href]",s)],f=Math.max(0,(Math.max(0,l.indexOf(p))+l.length+(c.type==="ArrowUp"?-1:1))%l.length);l[f].focus()}c.claim();break;default:i!==Re()&&i.focus()}}),r.pipe(g(({mode:c})=>c==="global")).subscribe(c=>{switch(c.type){case"f":case"s":case"/":i.focus(),i.select(),c.claim();break}});let a=Jn(i,{worker$:n});return T(a,Xn(s,{worker$:n,query$:a})).pipe($e(...ne("search-share",e).map(c=>Zn(c,{query$:a})),...ne("search-suggest",e).map(c=>ei(c,{worker$:n,keyboard$:r}))))}catch(n){return e.hidden=!0,qe}}function ri(e,{index$:t,location$:r}){return Q([t,r.pipe(q(ve()),g(o=>!!o.searchParams.get("h")))]).pipe(m(([o,n])=>Yn(o.config)(n.searchParams.get("h"))),m(o=>{var s;let n=new Map,i=document.createNodeIterator(e,NodeFilter.SHOW_TEXT);for(let a=i.nextNode();a;a=i.nextNode())if((s=a.parentElement)!=null&&s.offsetHeight){let c=a.textContent,p=o(c);p.length>c.length&&n.set(a,p)}for(let[a,c]of n){let{childNodes:p}=E("span",null,c);a.replaceWith(...Array.from(p))}return{ref:e,nodes:n}}))}function Ya(e,{viewport$:t,main$:r}){let o=e.closest(".md-grid"),n=o.offsetTop-o.parentElement.offsetTop;return Q([r,t]).pipe(m(([{offset:i,height:s},{offset:{y:a}}])=>(s=s+Math.min(n,Math.max(0,a-i))-n,{height:s,locked:a>=i+n})),Y((i,s)=>i.height===s.height&&i.locked===s.locked))}function Qr(e,o){var n=o,{header$:t}=n,r=to(n,["header$"]);let i=P(".md-sidebar__scrollwrap",e),{y:s}=Ue(i);return H(()=>{let a=new v,c=a.pipe(ee(),oe(!0)),p=a.pipe(Me(0,de));return p.pipe(ae(t)).subscribe({next([{height:l},{height:f}]){i.style.height=`${l-2*s}px`,e.style.top=`${f}px`},complete(){i.style.height="",e.style.top=""}}),p.pipe(He()).subscribe(()=>{for(let l of R(".md-nav__link--active[href]",e)){if(!l.clientHeight)continue;let f=l.closest(".md-sidebar__scrollwrap");if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2})}}}),fe(R("label[tabindex]",e)).pipe(re(l=>d(l,"click").pipe(Oe(ie),m(()=>l),U(c)))).subscribe(l=>{let f=P(`[id="${l.htmlFor}"]`);P(`[aria-labelledby="${l.id}"]`).setAttribute("aria-expanded",`${f.checked}`)}),Ya(e,r).pipe(y(l=>a.next(l)),_(()=>a.complete()),m(l=>F({ref:e},l)))})}function oi(e,t){if(typeof t!="undefined"){let r=`https://api.github.com/repos/${e}/${t}`;return Lt(De(`${r}/releases/latest`).pipe(he(()=>L),m(o=>({version:o.tag_name})),Qe({})),De(r).pipe(he(()=>L),m(o=>({stars:o.stargazers_count,forks:o.forks_count})),Qe({}))).pipe(m(([o,n])=>F(F({},o),n)))}else{let r=`https://api.github.com/users/${e}`;return De(r).pipe(m(o=>({repositories:o.public_repos})),Qe({}))}}function ni(e,t){let r=`https://${e}/api/v4/projects/${encodeURIComponent(t)}`;return De(r).pipe(he(()=>L),m(({star_count:o,forks_count:n})=>({stars:o,forks:n})),Qe({}))}function ii(e){let t=e.match(/^.+github\.com\/([^/]+)\/?([^/]+)?/i);if(t){let[,r,o]=t;return oi(r,o)}if(t=e.match(/^.+?([^/]*gitlab[^/]+)\/(.+?)\/?$/i),t){let[,r,o]=t;return ni(r,o)}return L}var Ba;function Ga(e){return Ba||(Ba=H(()=>{let t=__md_get("__source",sessionStorage);if(t)return $(t);if(ne("consent").length){let o=__md_get("__consent");if(!(o&&o.github))return L}return ii(e.href).pipe(y(o=>__md_set("__source",o,sessionStorage)))}).pipe(he(()=>L),g(t=>Object.keys(t).length>0),m(t=>({facts:t})),B(1)))}function ai(e){let t=P(":scope > :last-child",e);return H(()=>{let r=new v;return r.subscribe(({facts:o})=>{t.appendChild(bn(o)),t.classList.add("md-source__repository--active")}),Ga(e).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Ja(e,{viewport$:t,header$:r}){return Ee(document.body).pipe(b(()=>pr(e,{header$:r,viewport$:t})),m(({offset:{y:o}})=>({hidden:o>=10})),X("hidden"))}function si(e,t){return H(()=>{let r=new v;return r.subscribe({next({hidden:o}){e.hidden=o},complete(){e.hidden=!1}}),(G("navigation.tabs.sticky")?$({hidden:!1}):Ja(e,t)).pipe(y(o=>r.next(o)),_(()=>r.complete()),m(o=>F({ref:e},o)))})}function Xa(e,{viewport$:t,header$:r}){let o=new Map,n=R(".md-nav__link",e);for(let a of n){let c=decodeURIComponent(a.hash.substring(1)),p=me(`[id="${c}"]`);typeof p!="undefined"&&o.set(a,p)}let i=r.pipe(X("height"),m(({height:a})=>{let c=Te("main"),p=P(":scope > :first-child",c);return a+.8*(p.offsetTop-c.offsetTop)}),le());return Ee(document.body).pipe(X("height"),b(a=>H(()=>{let c=[];return $([...o].reduce((p,[l,f])=>{for(;c.length&&o.get(c[c.length-1]).tagName>=f.tagName;)c.pop();let u=f.offsetTop;for(;!u&&f.parentElement;)f=f.parentElement,u=f.offsetTop;let h=f.offsetParent;for(;h;h=h.offsetParent)u+=h.offsetTop;return p.set([...c=[...c,l]].reverse(),u)},new Map))}).pipe(m(c=>new Map([...c].sort(([,p],[,l])=>p-l))),je(i),b(([c,p])=>t.pipe(Rr(([l,f],{offset:{y:u},size:h})=>{let w=u+h.height>=Math.floor(a.height);for(;f.length;){let[,A]=f[0];if(A-p=u&&!w)f=[l.pop(),...f];else break}return[l,f]},[[],[...c]]),Y((l,f)=>l[0]===f[0]&&l[1]===f[1])))))).pipe(m(([a,c])=>({prev:a.map(([p])=>p),next:c.map(([p])=>p)})),q({prev:[],next:[]}),Ke(2,1),m(([a,c])=>a.prev.length{let i=new v,s=i.pipe(ee(),oe(!0));if(i.subscribe(({prev:a,next:c})=>{for(let[p]of c)p.classList.remove("md-nav__link--passed"),p.classList.remove("md-nav__link--active");for(let[p,[l]]of a.entries())l.classList.add("md-nav__link--passed"),l.classList.toggle("md-nav__link--active",p===a.length-1)}),G("toc.follow")){let a=T(t.pipe(be(1),m(()=>{})),t.pipe(be(250),m(()=>"smooth")));i.pipe(g(({prev:c})=>c.length>0),je(o.pipe(Oe(ie))),ae(a)).subscribe(([[{prev:c}],p])=>{let[l]=c[c.length-1];if(l.offsetHeight){let f=sr(l);if(typeof f!="undefined"){let u=l.offsetTop-f.offsetTop,{height:h}=pe(f);f.scrollTo({top:u-h/2,behavior:p})}}})}return G("navigation.tracking")&&t.pipe(U(s),X("offset"),be(250),Le(1),U(n.pipe(Le(1))),at({delay:250}),ae(i)).subscribe(([,{prev:a}])=>{let c=ve(),p=a[a.length-1];if(p&&p.length){let[l]=p,{hash:f}=new URL(l.href);c.hash!==f&&(c.hash=f,history.replaceState({},"",`${c}`))}else c.hash="",history.replaceState({},"",`${c}`)}),Xa(e,{viewport$:t,header$:r}).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))})}function Za(e,{viewport$:t,main$:r,target$:o}){let n=t.pipe(m(({offset:{y:s}})=>s),Ke(2,1),m(([s,a])=>s>a&&a>0),Y()),i=r.pipe(m(({active:s})=>s));return Q([i,n]).pipe(m(([s,a])=>!(s&&a)),Y(),U(o.pipe(Le(1))),oe(!0),at({delay:250}),m(s=>({hidden:s})))}function pi(e,{viewport$:t,header$:r,main$:o,target$:n}){let i=new v,s=i.pipe(ee(),oe(!0));return i.subscribe({next({hidden:a}){e.hidden=a,a?(e.setAttribute("tabindex","-1"),e.blur()):e.removeAttribute("tabindex")},complete(){e.style.top="",e.hidden=!0,e.removeAttribute("tabindex")}}),r.pipe(U(s),X("height")).subscribe(({height:a})=>{e.style.top=`${a+16}px`}),d(e,"click").subscribe(a=>{a.preventDefault(),window.scrollTo({top:0})}),Za(e,{viewport$:t,main$:o,target$:n}).pipe(y(a=>i.next(a)),_(()=>i.complete()),m(a=>F({ref:e},a)))}function li({document$:e}){e.pipe(b(()=>R(".md-ellipsis")),re(t=>yt(t).pipe(U(e.pipe(Le(1))),g(r=>r),m(()=>t),ye(1))),g(t=>t.offsetWidth{let r=t.innerText,o=t.closest("a")||t;return o.title=r,Ge(o).pipe(U(e.pipe(Le(1))),_(()=>o.removeAttribute("title")))})).subscribe(),e.pipe(b(()=>R(".md-status")),re(t=>Ge(t))).subscribe()}function mi({document$:e,tablet$:t}){e.pipe(b(()=>R(".md-toggle--indeterminate")),y(r=>{r.indeterminate=!0,r.checked=!1}),re(r=>d(r,"change").pipe(Fr(()=>r.classList.contains("md-toggle--indeterminate")),m(()=>r))),ae(t)).subscribe(([r,o])=>{r.classList.remove("md-toggle--indeterminate"),o&&(r.checked=!1)})}function es(){return/(iPad|iPhone|iPod)/.test(navigator.userAgent)}function fi({document$:e}){e.pipe(b(()=>R("[data-md-scrollfix]")),y(t=>t.removeAttribute("data-md-scrollfix")),g(es),re(t=>d(t,"touchstart").pipe(m(()=>t)))).subscribe(t=>{let r=t.scrollTop;r===0?t.scrollTop=1:r+t.offsetHeight===t.scrollHeight&&(t.scrollTop=r-1)})}function ui({viewport$:e,tablet$:t}){Q([We("search"),t]).pipe(m(([r,o])=>r&&!o),b(r=>$(r).pipe(Ye(r?400:100))),ae(e)).subscribe(([r,{offset:{y:o}}])=>{if(r)document.body.setAttribute("data-md-scrolllock",""),document.body.style.top=`-${o}px`;else{let n=-1*parseInt(document.body.style.top,10);document.body.removeAttribute("data-md-scrolllock"),document.body.style.top="",n&&window.scrollTo(0,n)}})}Object.entries||(Object.entries=function(e){let t=[];for(let r of Object.keys(e))t.push([r,e[r]]);return t});Object.values||(Object.values=function(e){let t=[];for(let r of Object.keys(e))t.push(e[r]);return t});typeof Element!="undefined"&&(Element.prototype.scrollTo||(Element.prototype.scrollTo=function(e,t){typeof e=="object"?(this.scrollLeft=e.left,this.scrollTop=e.top):(this.scrollLeft=e,this.scrollTop=t)}),Element.prototype.replaceWith||(Element.prototype.replaceWith=function(...e){let t=this.parentNode;if(t){e.length===0&&t.removeChild(this);for(let r=e.length-1;r>=0;r--){let o=e[r];typeof o=="string"?o=document.createTextNode(o):o.parentNode&&o.parentNode.removeChild(o),r?t.insertBefore(this.previousSibling,o):t.replaceChild(o,this)}}}));function ts(){return location.protocol==="file:"?gt(`${new URL("search/search_index.js",Yr.base)}`).pipe(m(()=>__index),B(1)):De(new URL("search/search_index.json",Yr.base))}document.documentElement.classList.remove("no-js");document.documentElement.classList.add("js");var rt=No(),Rt=Jo(),wt=en(Rt),Br=Go(),_e=pn(),ur=At("(min-width: 960px)"),hi=At("(min-width: 1220px)"),bi=tn(),Yr=we(),vi=document.forms.namedItem("search")?ts():qe,Gr=new v;Wn({alert$:Gr});var Jr=new v;G("navigation.instant")&&zn({location$:Rt,viewport$:_e,progress$:Jr}).subscribe(rt);var di;((di=Yr.version)==null?void 0:di.provider)==="mike"&&Gn({document$:rt});T(Rt,wt).pipe(Ye(125)).subscribe(()=>{Be("drawer",!1),Be("search",!1)});Br.pipe(g(({mode:e})=>e==="global")).subscribe(e=>{switch(e.type){case"p":case",":let t=me("link[rel=prev]");typeof t!="undefined"&&st(t);break;case"n":case".":let r=me("link[rel=next]");typeof r!="undefined"&&st(r);break;case"Enter":let o=Re();o instanceof HTMLLabelElement&&o.click()}});li({document$:rt});mi({document$:rt,tablet$:ur});fi({document$:rt});ui({viewport$:_e,tablet$:ur});var tt=Rn(Te("header"),{viewport$:_e}),$t=rt.pipe(m(()=>Te("main")),b(e=>Fn(e,{viewport$:_e,header$:tt})),B(1)),rs=T(...ne("consent").map(e=>fn(e,{target$:wt})),...ne("dialog").map(e=>$n(e,{alert$:Gr})),...ne("header").map(e=>Pn(e,{viewport$:_e,header$:tt,main$:$t})),...ne("palette").map(e=>jn(e)),...ne("progress").map(e=>Un(e,{progress$:Jr})),...ne("search").map(e=>ti(e,{index$:vi,keyboard$:Br})),...ne("source").map(e=>ai(e))),os=H(()=>T(...ne("announce").map(e=>mn(e)),...ne("content").map(e=>Hn(e,{viewport$:_e,target$:wt,print$:bi})),...ne("content").map(e=>G("search.highlight")?ri(e,{index$:vi,location$:Rt}):L),...ne("header-title").map(e=>In(e,{viewport$:_e,header$:tt})),...ne("sidebar").map(e=>e.getAttribute("data-md-type")==="navigation"?Ur(hi,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t})):Ur(ur,()=>Qr(e,{viewport$:_e,header$:tt,main$:$t}))),...ne("tabs").map(e=>si(e,{viewport$:_e,header$:tt})),...ne("toc").map(e=>ci(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})),...ne("top").map(e=>pi(e,{viewport$:_e,header$:tt,main$:$t,target$:wt})))),gi=rt.pipe(b(()=>os),$e(rs),B(1));gi.subscribe();window.document$=rt;window.location$=Rt;window.target$=wt;window.keyboard$=Br;window.viewport$=_e;window.tablet$=ur;window.screen$=hi;window.print$=bi;window.alert$=Gr;window.progress$=Jr;window.component$=gi;})(); +//# sourceMappingURL=bundle.bd41221c.min.js.map + diff --git a/assets/javascripts/bundle.bd41221c.min.js.map b/assets/javascripts/bundle.bd41221c.min.js.map new file mode 100644 index 00000000000..1663daba23f --- /dev/null +++ b/assets/javascripts/bundle.bd41221c.min.js.map @@ -0,0 +1,7 @@ +{ + "version": 3, + "sources": ["node_modules/focus-visible/dist/focus-visible.js", "node_modules/clipboard/dist/clipboard.js", "node_modules/escape-html/index.js", "src/templates/assets/javascripts/bundle.ts", "node_modules/rxjs/node_modules/tslib/tslib.es6.js", "node_modules/rxjs/src/internal/util/isFunction.ts", "node_modules/rxjs/src/internal/util/createErrorClass.ts", "node_modules/rxjs/src/internal/util/UnsubscriptionError.ts", "node_modules/rxjs/src/internal/util/arrRemove.ts", "node_modules/rxjs/src/internal/Subscription.ts", "node_modules/rxjs/src/internal/config.ts", "node_modules/rxjs/src/internal/scheduler/timeoutProvider.ts", "node_modules/rxjs/src/internal/util/reportUnhandledError.ts", "node_modules/rxjs/src/internal/util/noop.ts", "node_modules/rxjs/src/internal/NotificationFactories.ts", "node_modules/rxjs/src/internal/util/errorContext.ts", "node_modules/rxjs/src/internal/Subscriber.ts", "node_modules/rxjs/src/internal/symbol/observable.ts", "node_modules/rxjs/src/internal/util/identity.ts", "node_modules/rxjs/src/internal/util/pipe.ts", "node_modules/rxjs/src/internal/Observable.ts", "node_modules/rxjs/src/internal/util/lift.ts", "node_modules/rxjs/src/internal/operators/OperatorSubscriber.ts", "node_modules/rxjs/src/internal/scheduler/animationFrameProvider.ts", "node_modules/rxjs/src/internal/util/ObjectUnsubscribedError.ts", "node_modules/rxjs/src/internal/Subject.ts", "node_modules/rxjs/src/internal/scheduler/dateTimestampProvider.ts", "node_modules/rxjs/src/internal/ReplaySubject.ts", "node_modules/rxjs/src/internal/scheduler/Action.ts", "node_modules/rxjs/src/internal/scheduler/intervalProvider.ts", "node_modules/rxjs/src/internal/scheduler/AsyncAction.ts", "node_modules/rxjs/src/internal/Scheduler.ts", "node_modules/rxjs/src/internal/scheduler/AsyncScheduler.ts", "node_modules/rxjs/src/internal/scheduler/async.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameAction.ts", "node_modules/rxjs/src/internal/scheduler/AnimationFrameScheduler.ts", "node_modules/rxjs/src/internal/scheduler/animationFrame.ts", "node_modules/rxjs/src/internal/observable/empty.ts", "node_modules/rxjs/src/internal/util/isScheduler.ts", "node_modules/rxjs/src/internal/util/args.ts", "node_modules/rxjs/src/internal/util/isArrayLike.ts", "node_modules/rxjs/src/internal/util/isPromise.ts", "node_modules/rxjs/src/internal/util/isInteropObservable.ts", "node_modules/rxjs/src/internal/util/isAsyncIterable.ts", "node_modules/rxjs/src/internal/util/throwUnobservableError.ts", "node_modules/rxjs/src/internal/symbol/iterator.ts", "node_modules/rxjs/src/internal/util/isIterable.ts", "node_modules/rxjs/src/internal/util/isReadableStreamLike.ts", "node_modules/rxjs/src/internal/observable/innerFrom.ts", "node_modules/rxjs/src/internal/util/executeSchedule.ts", "node_modules/rxjs/src/internal/operators/observeOn.ts", "node_modules/rxjs/src/internal/operators/subscribeOn.ts", "node_modules/rxjs/src/internal/scheduled/scheduleObservable.ts", "node_modules/rxjs/src/internal/scheduled/schedulePromise.ts", "node_modules/rxjs/src/internal/scheduled/scheduleArray.ts", "node_modules/rxjs/src/internal/scheduled/scheduleIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleAsyncIterable.ts", "node_modules/rxjs/src/internal/scheduled/scheduleReadableStreamLike.ts", "node_modules/rxjs/src/internal/scheduled/scheduled.ts", "node_modules/rxjs/src/internal/observable/from.ts", "node_modules/rxjs/src/internal/observable/of.ts", "node_modules/rxjs/src/internal/observable/throwError.ts", "node_modules/rxjs/src/internal/util/EmptyError.ts", "node_modules/rxjs/src/internal/util/isDate.ts", "node_modules/rxjs/src/internal/operators/map.ts", "node_modules/rxjs/src/internal/util/mapOneOrManyArgs.ts", "node_modules/rxjs/src/internal/util/argsArgArrayOrObject.ts", "node_modules/rxjs/src/internal/util/createObject.ts", "node_modules/rxjs/src/internal/observable/combineLatest.ts", "node_modules/rxjs/src/internal/operators/mergeInternals.ts", "node_modules/rxjs/src/internal/operators/mergeMap.ts", "node_modules/rxjs/src/internal/operators/mergeAll.ts", "node_modules/rxjs/src/internal/operators/concatAll.ts", "node_modules/rxjs/src/internal/observable/concat.ts", "node_modules/rxjs/src/internal/observable/defer.ts", "node_modules/rxjs/src/internal/observable/fromEvent.ts", "node_modules/rxjs/src/internal/observable/fromEventPattern.ts", "node_modules/rxjs/src/internal/observable/timer.ts", "node_modules/rxjs/src/internal/observable/merge.ts", "node_modules/rxjs/src/internal/observable/never.ts", "node_modules/rxjs/src/internal/util/argsOrArgArray.ts", "node_modules/rxjs/src/internal/operators/filter.ts", "node_modules/rxjs/src/internal/observable/zip.ts", "node_modules/rxjs/src/internal/operators/audit.ts", "node_modules/rxjs/src/internal/operators/auditTime.ts", "node_modules/rxjs/src/internal/operators/bufferCount.ts", "node_modules/rxjs/src/internal/operators/catchError.ts", "node_modules/rxjs/src/internal/operators/scanInternals.ts", "node_modules/rxjs/src/internal/operators/combineLatest.ts", "node_modules/rxjs/src/internal/operators/combineLatestWith.ts", "node_modules/rxjs/src/internal/operators/debounceTime.ts", "node_modules/rxjs/src/internal/operators/defaultIfEmpty.ts", "node_modules/rxjs/src/internal/operators/take.ts", "node_modules/rxjs/src/internal/operators/ignoreElements.ts", "node_modules/rxjs/src/internal/operators/mapTo.ts", "node_modules/rxjs/src/internal/operators/delayWhen.ts", "node_modules/rxjs/src/internal/operators/delay.ts", "node_modules/rxjs/src/internal/operators/distinctUntilChanged.ts", "node_modules/rxjs/src/internal/operators/distinctUntilKeyChanged.ts", "node_modules/rxjs/src/internal/operators/throwIfEmpty.ts", "node_modules/rxjs/src/internal/operators/endWith.ts", "node_modules/rxjs/src/internal/operators/finalize.ts", "node_modules/rxjs/src/internal/operators/first.ts", "node_modules/rxjs/src/internal/operators/takeLast.ts", "node_modules/rxjs/src/internal/operators/merge.ts", "node_modules/rxjs/src/internal/operators/mergeWith.ts", "node_modules/rxjs/src/internal/operators/repeat.ts", "node_modules/rxjs/src/internal/operators/scan.ts", "node_modules/rxjs/src/internal/operators/share.ts", "node_modules/rxjs/src/internal/operators/shareReplay.ts", "node_modules/rxjs/src/internal/operators/skip.ts", "node_modules/rxjs/src/internal/operators/skipUntil.ts", "node_modules/rxjs/src/internal/operators/startWith.ts", "node_modules/rxjs/src/internal/operators/switchMap.ts", "node_modules/rxjs/src/internal/operators/takeUntil.ts", "node_modules/rxjs/src/internal/operators/takeWhile.ts", "node_modules/rxjs/src/internal/operators/tap.ts", "node_modules/rxjs/src/internal/operators/throttle.ts", "node_modules/rxjs/src/internal/operators/throttleTime.ts", "node_modules/rxjs/src/internal/operators/withLatestFrom.ts", "node_modules/rxjs/src/internal/operators/zip.ts", "node_modules/rxjs/src/internal/operators/zipWith.ts", "src/templates/assets/javascripts/browser/document/index.ts", "src/templates/assets/javascripts/browser/element/_/index.ts", "src/templates/assets/javascripts/browser/element/focus/index.ts", "src/templates/assets/javascripts/browser/element/hover/index.ts", "src/templates/assets/javascripts/browser/element/offset/_/index.ts", "src/templates/assets/javascripts/browser/element/offset/content/index.ts", "src/templates/assets/javascripts/utilities/h/index.ts", "src/templates/assets/javascripts/utilities/round/index.ts", "src/templates/assets/javascripts/browser/script/index.ts", "src/templates/assets/javascripts/browser/element/size/_/index.ts", "src/templates/assets/javascripts/browser/element/size/content/index.ts", "src/templates/assets/javascripts/browser/element/visibility/index.ts", "src/templates/assets/javascripts/browser/toggle/index.ts", "src/templates/assets/javascripts/browser/keyboard/index.ts", "src/templates/assets/javascripts/browser/location/_/index.ts", "src/templates/assets/javascripts/browser/location/hash/index.ts", "src/templates/assets/javascripts/browser/media/index.ts", "src/templates/assets/javascripts/browser/request/index.ts", "src/templates/assets/javascripts/browser/viewport/offset/index.ts", "src/templates/assets/javascripts/browser/viewport/size/index.ts", "src/templates/assets/javascripts/browser/viewport/_/index.ts", "src/templates/assets/javascripts/browser/viewport/at/index.ts", "src/templates/assets/javascripts/browser/worker/index.ts", "src/templates/assets/javascripts/_/index.ts", "src/templates/assets/javascripts/components/_/index.ts", "src/templates/assets/javascripts/components/announce/index.ts", "src/templates/assets/javascripts/components/consent/index.ts", "src/templates/assets/javascripts/templates/tooltip/index.tsx", "src/templates/assets/javascripts/templates/annotation/index.tsx", "src/templates/assets/javascripts/templates/clipboard/index.tsx", "src/templates/assets/javascripts/templates/search/index.tsx", "src/templates/assets/javascripts/templates/source/index.tsx", "src/templates/assets/javascripts/templates/tabbed/index.tsx", "src/templates/assets/javascripts/templates/table/index.tsx", "src/templates/assets/javascripts/templates/version/index.tsx", "src/templates/assets/javascripts/components/tooltip/index.ts", "src/templates/assets/javascripts/components/content/annotation/_/index.ts", "src/templates/assets/javascripts/components/content/annotation/list/index.ts", "src/templates/assets/javascripts/components/content/annotation/block/index.ts", "src/templates/assets/javascripts/components/content/code/_/index.ts", "src/templates/assets/javascripts/components/content/details/index.ts", "src/templates/assets/javascripts/components/content/mermaid/index.css", "src/templates/assets/javascripts/components/content/mermaid/index.ts", "src/templates/assets/javascripts/components/content/table/index.ts", "src/templates/assets/javascripts/components/content/tabs/index.ts", "src/templates/assets/javascripts/components/content/_/index.ts", "src/templates/assets/javascripts/components/dialog/index.ts", "src/templates/assets/javascripts/components/header/_/index.ts", "src/templates/assets/javascripts/components/header/title/index.ts", "src/templates/assets/javascripts/components/main/index.ts", "src/templates/assets/javascripts/components/palette/index.ts", "src/templates/assets/javascripts/components/progress/index.ts", "src/templates/assets/javascripts/integrations/clipboard/index.ts", "src/templates/assets/javascripts/integrations/sitemap/index.ts", "src/templates/assets/javascripts/integrations/instant/index.ts", "src/templates/assets/javascripts/integrations/search/highlighter/index.ts", "src/templates/assets/javascripts/integrations/search/worker/message/index.ts", "src/templates/assets/javascripts/integrations/search/worker/_/index.ts", "src/templates/assets/javascripts/integrations/version/index.ts", "src/templates/assets/javascripts/components/search/query/index.ts", "src/templates/assets/javascripts/components/search/result/index.ts", "src/templates/assets/javascripts/components/search/share/index.ts", "src/templates/assets/javascripts/components/search/suggest/index.ts", "src/templates/assets/javascripts/components/search/_/index.ts", "src/templates/assets/javascripts/components/search/highlight/index.ts", "src/templates/assets/javascripts/components/sidebar/index.ts", "src/templates/assets/javascripts/components/source/facts/github/index.ts", "src/templates/assets/javascripts/components/source/facts/gitlab/index.ts", "src/templates/assets/javascripts/components/source/facts/_/index.ts", "src/templates/assets/javascripts/components/source/_/index.ts", "src/templates/assets/javascripts/components/tabs/index.ts", "src/templates/assets/javascripts/components/toc/index.ts", "src/templates/assets/javascripts/components/top/index.ts", "src/templates/assets/javascripts/patches/ellipsis/index.ts", "src/templates/assets/javascripts/patches/indeterminate/index.ts", "src/templates/assets/javascripts/patches/scrollfix/index.ts", "src/templates/assets/javascripts/patches/scrolllock/index.ts", "src/templates/assets/javascripts/polyfills/index.ts"], + "sourcesContent": ["(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. \u00AF\\_(\u30C4)_/\u00AF\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n", "/*!\n * clipboard.js v2.0.11\n * https://clipboardjs.com/\n *\n * Licensed MIT \u00A9 Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function() { // webpackBootstrap\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 686:\n/***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {\n\n\"use strict\";\n\n// EXPORTS\n__webpack_require__.d(__webpack_exports__, {\n \"default\": function() { return /* binding */ clipboard; }\n});\n\n// EXTERNAL MODULE: ./node_modules/tiny-emitter/index.js\nvar tiny_emitter = __webpack_require__(279);\nvar tiny_emitter_default = /*#__PURE__*/__webpack_require__.n(tiny_emitter);\n// EXTERNAL MODULE: ./node_modules/good-listener/src/listen.js\nvar listen = __webpack_require__(370);\nvar listen_default = /*#__PURE__*/__webpack_require__.n(listen);\n// EXTERNAL MODULE: ./node_modules/select/src/select.js\nvar src_select = __webpack_require__(817);\nvar select_default = /*#__PURE__*/__webpack_require__.n(src_select);\n;// CONCATENATED MODULE: ./src/common/command.js\n/**\n * Executes a given operation type.\n * @param {String} type\n * @return {Boolean}\n */\nfunction command(type) {\n try {\n return document.execCommand(type);\n } catch (err) {\n return false;\n }\n}\n;// CONCATENATED MODULE: ./src/actions/cut.js\n\n\n/**\n * Cut action wrapper.\n * @param {String|HTMLElement} target\n * @return {String}\n */\n\nvar ClipboardActionCut = function ClipboardActionCut(target) {\n var selectedText = select_default()(target);\n command('cut');\n return selectedText;\n};\n\n/* harmony default export */ var actions_cut = (ClipboardActionCut);\n;// CONCATENATED MODULE: ./src/common/create-fake-element.js\n/**\n * Creates a fake textarea element with a value.\n * @param {String} value\n * @return {HTMLElement}\n */\nfunction createFakeElement(value) {\n var isRTL = document.documentElement.getAttribute('dir') === 'rtl';\n var fakeElement = document.createElement('textarea'); // Prevent zooming on iOS\n\n fakeElement.style.fontSize = '12pt'; // Reset box model\n\n fakeElement.style.border = '0';\n fakeElement.style.padding = '0';\n fakeElement.style.margin = '0'; // Move element out of screen horizontally\n\n fakeElement.style.position = 'absolute';\n fakeElement.style[isRTL ? 'right' : 'left'] = '-9999px'; // Move element to the same position vertically\n\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n fakeElement.style.top = \"\".concat(yPosition, \"px\");\n fakeElement.setAttribute('readonly', '');\n fakeElement.value = value;\n return fakeElement;\n}\n;// CONCATENATED MODULE: ./src/actions/copy.js\n\n\n\n/**\n * Create fake copy action wrapper using a fake element.\n * @param {String} target\n * @param {Object} options\n * @return {String}\n */\n\nvar fakeCopyAction = function fakeCopyAction(value, options) {\n var fakeElement = createFakeElement(value);\n options.container.appendChild(fakeElement);\n var selectedText = select_default()(fakeElement);\n command('copy');\n fakeElement.remove();\n return selectedText;\n};\n/**\n * Copy action wrapper.\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @return {String}\n */\n\n\nvar ClipboardActionCopy = function ClipboardActionCopy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n var selectedText = '';\n\n if (typeof target === 'string') {\n selectedText = fakeCopyAction(target, options);\n } else if (target instanceof HTMLInputElement && !['text', 'search', 'url', 'tel', 'password'].includes(target === null || target === void 0 ? void 0 : target.type)) {\n // If input type doesn't support `setSelectionRange`. Simulate it. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setSelectionRange\n selectedText = fakeCopyAction(target.value, options);\n } else {\n selectedText = select_default()(target);\n command('copy');\n }\n\n return selectedText;\n};\n\n/* harmony default export */ var actions_copy = (ClipboardActionCopy);\n;// CONCATENATED MODULE: ./src/actions/default.js\nfunction _typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return _typeof(obj); }\n\n\n\n/**\n * Inner function which performs selection from either `text` or `target`\n * properties and then executes copy or cut operations.\n * @param {Object} options\n */\n\nvar ClipboardActionDefault = function ClipboardActionDefault() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n // Defines base properties passed from constructor.\n var _options$action = options.action,\n action = _options$action === void 0 ? 'copy' : _options$action,\n container = options.container,\n target = options.target,\n text = options.text; // Sets the `action` to be performed which can be either 'copy' or 'cut'.\n\n if (action !== 'copy' && action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n } // Sets the `target` property using an element that will be have its content copied.\n\n\n if (target !== undefined) {\n if (target && _typeof(target) === 'object' && target.nodeType === 1) {\n if (action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n } // Define selection strategy based on `text` property.\n\n\n if (text) {\n return actions_copy(text, {\n container: container\n });\n } // Defines which selection strategy based on `target` property.\n\n\n if (target) {\n return action === 'cut' ? actions_cut(target) : actions_copy(target, {\n container: container\n });\n }\n};\n\n/* harmony default export */ var actions_default = (ClipboardActionDefault);\n;// CONCATENATED MODULE: ./src/clipboard.js\nfunction clipboard_typeof(obj) { \"@babel/helpers - typeof\"; if (typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\") { clipboard_typeof = function _typeof(obj) { return typeof obj; }; } else { clipboard_typeof = function _typeof(obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; }; } return clipboard_typeof(obj); }\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\nfunction _inherits(subClass, superClass) { if (typeof superClass !== \"function\" && superClass !== null) { throw new TypeError(\"Super expression must either be null or a function\"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }\n\nfunction _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }\n\nfunction _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }\n\nfunction _possibleConstructorReturn(self, call) { if (call && (clipboard_typeof(call) === \"object\" || typeof call === \"function\")) { return call; } return _assertThisInitialized(self); }\n\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\"); } return self; }\n\nfunction _isNativeReflectConstruct() { if (typeof Reflect === \"undefined\" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === \"function\") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }\n\nfunction _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }\n\n\n\n\n\n\n/**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n\nfunction getAttributeValue(suffix, element) {\n var attribute = \"data-clipboard-\".concat(suffix);\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n}\n/**\n * Base class which takes one or more elements, adds event listeners to them,\n * and instantiates a new `ClipboardAction` on each click.\n */\n\n\nvar Clipboard = /*#__PURE__*/function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n var _super = _createSuper(Clipboard);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n var _this;\n\n _classCallCheck(this, Clipboard);\n\n _this = _super.call(this);\n\n _this.resolveOptions(options);\n\n _this.listenClick(trigger);\n\n return _this;\n }\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: \"resolveOptions\",\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = clipboard_typeof(options.container) === 'object' ? options.container : document.body;\n }\n /**\n * Adds a click event listener to the passed trigger.\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n */\n\n }, {\n key: \"listenClick\",\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = listen_default()(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n /**\n * Defines a new `ClipboardAction` on each click event.\n * @param {Event} e\n */\n\n }, {\n key: \"onClick\",\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n var action = this.action(trigger) || 'copy';\n var text = actions_default({\n action: action,\n container: this.container,\n target: this.target(trigger),\n text: this.text(trigger)\n }); // Fires an event based on the copy operation result.\n\n this.emit(text ? 'success' : 'error', {\n action: action,\n text: text,\n trigger: trigger,\n clearSelection: function clearSelection() {\n if (trigger) {\n trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n });\n }\n /**\n * Default `action` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultAction\",\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n /**\n * Default `target` lookup function.\n * @param {Element} trigger\n */\n\n }, {\n key: \"defaultTarget\",\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n /**\n * Allow fire programmatically a copy action\n * @param {String|HTMLElement} target\n * @param {Object} options\n * @returns Text copied.\n */\n\n }, {\n key: \"defaultText\",\n\n /**\n * Default `text` lookup function.\n * @param {Element} trigger\n */\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n /**\n * Destroy lifecycle.\n */\n\n }, {\n key: \"destroy\",\n value: function destroy() {\n this.listener.destroy();\n }\n }], [{\n key: \"copy\",\n value: function copy(target) {\n var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {\n container: document.body\n };\n return actions_copy(target, options);\n }\n /**\n * Allow fire programmatically a cut action\n * @param {String|HTMLElement} target\n * @returns Text cutted.\n */\n\n }, {\n key: \"cut\",\n value: function cut(target) {\n return actions_cut(target);\n }\n /**\n * Returns the support of the given action, or all actions if no action is\n * given.\n * @param {String} [action]\n */\n\n }, {\n key: \"isSupported\",\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n return support;\n }\n }]);\n\n return Clipboard;\n}((tiny_emitter_default()));\n\n/* harmony default export */ var clipboard = (Clipboard);\n\n/***/ }),\n\n/***/ 828:\n/***/ (function(module) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n\n/***/ 438:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar closest = __webpack_require__(828);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n\n/***/ 879:\n/***/ (function(__unused_webpack_module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n\n/***/ 370:\n/***/ (function(module, __unused_webpack_exports, __webpack_require__) {\n\nvar is = __webpack_require__(879);\nvar delegate = __webpack_require__(438);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n\n/***/ 817:\n/***/ (function(module) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ }),\n\n/***/ 279:\n/***/ (function(module) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\nmodule.exports.TinyEmitter = E;\n\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(__webpack_module_cache__[moduleId]) {\n/******/ \t\t\treturn __webpack_module_cache__[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t/* webpack/runtime/compat get default export */\n/******/ \t!function() {\n/******/ \t\t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t\t__webpack_require__.n = function(module) {\n/******/ \t\t\tvar getter = module && module.__esModule ?\n/******/ \t\t\t\tfunction() { return module['default']; } :\n/******/ \t\t\t\tfunction() { return module; };\n/******/ \t\t\t__webpack_require__.d(getter, { a: getter });\n/******/ \t\t\treturn getter;\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/define property getters */\n/******/ \t!function() {\n/******/ \t\t// define getter functions for harmony exports\n/******/ \t\t__webpack_require__.d = function(exports, definition) {\n/******/ \t\t\tfor(var key in definition) {\n/******/ \t\t\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n/******/ \t\t\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n/******/ \t\t\t\t}\n/******/ \t\t\t}\n/******/ \t\t};\n/******/ \t}();\n/******/ \t\n/******/ \t/* webpack/runtime/hasOwnProperty shorthand */\n/******/ \t!function() {\n/******/ \t\t__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }\n/******/ \t}();\n/******/ \t\n/************************************************************************/\n/******/ \t// module exports must be returned from runtime so entry inlining is disabled\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(686);\n/******/ })()\n.default;\n});", "/*!\n * escape-html\n * Copyright(c) 2012-2013 TJ Holowaychuk\n * Copyright(c) 2015 Andreas Lubbe\n * Copyright(c) 2015 Tiancheng \"Timothy\" Gu\n * MIT Licensed\n */\n\n'use strict';\n\n/**\n * Module variables.\n * @private\n */\n\nvar matchHtmlRegExp = /[\"'&<>]/;\n\n/**\n * Module exports.\n * @public\n */\n\nmodule.exports = escapeHtml;\n\n/**\n * Escape special characters in the given string of html.\n *\n * @param {string} string The string to escape for inserting into HTML\n * @return {string}\n * @public\n */\n\nfunction escapeHtml(string) {\n var str = '' + string;\n var match = matchHtmlRegExp.exec(str);\n\n if (!match) {\n return str;\n }\n\n var escape;\n var html = '';\n var index = 0;\n var lastIndex = 0;\n\n for (index = match.index; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34: // \"\n escape = '"';\n break;\n case 38: // &\n escape = '&';\n break;\n case 39: // '\n escape = ''';\n break;\n case 60: // <\n escape = '<';\n break;\n case 62: // >\n escape = '>';\n break;\n default:\n continue;\n }\n\n if (lastIndex !== index) {\n html += str.substring(lastIndex, index);\n }\n\n lastIndex = index + 1;\n html += escape;\n }\n\n return lastIndex !== index\n ? html + str.substring(lastIndex, index)\n : html;\n}\n", "/*\n * Copyright (c) 2016-2024 Martin Donath \n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport \"focus-visible\"\n\nimport {\n EMPTY,\n NEVER,\n Observable,\n Subject,\n defer,\n delay,\n filter,\n map,\n merge,\n mergeWith,\n shareReplay,\n switchMap\n} from \"rxjs\"\n\nimport { configuration, feature } from \"./_\"\nimport {\n at,\n getActiveElement,\n getOptionalElement,\n requestJSON,\n setLocation,\n setToggle,\n watchDocument,\n watchKeyboard,\n watchLocation,\n watchLocationTarget,\n watchMedia,\n watchPrint,\n watchScript,\n watchViewport\n} from \"./browser\"\nimport {\n getComponentElement,\n getComponentElements,\n mountAnnounce,\n mountBackToTop,\n mountConsent,\n mountContent,\n mountDialog,\n mountHeader,\n mountHeaderTitle,\n mountPalette,\n mountProgress,\n mountSearch,\n mountSearchHiglight,\n mountSidebar,\n mountSource,\n mountTableOfContents,\n mountTabs,\n watchHeader,\n watchMain\n} from \"./components\"\nimport {\n SearchIndex,\n setupClipboardJS,\n setupInstantNavigation,\n setupVersionSelector\n} from \"./integrations\"\nimport {\n patchEllipsis,\n patchIndeterminate,\n patchScrollfix,\n patchScrolllock\n} from \"./patches\"\nimport \"./polyfills\"\n\n/* ----------------------------------------------------------------------------\n * Functions - @todo refactor\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch search index\n *\n * @returns Search index observable\n */\nfunction fetchSearchIndex(): Observable {\n if (location.protocol === \"file:\") {\n return watchScript(\n `${new URL(\"search/search_index.js\", config.base)}`\n )\n .pipe(\n // @ts-ignore - @todo fix typings\n map(() => __index),\n shareReplay(1)\n )\n } else {\n return requestJSON(\n new URL(\"search/search_index.json\", config.base)\n )\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Application\n * ------------------------------------------------------------------------- */\n\n/* Yay, JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Set up navigation observables and subjects */\nconst document$ = watchDocument()\nconst location$ = watchLocation()\nconst target$ = watchLocationTarget(location$)\nconst keyboard$ = watchKeyboard()\n\n/* Set up media observables */\nconst viewport$ = watchViewport()\nconst tablet$ = watchMedia(\"(min-width: 960px)\")\nconst screen$ = watchMedia(\"(min-width: 1220px)\")\nconst print$ = watchPrint()\n\n/* Retrieve search index, if search is enabled */\nconst config = configuration()\nconst index$ = document.forms.namedItem(\"search\")\n ? fetchSearchIndex()\n : NEVER\n\n/* Set up Clipboard.js integration */\nconst alert$ = new Subject()\nsetupClipboardJS({ alert$ })\n\n/* Set up progress indicator */\nconst progress$ = new Subject()\n\n/* Set up instant navigation, if enabled */\nif (feature(\"navigation.instant\"))\n setupInstantNavigation({ location$, viewport$, progress$ })\n .subscribe(document$)\n\n/* Set up version selector */\nif (config.version?.provider === \"mike\")\n setupVersionSelector({ document$ })\n\n/* Always close drawer and search on navigation */\nmerge(location$, target$)\n .pipe(\n delay(125)\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n setToggle(\"search\", false)\n })\n\n/* Set up global keyboard handlers */\nkeyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\")\n )\n .subscribe(key => {\n switch (key.type) {\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getOptionalElement(\"link[rel=prev]\")\n if (typeof prev !== \"undefined\")\n setLocation(prev)\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getOptionalElement(\"link[rel=next]\")\n if (typeof next !== \"undefined\")\n setLocation(next)\n break\n\n /* Expand navigation, see https://bit.ly/3ZjG5io */\n case \"Enter\":\n const active = getActiveElement()\n if (active instanceof HTMLLabelElement)\n active.click()\n }\n })\n\n/* Set up patches */\npatchEllipsis({ document$ })\npatchIndeterminate({ document$, tablet$ })\npatchScrollfix({ document$ })\npatchScrolllock({ viewport$, tablet$ })\n\n/* Set up header and main area observable */\nconst header$ = watchHeader(getComponentElement(\"header\"), { viewport$ })\nconst main$ = document$\n .pipe(\n map(() => getComponentElement(\"main\")),\n switchMap(el => watchMain(el, { viewport$, header$ })),\n shareReplay(1)\n )\n\n/* Set up control component observables */\nconst control$ = merge(\n\n /* Consent */\n ...getComponentElements(\"consent\")\n .map(el => mountConsent(el, { target$ })),\n\n /* Dialog */\n ...getComponentElements(\"dialog\")\n .map(el => mountDialog(el, { alert$ })),\n\n /* Header */\n ...getComponentElements(\"header\")\n .map(el => mountHeader(el, { viewport$, header$, main$ })),\n\n /* Color palette */\n ...getComponentElements(\"palette\")\n .map(el => mountPalette(el)),\n\n /* Progress bar */\n ...getComponentElements(\"progress\")\n .map(el => mountProgress(el, { progress$ })),\n\n /* Search */\n ...getComponentElements(\"search\")\n .map(el => mountSearch(el, { index$, keyboard$ })),\n\n /* Repository information */\n ...getComponentElements(\"source\")\n .map(el => mountSource(el))\n)\n\n/* Set up content component observables */\nconst content$ = defer(() => merge(\n\n /* Announcement bar */\n ...getComponentElements(\"announce\")\n .map(el => mountAnnounce(el)),\n\n /* Content */\n ...getComponentElements(\"content\")\n .map(el => mountContent(el, { viewport$, target$, print$ })),\n\n /* Search highlighting */\n ...getComponentElements(\"content\")\n .map(el => feature(\"search.highlight\")\n ? mountSearchHiglight(el, { index$, location$ })\n : EMPTY\n ),\n\n /* Header title */\n ...getComponentElements(\"header-title\")\n .map(el => mountHeaderTitle(el, { viewport$, header$ })),\n\n /* Sidebar */\n ...getComponentElements(\"sidebar\")\n .map(el => el.getAttribute(\"data-md-type\") === \"navigation\"\n ? at(screen$, () => mountSidebar(el, { viewport$, header$, main$ }))\n : at(tablet$, () => mountSidebar(el, { viewport$, header$, main$ }))\n ),\n\n /* Navigation tabs */\n ...getComponentElements(\"tabs\")\n .map(el => mountTabs(el, { viewport$, header$ })),\n\n /* Table of contents */\n ...getComponentElements(\"toc\")\n .map(el => mountTableOfContents(el, {\n viewport$, header$, main$, target$\n })),\n\n /* Back-to-top button */\n ...getComponentElements(\"top\")\n .map(el => mountBackToTop(el, { viewport$, header$, main$, target$ }))\n))\n\n/* Set up component observables */\nconst component$ = document$\n .pipe(\n switchMap(() => content$),\n mergeWith(control$),\n shareReplay(1)\n )\n\n/* Subscribe to all components */\ncomponent$.subscribe()\n\n/* ----------------------------------------------------------------------------\n * Exports\n * ------------------------------------------------------------------------- */\n\nwindow.document$ = document$ /* Document observable */\nwindow.location$ = location$ /* Location subject */\nwindow.target$ = target$ /* Location target observable */\nwindow.keyboard$ = keyboard$ /* Keyboard observable */\nwindow.viewport$ = viewport$ /* Viewport observable */\nwindow.tablet$ = tablet$ /* Media tablet observable */\nwindow.screen$ = screen$ /* Media screen observable */\nwindow.print$ = print$ /* Media print observable */\nwindow.alert$ = alert$ /* Alert subject */\nwindow.progress$ = progress$ /* Progress indicator subject */\nwindow.component$ = component$ /* Component observable */\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n if (typeof b !== \"function\" && b !== null)\r\n throw new TypeError(\"Class extends value \" + String(b) + \" is not a constructor or null\");\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport var __createBinding = Object.create ? (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\r\n}) : (function(o, m, k, k2) {\r\n if (k2 === undefined) k2 = k;\r\n o[k2] = m[k];\r\n});\r\n\r\nexport function __exportStar(m, o) {\r\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);\r\n}\r\n\r\nexport function __values(o) {\r\n var s = typeof Symbol === \"function\" && Symbol.iterator, m = s && o[s], i = 0;\r\n if (m) return m.call(o);\r\n if (o && typeof o.length === \"number\") return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n throw new TypeError(s ? \"Object is not iterable.\" : \"Symbol.iterator is not defined.\");\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\n/** @deprecated */\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n}\r\n\r\nexport function __spreadArray(to, from, pack) {\r\n if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {\r\n if (ar || !(i in from)) {\r\n if (!ar) ar = Array.prototype.slice.call(from, 0, i);\r\n ar[i] = from[i];\r\n }\r\n }\r\n return to.concat(ar || Array.prototype.slice.call(from));\r\n}\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nvar __setModuleDefault = Object.create ? (function(o, v) {\r\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\r\n}) : function(o, v) {\r\n o[\"default\"] = v;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\r\n __setModuleDefault(result, mod);\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n\r\nexport function __classPrivateFieldGet(receiver, state, kind, f) {\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a getter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot read private member from an object whose class did not declare it\");\r\n return kind === \"m\" ? f : kind === \"a\" ? f.call(receiver) : f ? f.value : state.get(receiver);\r\n}\r\n\r\nexport function __classPrivateFieldSet(receiver, state, value, kind, f) {\r\n if (kind === \"m\") throw new TypeError(\"Private method is not writable\");\r\n if (kind === \"a\" && !f) throw new TypeError(\"Private accessor was defined without a setter\");\r\n if (typeof state === \"function\" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError(\"Cannot write private member to an object whose class did not declare it\");\r\n return (kind === \"a\" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;\r\n}\r\n", "/**\n * Returns true if the object is a function.\n * @param value The value to check\n */\nexport function isFunction(value: any): value is (...args: any[]) => any {\n return typeof value === 'function';\n}\n", "/**\n * Used to create Error subclasses until the community moves away from ES5.\n *\n * This is because compiling from TypeScript down to ES5 has issues with subclassing Errors\n * as well as other built-in types: https://github.com/Microsoft/TypeScript/issues/12123\n *\n * @param createImpl A factory function to create the actual constructor implementation. The returned\n * function should be a named function that calls `_super` internally.\n */\nexport function createErrorClass(createImpl: (_super: any) => any): T {\n const _super = (instance: any) => {\n Error.call(instance);\n instance.stack = new Error().stack;\n };\n\n const ctorFunc = createImpl(_super);\n ctorFunc.prototype = Object.create(Error.prototype);\n ctorFunc.prototype.constructor = ctorFunc;\n return ctorFunc;\n}\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface UnsubscriptionError extends Error {\n readonly errors: any[];\n}\n\nexport interface UnsubscriptionErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (errors: any[]): UnsubscriptionError;\n}\n\n/**\n * An error thrown when one or more errors have occurred during the\n * `unsubscribe` of a {@link Subscription}.\n */\nexport const UnsubscriptionError: UnsubscriptionErrorCtor = createErrorClass(\n (_super) =>\n function UnsubscriptionErrorImpl(this: any, errors: (Error | string)[]) {\n _super(this);\n this.message = errors\n ? `${errors.length} errors occurred during unsubscription:\n${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\\n ')}`\n : '';\n this.name = 'UnsubscriptionError';\n this.errors = errors;\n }\n);\n", "/**\n * Removes an item from an array, mutating it.\n * @param arr The array to remove the item from\n * @param item The item to remove\n */\nexport function arrRemove(arr: T[] | undefined | null, item: T) {\n if (arr) {\n const index = arr.indexOf(item);\n 0 <= index && arr.splice(index, 1);\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { UnsubscriptionError } from './util/UnsubscriptionError';\nimport { SubscriptionLike, TeardownLogic, Unsubscribable } from './types';\nimport { arrRemove } from './util/arrRemove';\n\n/**\n * Represents a disposable resource, such as the execution of an Observable. A\n * Subscription has one important method, `unsubscribe`, that takes no argument\n * and just disposes the resource held by the subscription.\n *\n * Additionally, subscriptions may be grouped together through the `add()`\n * method, which will attach a child Subscription to the current Subscription.\n * When a Subscription is unsubscribed, all its children (and its grandchildren)\n * will be unsubscribed as well.\n *\n * @class Subscription\n */\nexport class Subscription implements SubscriptionLike {\n /** @nocollapse */\n public static EMPTY = (() => {\n const empty = new Subscription();\n empty.closed = true;\n return empty;\n })();\n\n /**\n * A flag to indicate whether this Subscription has already been unsubscribed.\n */\n public closed = false;\n\n private _parentage: Subscription[] | Subscription | null = null;\n\n /**\n * The list of registered finalizers to execute upon unsubscription. Adding and removing from this\n * list occurs in the {@link #add} and {@link #remove} methods.\n */\n private _finalizers: Exclude[] | null = null;\n\n /**\n * @param initialTeardown A function executed first as part of the finalization\n * process that is kicked off when {@link #unsubscribe} is called.\n */\n constructor(private initialTeardown?: () => void) {}\n\n /**\n * Disposes the resources held by the subscription. May, for instance, cancel\n * an ongoing Observable execution or cancel any other type of work that\n * started when the Subscription was created.\n * @return {void}\n */\n unsubscribe(): void {\n let errors: any[] | undefined;\n\n if (!this.closed) {\n this.closed = true;\n\n // Remove this from it's parents.\n const { _parentage } = this;\n if (_parentage) {\n this._parentage = null;\n if (Array.isArray(_parentage)) {\n for (const parent of _parentage) {\n parent.remove(this);\n }\n } else {\n _parentage.remove(this);\n }\n }\n\n const { initialTeardown: initialFinalizer } = this;\n if (isFunction(initialFinalizer)) {\n try {\n initialFinalizer();\n } catch (e) {\n errors = e instanceof UnsubscriptionError ? e.errors : [e];\n }\n }\n\n const { _finalizers } = this;\n if (_finalizers) {\n this._finalizers = null;\n for (const finalizer of _finalizers) {\n try {\n execFinalizer(finalizer);\n } catch (err) {\n errors = errors ?? [];\n if (err instanceof UnsubscriptionError) {\n errors = [...errors, ...err.errors];\n } else {\n errors.push(err);\n }\n }\n }\n }\n\n if (errors) {\n throw new UnsubscriptionError(errors);\n }\n }\n }\n\n /**\n * Adds a finalizer to this subscription, so that finalization will be unsubscribed/called\n * when this subscription is unsubscribed. If this subscription is already {@link #closed},\n * because it has already been unsubscribed, then whatever finalizer is passed to it\n * will automatically be executed (unless the finalizer itself is also a closed subscription).\n *\n * Closed Subscriptions cannot be added as finalizers to any subscription. Adding a closed\n * subscription to a any subscription will result in no operation. (A noop).\n *\n * Adding a subscription to itself, or adding `null` or `undefined` will not perform any\n * operation at all. (A noop).\n *\n * `Subscription` instances that are added to this instance will automatically remove themselves\n * if they are unsubscribed. Functions and {@link Unsubscribable} objects that you wish to remove\n * will need to be removed manually with {@link #remove}\n *\n * @param teardown The finalization logic to add to this subscription.\n */\n add(teardown: TeardownLogic): void {\n // Only add the finalizer if it's not undefined\n // and don't add a subscription to itself.\n if (teardown && teardown !== this) {\n if (this.closed) {\n // If this subscription is already closed,\n // execute whatever finalizer is handed to it automatically.\n execFinalizer(teardown);\n } else {\n if (teardown instanceof Subscription) {\n // We don't add closed subscriptions, and we don't add the same subscription\n // twice. Subscription unsubscribe is idempotent.\n if (teardown.closed || teardown._hasParent(this)) {\n return;\n }\n teardown._addParent(this);\n }\n (this._finalizers = this._finalizers ?? []).push(teardown);\n }\n }\n }\n\n /**\n * Checks to see if a this subscription already has a particular parent.\n * This will signal that this subscription has already been added to the parent in question.\n * @param parent the parent to check for\n */\n private _hasParent(parent: Subscription) {\n const { _parentage } = this;\n return _parentage === parent || (Array.isArray(_parentage) && _parentage.includes(parent));\n }\n\n /**\n * Adds a parent to this subscription so it can be removed from the parent if it\n * unsubscribes on it's own.\n *\n * NOTE: THIS ASSUMES THAT {@link _hasParent} HAS ALREADY BEEN CHECKED.\n * @param parent The parent subscription to add\n */\n private _addParent(parent: Subscription) {\n const { _parentage } = this;\n this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;\n }\n\n /**\n * Called on a child when it is removed via {@link #remove}.\n * @param parent The parent to remove\n */\n private _removeParent(parent: Subscription) {\n const { _parentage } = this;\n if (_parentage === parent) {\n this._parentage = null;\n } else if (Array.isArray(_parentage)) {\n arrRemove(_parentage, parent);\n }\n }\n\n /**\n * Removes a finalizer from this subscription that was previously added with the {@link #add} method.\n *\n * Note that `Subscription` instances, when unsubscribed, will automatically remove themselves\n * from every other `Subscription` they have been added to. This means that using the `remove` method\n * is not a common thing and should be used thoughtfully.\n *\n * If you add the same finalizer instance of a function or an unsubscribable object to a `Subscription` instance\n * more than once, you will need to call `remove` the same number of times to remove all instances.\n *\n * All finalizer instances are removed to free up memory upon unsubscription.\n *\n * @param teardown The finalizer to remove from this subscription\n */\n remove(teardown: Exclude): void {\n const { _finalizers } = this;\n _finalizers && arrRemove(_finalizers, teardown);\n\n if (teardown instanceof Subscription) {\n teardown._removeParent(this);\n }\n }\n}\n\nexport const EMPTY_SUBSCRIPTION = Subscription.EMPTY;\n\nexport function isSubscription(value: any): value is Subscription {\n return (\n value instanceof Subscription ||\n (value && 'closed' in value && isFunction(value.remove) && isFunction(value.add) && isFunction(value.unsubscribe))\n );\n}\n\nfunction execFinalizer(finalizer: Unsubscribable | (() => void)) {\n if (isFunction(finalizer)) {\n finalizer();\n } else {\n finalizer.unsubscribe();\n }\n}\n", "import { Subscriber } from './Subscriber';\nimport { ObservableNotification } from './types';\n\n/**\n * The {@link GlobalConfig} object for RxJS. It is used to configure things\n * like how to react on unhandled errors.\n */\nexport const config: GlobalConfig = {\n onUnhandledError: null,\n onStoppedNotification: null,\n Promise: undefined,\n useDeprecatedSynchronousErrorHandling: false,\n useDeprecatedNextContext: false,\n};\n\n/**\n * The global configuration object for RxJS, used to configure things\n * like how to react on unhandled errors. Accessible via {@link config}\n * object.\n */\nexport interface GlobalConfig {\n /**\n * A registration point for unhandled errors from RxJS. These are errors that\n * cannot were not handled by consuming code in the usual subscription path. For\n * example, if you have this configured, and you subscribe to an observable without\n * providing an error handler, errors from that subscription will end up here. This\n * will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onUnhandledError: ((err: any) => void) | null;\n\n /**\n * A registration point for notifications that cannot be sent to subscribers because they\n * have completed, errored or have been explicitly unsubscribed. By default, next, complete\n * and error notifications sent to stopped subscribers are noops. However, sometimes callers\n * might want a different behavior. For example, with sources that attempt to report errors\n * to stopped subscribers, a caller can configure RxJS to throw an unhandled error instead.\n * This will _always_ be called asynchronously on another job in the runtime. This is because\n * we do not want errors thrown in this user-configured handler to interfere with the\n * behavior of the library.\n */\n onStoppedNotification: ((notification: ObservableNotification, subscriber: Subscriber) => void) | null;\n\n /**\n * The promise constructor used by default for {@link Observable#toPromise toPromise} and {@link Observable#forEach forEach}\n * methods.\n *\n * @deprecated As of version 8, RxJS will no longer support this sort of injection of a\n * Promise constructor. If you need a Promise implementation other than native promises,\n * please polyfill/patch Promise as you see appropriate. Will be removed in v8.\n */\n Promise?: PromiseConstructorLike;\n\n /**\n * If true, turns on synchronous error rethrowing, which is a deprecated behavior\n * in v6 and higher. This behavior enables bad patterns like wrapping a subscribe\n * call in a try/catch block. It also enables producer interference, a nasty bug\n * where a multicast can be broken for all observers by a downstream consumer with\n * an unhandled error. DO NOT USE THIS FLAG UNLESS IT'S NEEDED TO BUY TIME\n * FOR MIGRATION REASONS.\n *\n * @deprecated As of version 8, RxJS will no longer support synchronous throwing\n * of unhandled errors. All errors will be thrown on a separate call stack to prevent bad\n * behaviors described above. Will be removed in v8.\n */\n useDeprecatedSynchronousErrorHandling: boolean;\n\n /**\n * If true, enables an as-of-yet undocumented feature from v5: The ability to access\n * `unsubscribe()` via `this` context in `next` functions created in observers passed\n * to `subscribe`.\n *\n * This is being removed because the performance was severely problematic, and it could also cause\n * issues when types other than POJOs are passed to subscribe as subscribers, as they will likely have\n * their `this` context overwritten.\n *\n * @deprecated As of version 8, RxJS will no longer support altering the\n * context of next functions provided as part of an observer to Subscribe. Instead,\n * you will have access to a subscription or a signal or token that will allow you to do things like\n * unsubscribe and test closed status. Will be removed in v8.\n */\n useDeprecatedNextContext: boolean;\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetTimeoutFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearTimeoutFunction = (handle: TimerHandle) => void;\n\ninterface TimeoutProvider {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n delegate:\n | {\n setTimeout: SetTimeoutFunction;\n clearTimeout: ClearTimeoutFunction;\n }\n | undefined;\n}\n\nexport const timeoutProvider: TimeoutProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setTimeout(handler: () => void, timeout?: number, ...args) {\n const { delegate } = timeoutProvider;\n if (delegate?.setTimeout) {\n return delegate.setTimeout(handler, timeout, ...args);\n }\n return setTimeout(handler, timeout, ...args);\n },\n clearTimeout(handle) {\n const { delegate } = timeoutProvider;\n return (delegate?.clearTimeout || clearTimeout)(handle as any);\n },\n delegate: undefined,\n};\n", "import { config } from '../config';\nimport { timeoutProvider } from '../scheduler/timeoutProvider';\n\n/**\n * Handles an error on another job either with the user-configured {@link onUnhandledError},\n * or by throwing it on that new job so it can be picked up by `window.onerror`, `process.on('error')`, etc.\n *\n * This should be called whenever there is an error that is out-of-band with the subscription\n * or when an error hits a terminal boundary of the subscription and no error handler was provided.\n *\n * @param err the error to report\n */\nexport function reportUnhandledError(err: any) {\n timeoutProvider.setTimeout(() => {\n const { onUnhandledError } = config;\n if (onUnhandledError) {\n // Execute the user-configured error handler.\n onUnhandledError(err);\n } else {\n // Throw so it is picked up by the runtime's uncaught error mechanism.\n throw err;\n }\n });\n}\n", "/* tslint:disable:no-empty */\nexport function noop() { }\n", "import { CompleteNotification, NextNotification, ErrorNotification } from './types';\n\n/**\n * A completion object optimized for memory use and created to be the\n * same \"shape\" as other notifications in v8.\n * @internal\n */\nexport const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined) as CompleteNotification)();\n\n/**\n * Internal use only. Creates an optimized error notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function errorNotification(error: any): ErrorNotification {\n return createNotification('E', undefined, error) as any;\n}\n\n/**\n * Internal use only. Creates an optimized next notification that is the same \"shape\"\n * as other notifications.\n * @internal\n */\nexport function nextNotification(value: T) {\n return createNotification('N', value, undefined) as NextNotification;\n}\n\n/**\n * Ensures that all notifications created internally have the same \"shape\" in v8.\n *\n * TODO: This is only exported to support a crazy legacy test in `groupBy`.\n * @internal\n */\nexport function createNotification(kind: 'N' | 'E' | 'C', value: any, error: any) {\n return {\n kind,\n value,\n error,\n };\n}\n", "import { config } from '../config';\n\nlet context: { errorThrown: boolean; error: any } | null = null;\n\n/**\n * Handles dealing with errors for super-gross mode. Creates a context, in which\n * any synchronously thrown errors will be passed to {@link captureError}. Which\n * will record the error such that it will be rethrown after the call back is complete.\n * TODO: Remove in v8\n * @param cb An immediately executed function.\n */\nexport function errorContext(cb: () => void) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n const isRoot = !context;\n if (isRoot) {\n context = { errorThrown: false, error: null };\n }\n cb();\n if (isRoot) {\n const { errorThrown, error } = context!;\n context = null;\n if (errorThrown) {\n throw error;\n }\n }\n } else {\n // This is the general non-deprecated path for everyone that\n // isn't crazy enough to use super-gross mode (useDeprecatedSynchronousErrorHandling)\n cb();\n }\n}\n\n/**\n * Captures errors only in super-gross mode.\n * @param err the error to capture\n */\nexport function captureError(err: any) {\n if (config.useDeprecatedSynchronousErrorHandling && context) {\n context.errorThrown = true;\n context.error = err;\n }\n}\n", "import { isFunction } from './util/isFunction';\nimport { Observer, ObservableNotification } from './types';\nimport { isSubscription, Subscription } from './Subscription';\nimport { config } from './config';\nimport { reportUnhandledError } from './util/reportUnhandledError';\nimport { noop } from './util/noop';\nimport { nextNotification, errorNotification, COMPLETE_NOTIFICATION } from './NotificationFactories';\nimport { timeoutProvider } from './scheduler/timeoutProvider';\nimport { captureError } from './util/errorContext';\n\n/**\n * Implements the {@link Observer} interface and extends the\n * {@link Subscription} class. While the {@link Observer} is the public API for\n * consuming the values of an {@link Observable}, all Observers get converted to\n * a Subscriber, in order to provide Subscription-like capabilities such as\n * `unsubscribe`. Subscriber is a common type in RxJS, and crucial for\n * implementing operators, but it is rarely used as a public API.\n *\n * @class Subscriber\n */\nexport class Subscriber extends Subscription implements Observer {\n /**\n * A static factory for a Subscriber, given a (potentially partial) definition\n * of an Observer.\n * @param next The `next` callback of an Observer.\n * @param error The `error` callback of an\n * Observer.\n * @param complete The `complete` callback of an\n * Observer.\n * @return A Subscriber wrapping the (partially defined)\n * Observer represented by the given arguments.\n * @nocollapse\n * @deprecated Do not use. Will be removed in v8. There is no replacement for this\n * method, and there is no reason to be creating instances of `Subscriber` directly.\n * If you have a specific use case, please file an issue.\n */\n static create(next?: (x?: T) => void, error?: (e?: any) => void, complete?: () => void): Subscriber {\n return new SafeSubscriber(next, error, complete);\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected isStopped: boolean = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n protected destination: Subscriber | Observer; // this `any` is the escape hatch to erase extra type param (e.g. R)\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * There is no reason to directly create an instance of Subscriber. This type is exported for typings reasons.\n */\n constructor(destination?: Subscriber | Observer) {\n super();\n if (destination) {\n this.destination = destination;\n // Automatically chain subscriptions together here.\n // if destination is a Subscription, then it is a Subscriber.\n if (isSubscription(destination)) {\n destination.add(this);\n }\n } else {\n this.destination = EMPTY_OBSERVER;\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `next` from\n * the Observable, with a value. The Observable may call this method 0 or more\n * times.\n * @param {T} [value] The `next` value.\n * @return {void}\n */\n next(value?: T): void {\n if (this.isStopped) {\n handleStoppedNotification(nextNotification(value), this);\n } else {\n this._next(value!);\n }\n }\n\n /**\n * The {@link Observer} callback to receive notifications of type `error` from\n * the Observable, with an attached `Error`. Notifies the Observer that\n * the Observable has experienced an error condition.\n * @param {any} [err] The `error` exception.\n * @return {void}\n */\n error(err?: any): void {\n if (this.isStopped) {\n handleStoppedNotification(errorNotification(err), this);\n } else {\n this.isStopped = true;\n this._error(err);\n }\n }\n\n /**\n * The {@link Observer} callback to receive a valueless notification of type\n * `complete` from the Observable. Notifies the Observer that the Observable\n * has finished sending push-based notifications.\n * @return {void}\n */\n complete(): void {\n if (this.isStopped) {\n handleStoppedNotification(COMPLETE_NOTIFICATION, this);\n } else {\n this.isStopped = true;\n this._complete();\n }\n }\n\n unsubscribe(): void {\n if (!this.closed) {\n this.isStopped = true;\n super.unsubscribe();\n this.destination = null!;\n }\n }\n\n protected _next(value: T): void {\n this.destination.next(value);\n }\n\n protected _error(err: any): void {\n try {\n this.destination.error(err);\n } finally {\n this.unsubscribe();\n }\n }\n\n protected _complete(): void {\n try {\n this.destination.complete();\n } finally {\n this.unsubscribe();\n }\n }\n}\n\n/**\n * This bind is captured here because we want to be able to have\n * compatibility with monoid libraries that tend to use a method named\n * `bind`. In particular, a library called Monio requires this.\n */\nconst _bind = Function.prototype.bind;\n\nfunction bind any>(fn: Fn, thisArg: any): Fn {\n return _bind.call(fn, thisArg);\n}\n\n/**\n * Internal optimization only, DO NOT EXPOSE.\n * @internal\n */\nclass ConsumerObserver implements Observer {\n constructor(private partialObserver: Partial>) {}\n\n next(value: T): void {\n const { partialObserver } = this;\n if (partialObserver.next) {\n try {\n partialObserver.next(value);\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n\n error(err: any): void {\n const { partialObserver } = this;\n if (partialObserver.error) {\n try {\n partialObserver.error(err);\n } catch (error) {\n handleUnhandledError(error);\n }\n } else {\n handleUnhandledError(err);\n }\n }\n\n complete(): void {\n const { partialObserver } = this;\n if (partialObserver.complete) {\n try {\n partialObserver.complete();\n } catch (error) {\n handleUnhandledError(error);\n }\n }\n }\n}\n\nexport class SafeSubscriber extends Subscriber {\n constructor(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((e?: any) => void) | null,\n complete?: (() => void) | null\n ) {\n super();\n\n let partialObserver: Partial>;\n if (isFunction(observerOrNext) || !observerOrNext) {\n // The first argument is a function, not an observer. The next\n // two arguments *could* be observers, or they could be empty.\n partialObserver = {\n next: (observerOrNext ?? undefined) as (((value: T) => void) | undefined),\n error: error ?? undefined,\n complete: complete ?? undefined,\n };\n } else {\n // The first argument is a partial observer.\n let context: any;\n if (this && config.useDeprecatedNextContext) {\n // This is a deprecated path that made `this.unsubscribe()` available in\n // next handler functions passed to subscribe. This only exists behind a flag\n // now, as it is *very* slow.\n context = Object.create(observerOrNext);\n context.unsubscribe = () => this.unsubscribe();\n partialObserver = {\n next: observerOrNext.next && bind(observerOrNext.next, context),\n error: observerOrNext.error && bind(observerOrNext.error, context),\n complete: observerOrNext.complete && bind(observerOrNext.complete, context),\n };\n } else {\n // The \"normal\" path. Just use the partial observer directly.\n partialObserver = observerOrNext;\n }\n }\n\n // Wrap the partial observer to ensure it's a full observer, and\n // make sure proper error handling is accounted for.\n this.destination = new ConsumerObserver(partialObserver);\n }\n}\n\nfunction handleUnhandledError(error: any) {\n if (config.useDeprecatedSynchronousErrorHandling) {\n captureError(error);\n } else {\n // Ideal path, we report this as an unhandled error,\n // which is thrown on a new call stack.\n reportUnhandledError(error);\n }\n}\n\n/**\n * An error handler used when no error handler was supplied\n * to the SafeSubscriber -- meaning no error handler was supplied\n * do the `subscribe` call on our observable.\n * @param err The error to handle\n */\nfunction defaultErrorHandler(err: any) {\n throw err;\n}\n\n/**\n * A handler for notifications that cannot be sent to a stopped subscriber.\n * @param notification The notification being sent\n * @param subscriber The stopped subscriber\n */\nfunction handleStoppedNotification(notification: ObservableNotification, subscriber: Subscriber) {\n const { onStoppedNotification } = config;\n onStoppedNotification && timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));\n}\n\n/**\n * The observer used as a stub for subscriptions where the user did not\n * pass any arguments to `subscribe`. Comes with the default error handling\n * behavior.\n */\nexport const EMPTY_OBSERVER: Readonly> & { closed: true } = {\n closed: true,\n next: noop,\n error: defaultErrorHandler,\n complete: noop,\n};\n", "/**\n * Symbol.observable or a string \"@@observable\". Used for interop\n *\n * @deprecated We will no longer be exporting this symbol in upcoming versions of RxJS.\n * Instead polyfill and use Symbol.observable directly *or* use https://www.npmjs.com/package/symbol-observable\n */\nexport const observable: string | symbol = (() => (typeof Symbol === 'function' && Symbol.observable) || '@@observable')();\n", "/**\n * This function takes one parameter and just returns it. Simply put,\n * this is like `(x: T): T => x`.\n *\n * ## Examples\n *\n * This is useful in some cases when using things like `mergeMap`\n *\n * ```ts\n * import { interval, take, map, range, mergeMap, identity } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(5));\n *\n * const result$ = source$.pipe(\n * map(i => range(i)),\n * mergeMap(identity) // same as mergeMap(x => x)\n * );\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * Or when you want to selectively apply an operator\n *\n * ```ts\n * import { interval, take, identity } from 'rxjs';\n *\n * const shouldLimit = () => Math.random() < 0.5;\n *\n * const source$ = interval(1000);\n *\n * const result$ = source$.pipe(shouldLimit() ? take(5) : identity);\n *\n * result$.subscribe({\n * next: console.log\n * });\n * ```\n *\n * @param x Any value that is returned by this function\n * @returns The value passed as the first parameter to this function\n */\nexport function identity(x: T): T {\n return x;\n}\n", "import { identity } from './identity';\nimport { UnaryFunction } from '../types';\n\nexport function pipe(): typeof identity;\nexport function pipe(fn1: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction): UnaryFunction;\nexport function pipe(fn1: UnaryFunction, fn2: UnaryFunction, fn3: UnaryFunction): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction\n): UnaryFunction;\nexport function pipe(\n fn1: UnaryFunction,\n fn2: UnaryFunction,\n fn3: UnaryFunction,\n fn4: UnaryFunction,\n fn5: UnaryFunction,\n fn6: UnaryFunction,\n fn7: UnaryFunction,\n fn8: UnaryFunction,\n fn9: UnaryFunction,\n ...fns: UnaryFunction[]\n): UnaryFunction;\n\n/**\n * pipe() can be called on one or more functions, each of which can take one argument (\"UnaryFunction\")\n * and uses it to return a value.\n * It returns a function that takes one argument, passes it to the first UnaryFunction, and then\n * passes the result to the next one, passes that result to the next one, and so on. \n */\nexport function pipe(...fns: Array>): UnaryFunction {\n return pipeFromArray(fns);\n}\n\n/** @internal */\nexport function pipeFromArray(fns: Array>): UnaryFunction {\n if (fns.length === 0) {\n return identity as UnaryFunction;\n }\n\n if (fns.length === 1) {\n return fns[0];\n }\n\n return function piped(input: T): R {\n return fns.reduce((prev: any, fn: UnaryFunction) => fn(prev), input as any);\n };\n}\n", "import { Operator } from './Operator';\nimport { SafeSubscriber, Subscriber } from './Subscriber';\nimport { isSubscription, Subscription } from './Subscription';\nimport { TeardownLogic, OperatorFunction, Subscribable, Observer } from './types';\nimport { observable as Symbol_observable } from './symbol/observable';\nimport { pipeFromArray } from './util/pipe';\nimport { config } from './config';\nimport { isFunction } from './util/isFunction';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A representation of any set of values over any amount of time. This is the most basic building block\n * of RxJS.\n *\n * @class Observable\n */\nexport class Observable implements Subscribable {\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n source: Observable | undefined;\n\n /**\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n */\n operator: Operator | undefined;\n\n /**\n * @constructor\n * @param {Function} subscribe the function that is called when the Observable is\n * initially subscribed to. This function is given a Subscriber, to which new values\n * can be `next`ed, or an `error` method can be called to raise an error, or\n * `complete` can be called to notify of a successful completion.\n */\n constructor(subscribe?: (this: Observable, subscriber: Subscriber) => TeardownLogic) {\n if (subscribe) {\n this._subscribe = subscribe;\n }\n }\n\n // HACK: Since TypeScript inherits static properties too, we have to\n // fight against TypeScript here so Subject can have a different static create signature\n /**\n * Creates a new Observable by calling the Observable constructor\n * @owner Observable\n * @method create\n * @param {Function} subscribe? the subscriber function to be passed to the Observable constructor\n * @return {Observable} a new observable\n * @nocollapse\n * @deprecated Use `new Observable()` instead. Will be removed in v8.\n */\n static create: (...args: any[]) => any = (subscribe?: (subscriber: Subscriber) => TeardownLogic) => {\n return new Observable(subscribe);\n };\n\n /**\n * Creates a new Observable, with this Observable instance as the source, and the passed\n * operator defined as the new observable's operator.\n * @method lift\n * @param operator the operator defining the operation to take on the observable\n * @return a new observable with the Operator applied\n * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8.\n * If you have implemented an operator using `lift`, it is recommended that you create an\n * operator by simply returning `new Observable()` directly. See \"Creating new operators from\n * scratch\" section here: https://rxjs.dev/guide/operators\n */\n lift(operator?: Operator): Observable {\n const observable = new Observable();\n observable.source = this;\n observable.operator = operator;\n return observable;\n }\n\n subscribe(observerOrNext?: Partial> | ((value: T) => void)): Subscription;\n /** @deprecated Instead of passing separate callback arguments, use an observer argument. Signatures taking separate callback arguments will be removed in v8. Details: https://rxjs.dev/deprecations/subscribe-arguments */\n subscribe(next?: ((value: T) => void) | null, error?: ((error: any) => void) | null, complete?: (() => void) | null): Subscription;\n /**\n * Invokes an execution of an Observable and registers Observer handlers for notifications it will emit.\n *\n * Use it when you have all these Observables, but still nothing is happening.\n *\n * `subscribe` is not a regular operator, but a method that calls Observable's internal `subscribe` function. It\n * might be for example a function that you passed to Observable's constructor, but most of the time it is\n * a library implementation, which defines what will be emitted by an Observable, and when it be will emitted. This means\n * that calling `subscribe` is actually the moment when Observable starts its work, not when it is created, as it is often\n * the thought.\n *\n * Apart from starting the execution of an Observable, this method allows you to listen for values\n * that an Observable emits, as well as for when it completes or errors. You can achieve this in two\n * of the following ways.\n *\n * The first way is creating an object that implements {@link Observer} interface. It should have methods\n * defined by that interface, but note that it should be just a regular JavaScript object, which you can create\n * yourself in any way you want (ES6 class, classic function constructor, object literal etc.). In particular, do\n * not attempt to use any RxJS implementation details to create Observers - you don't need them. Remember also\n * that your object does not have to implement all methods. If you find yourself creating a method that doesn't\n * do anything, you can simply omit it. Note however, if the `error` method is not provided and an error happens,\n * it will be thrown asynchronously. Errors thrown asynchronously cannot be caught using `try`/`catch`. Instead,\n * use the {@link onUnhandledError} configuration option or use a runtime handler (like `window.onerror` or\n * `process.on('error)`) to be notified of unhandled errors. Because of this, it's recommended that you provide\n * an `error` method to avoid missing thrown errors.\n *\n * The second way is to give up on Observer object altogether and simply provide callback functions in place of its methods.\n * This means you can provide three functions as arguments to `subscribe`, where the first function is equivalent\n * of a `next` method, the second of an `error` method and the third of a `complete` method. Just as in case of an Observer,\n * if you do not need to listen for something, you can omit a function by passing `undefined` or `null`,\n * since `subscribe` recognizes these functions by where they were placed in function call. When it comes\n * to the `error` function, as with an Observer, if not provided, errors emitted by an Observable will be thrown asynchronously.\n *\n * You can, however, subscribe with no parameters at all. This may be the case where you're not interested in terminal events\n * and you also handled emissions internally by using operators (e.g. using `tap`).\n *\n * Whichever style of calling `subscribe` you use, in both cases it returns a Subscription object.\n * This object allows you to call `unsubscribe` on it, which in turn will stop the work that an Observable does and will clean\n * up all resources that an Observable used. Note that cancelling a subscription will not call `complete` callback\n * provided to `subscribe` function, which is reserved for a regular completion signal that comes from an Observable.\n *\n * Remember that callbacks provided to `subscribe` are not guaranteed to be called asynchronously.\n * It is an Observable itself that decides when these functions will be called. For example {@link of}\n * by default emits all its values synchronously. Always check documentation for how given Observable\n * will behave when subscribed and if its default behavior can be modified with a `scheduler`.\n *\n * #### Examples\n *\n * Subscribe with an {@link guide/observer Observer}\n *\n * ```ts\n * import { of } from 'rxjs';\n *\n * const sumObserver = {\n * sum: 0,\n * next(value) {\n * console.log('Adding: ' + value);\n * this.sum = this.sum + value;\n * },\n * error() {\n * // We actually could just remove this method,\n * // since we do not really care about errors right now.\n * },\n * complete() {\n * console.log('Sum equals: ' + this.sum);\n * }\n * };\n *\n * of(1, 2, 3) // Synchronously emits 1, 2, 3 and then completes.\n * .subscribe(sumObserver);\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Subscribe with functions ({@link deprecations/subscribe-arguments deprecated})\n *\n * ```ts\n * import { of } from 'rxjs'\n *\n * let sum = 0;\n *\n * of(1, 2, 3).subscribe(\n * value => {\n * console.log('Adding: ' + value);\n * sum = sum + value;\n * },\n * undefined,\n * () => console.log('Sum equals: ' + sum)\n * );\n *\n * // Logs:\n * // 'Adding: 1'\n * // 'Adding: 2'\n * // 'Adding: 3'\n * // 'Sum equals: 6'\n * ```\n *\n * Cancel a subscription\n *\n * ```ts\n * import { interval } from 'rxjs';\n *\n * const subscription = interval(1000).subscribe({\n * next(num) {\n * console.log(num)\n * },\n * complete() {\n * // Will not be called, even when cancelling subscription.\n * console.log('completed!');\n * }\n * });\n *\n * setTimeout(() => {\n * subscription.unsubscribe();\n * console.log('unsubscribed!');\n * }, 2500);\n *\n * // Logs:\n * // 0 after 1s\n * // 1 after 2s\n * // 'unsubscribed!' after 2.5s\n * ```\n *\n * @param {Observer|Function} observerOrNext (optional) Either an observer with methods to be called,\n * or the first of three possible handlers, which is the handler for each value emitted from the subscribed\n * Observable.\n * @param {Function} error (optional) A handler for a terminal event resulting from an error. If no error handler is provided,\n * the error will be thrown asynchronously as unhandled.\n * @param {Function} complete (optional) A handler for a terminal event resulting from successful completion.\n * @return {Subscription} a subscription reference to the registered handlers\n * @method subscribe\n */\n subscribe(\n observerOrNext?: Partial> | ((value: T) => void) | null,\n error?: ((error: any) => void) | null,\n complete?: (() => void) | null\n ): Subscription {\n const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new SafeSubscriber(observerOrNext, error, complete);\n\n errorContext(() => {\n const { operator, source } = this;\n subscriber.add(\n operator\n ? // We're dealing with a subscription in the\n // operator chain to one of our lifted operators.\n operator.call(subscriber, source)\n : source\n ? // If `source` has a value, but `operator` does not, something that\n // had intimate knowledge of our API, like our `Subject`, must have\n // set it. We're going to just call `_subscribe` directly.\n this._subscribe(subscriber)\n : // In all other cases, we're likely wrapping a user-provided initializer\n // function, so we need to catch errors and handle them appropriately.\n this._trySubscribe(subscriber)\n );\n });\n\n return subscriber;\n }\n\n /** @internal */\n protected _trySubscribe(sink: Subscriber): TeardownLogic {\n try {\n return this._subscribe(sink);\n } catch (err) {\n // We don't need to return anything in this case,\n // because it's just going to try to `add()` to a subscription\n // above.\n sink.error(err);\n }\n }\n\n /**\n * Used as a NON-CANCELLABLE means of subscribing to an observable, for use with\n * APIs that expect promises, like `async/await`. You cannot unsubscribe from this.\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * #### Example\n *\n * ```ts\n * import { interval, take } from 'rxjs';\n *\n * const source$ = interval(1000).pipe(take(4));\n *\n * async function getTotal() {\n * let total = 0;\n *\n * await source$.forEach(value => {\n * total += value;\n * console.log('observable -> ' + value);\n * });\n *\n * return total;\n * }\n *\n * getTotal().then(\n * total => console.log('Total: ' + total)\n * );\n *\n * // Expected:\n * // 'observable -> 0'\n * // 'observable -> 1'\n * // 'observable -> 2'\n * // 'observable -> 3'\n * // 'Total: 6'\n * ```\n *\n * @param next a handler for each value emitted by the observable\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n */\n forEach(next: (value: T) => void): Promise;\n\n /**\n * @param next a handler for each value emitted by the observable\n * @param promiseCtor a constructor function used to instantiate the Promise\n * @return a promise that either resolves on observable completion or\n * rejects with the handled error\n * @deprecated Passing a Promise constructor will no longer be available\n * in upcoming versions of RxJS. This is because it adds weight to the library, for very\n * little benefit. If you need this functionality, it is recommended that you either\n * polyfill Promise, or you create an adapter to convert the returned native promise\n * to whatever promise implementation you wanted. Will be removed in v8.\n */\n forEach(next: (value: T) => void, promiseCtor: PromiseConstructorLike): Promise;\n\n forEach(next: (value: T) => void, promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n const subscriber = new SafeSubscriber({\n next: (value) => {\n try {\n next(value);\n } catch (err) {\n reject(err);\n subscriber.unsubscribe();\n }\n },\n error: reject,\n complete: resolve,\n });\n this.subscribe(subscriber);\n }) as Promise;\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): TeardownLogic {\n return this.source?.subscribe(subscriber);\n }\n\n /**\n * An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable\n * @method Symbol.observable\n * @return {Observable} this instance of the observable\n */\n [Symbol_observable]() {\n return this;\n }\n\n /* tslint:disable:max-line-length */\n pipe(): Observable;\n pipe(op1: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction): Observable;\n pipe(op1: OperatorFunction, op2: OperatorFunction, op3: OperatorFunction): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction\n ): Observable;\n pipe(\n op1: OperatorFunction,\n op2: OperatorFunction,\n op3: OperatorFunction,\n op4: OperatorFunction,\n op5: OperatorFunction,\n op6: OperatorFunction,\n op7: OperatorFunction,\n op8: OperatorFunction,\n op9: OperatorFunction,\n ...operations: OperatorFunction[]\n ): Observable;\n /* tslint:enable:max-line-length */\n\n /**\n * Used to stitch together functional operators into a chain.\n * @method pipe\n * @return {Observable} the Observable result of all of the operators having\n * been called in the order they were passed in.\n *\n * ## Example\n *\n * ```ts\n * import { interval, filter, map, scan } from 'rxjs';\n *\n * interval(1000)\n * .pipe(\n * filter(x => x % 2 === 0),\n * map(x => x + x),\n * scan((acc, x) => acc + x)\n * )\n * .subscribe(x => console.log(x));\n * ```\n */\n pipe(...operations: OperatorFunction[]): Observable {\n return pipeFromArray(operations)(this);\n }\n\n /* tslint:disable:max-line-length */\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: typeof Promise): Promise;\n /** @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise */\n toPromise(PromiseCtor: PromiseConstructorLike): Promise;\n /* tslint:enable:max-line-length */\n\n /**\n * Subscribe to this Observable and get a Promise resolving on\n * `complete` with the last emission (if any).\n *\n * **WARNING**: Only use this with observables you *know* will complete. If the source\n * observable does not complete, you will end up with a promise that is hung up, and\n * potentially all of the state of an async function hanging out in memory. To avoid\n * this situation, look into adding something like {@link timeout}, {@link take},\n * {@link takeWhile}, or {@link takeUntil} amongst others.\n *\n * @method toPromise\n * @param [promiseCtor] a constructor function used to instantiate\n * the Promise\n * @return A Promise that resolves with the last value emit, or\n * rejects on an error. If there were no emissions, Promise\n * resolves with undefined.\n * @deprecated Replaced with {@link firstValueFrom} and {@link lastValueFrom}. Will be removed in v8. Details: https://rxjs.dev/deprecations/to-promise\n */\n toPromise(promiseCtor?: PromiseConstructorLike): Promise {\n promiseCtor = getPromiseCtor(promiseCtor);\n\n return new promiseCtor((resolve, reject) => {\n let value: T | undefined;\n this.subscribe(\n (x: T) => (value = x),\n (err: any) => reject(err),\n () => resolve(value)\n );\n }) as Promise;\n }\n}\n\n/**\n * Decides between a passed promise constructor from consuming code,\n * A default configured promise constructor, and the native promise\n * constructor and returns it. If nothing can be found, it will throw\n * an error.\n * @param promiseCtor The optional promise constructor to passed by consuming code\n */\nfunction getPromiseCtor(promiseCtor: PromiseConstructorLike | undefined) {\n return promiseCtor ?? config.Promise ?? Promise;\n}\n\nfunction isObserver(value: any): value is Observer {\n return value && isFunction(value.next) && isFunction(value.error) && isFunction(value.complete);\n}\n\nfunction isSubscriber(value: any): value is Subscriber {\n return (value && value instanceof Subscriber) || (isObserver(value) && isSubscription(value));\n}\n", "import { Observable } from '../Observable';\nimport { Subscriber } from '../Subscriber';\nimport { OperatorFunction } from '../types';\nimport { isFunction } from './isFunction';\n\n/**\n * Used to determine if an object is an Observable with a lift function.\n */\nexport function hasLift(source: any): source is { lift: InstanceType['lift'] } {\n return isFunction(source?.lift);\n}\n\n/**\n * Creates an `OperatorFunction`. Used to define operators throughout the library in a concise way.\n * @param init The logic to connect the liftedSource to the subscriber at the moment of subscription.\n */\nexport function operate(\n init: (liftedSource: Observable, subscriber: Subscriber) => (() => void) | void\n): OperatorFunction {\n return (source: Observable) => {\n if (hasLift(source)) {\n return source.lift(function (this: Subscriber, liftedSource: Observable) {\n try {\n return init(liftedSource, this);\n } catch (err) {\n this.error(err);\n }\n });\n }\n throw new TypeError('Unable to lift unknown Observable type');\n };\n}\n", "import { Subscriber } from '../Subscriber';\n\n/**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional teardown logic here. This will only be called on teardown if the\n * subscriber itself is not already closed. This is called after all other teardown logic is executed.\n */\nexport function createOperatorSubscriber(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n onFinalize?: () => void\n): Subscriber {\n return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);\n}\n\n/**\n * A generic helper for allowing operators to be created with a Subscriber and\n * use closures to capture necessary state from the operator function itself.\n */\nexport class OperatorSubscriber extends Subscriber {\n /**\n * Creates an instance of an `OperatorSubscriber`.\n * @param destination The downstream subscriber.\n * @param onNext Handles next values, only called if this subscriber is not stopped or closed. Any\n * error that occurs in this function is caught and sent to the `error` method of this subscriber.\n * @param onError Handles errors from the subscription, any errors that occur in this handler are caught\n * and send to the `destination` error handler.\n * @param onComplete Handles completion notification from the subscription. Any errors that occur in\n * this handler are sent to the `destination` error handler.\n * @param onFinalize Additional finalization logic here. This will only be called on finalization if the\n * subscriber itself is not already closed. This is called after all other finalization logic is executed.\n * @param shouldUnsubscribe An optional check to see if an unsubscribe call should truly unsubscribe.\n * NOTE: This currently **ONLY** exists to support the strange behavior of {@link groupBy}, where unsubscription\n * to the resulting observable does not actually disconnect from the source if there are active subscriptions\n * to any grouped observable. (DO NOT EXPOSE OR USE EXTERNALLY!!!)\n */\n constructor(\n destination: Subscriber,\n onNext?: (value: T) => void,\n onComplete?: () => void,\n onError?: (err: any) => void,\n private onFinalize?: () => void,\n private shouldUnsubscribe?: () => boolean\n ) {\n // It's important - for performance reasons - that all of this class's\n // members are initialized and that they are always initialized in the same\n // order. This will ensure that all OperatorSubscriber instances have the\n // same hidden class in V8. This, in turn, will help keep the number of\n // hidden classes involved in property accesses within the base class as\n // low as possible. If the number of hidden classes involved exceeds four,\n // the property accesses will become megamorphic and performance penalties\n // will be incurred - i.e. inline caches won't be used.\n //\n // The reasons for ensuring all instances have the same hidden class are\n // further discussed in this blog post from Benedikt Meurer:\n // https://benediktmeurer.de/2018/03/23/impact-of-polymorphism-on-component-based-frameworks-like-react/\n super(destination);\n this._next = onNext\n ? function (this: OperatorSubscriber, value: T) {\n try {\n onNext(value);\n } catch (err) {\n destination.error(err);\n }\n }\n : super._next;\n this._error = onError\n ? function (this: OperatorSubscriber, err: any) {\n try {\n onError(err);\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._error;\n this._complete = onComplete\n ? function (this: OperatorSubscriber) {\n try {\n onComplete();\n } catch (err) {\n // Send any errors that occur down stream.\n destination.error(err);\n } finally {\n // Ensure finalization.\n this.unsubscribe();\n }\n }\n : super._complete;\n }\n\n unsubscribe() {\n if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {\n const { closed } = this;\n super.unsubscribe();\n // Execute additional teardown if we have any and we didn't already do so.\n !closed && this.onFinalize?.();\n }\n }\n}\n", "import { Subscription } from '../Subscription';\n\ninterface AnimationFrameProvider {\n schedule(callback: FrameRequestCallback): Subscription;\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n delegate:\n | {\n requestAnimationFrame: typeof requestAnimationFrame;\n cancelAnimationFrame: typeof cancelAnimationFrame;\n }\n | undefined;\n}\n\nexport const animationFrameProvider: AnimationFrameProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n schedule(callback) {\n let request = requestAnimationFrame;\n let cancel: typeof cancelAnimationFrame | undefined = cancelAnimationFrame;\n const { delegate } = animationFrameProvider;\n if (delegate) {\n request = delegate.requestAnimationFrame;\n cancel = delegate.cancelAnimationFrame;\n }\n const handle = request((timestamp) => {\n // Clear the cancel function. The request has been fulfilled, so\n // attempting to cancel the request upon unsubscription would be\n // pointless.\n cancel = undefined;\n callback(timestamp);\n });\n return new Subscription(() => cancel?.(handle));\n },\n requestAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.requestAnimationFrame || requestAnimationFrame)(...args);\n },\n cancelAnimationFrame(...args) {\n const { delegate } = animationFrameProvider;\n return (delegate?.cancelAnimationFrame || cancelAnimationFrame)(...args);\n },\n delegate: undefined,\n};\n", "import { createErrorClass } from './createErrorClass';\n\nexport interface ObjectUnsubscribedError extends Error {}\n\nexport interface ObjectUnsubscribedErrorCtor {\n /**\n * @deprecated Internal implementation detail. Do not construct error instances.\n * Cannot be tagged as internal: https://github.com/ReactiveX/rxjs/issues/6269\n */\n new (): ObjectUnsubscribedError;\n}\n\n/**\n * An error thrown when an action is invalid because the object has been\n * unsubscribed.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n *\n * @class ObjectUnsubscribedError\n */\nexport const ObjectUnsubscribedError: ObjectUnsubscribedErrorCtor = createErrorClass(\n (_super) =>\n function ObjectUnsubscribedErrorImpl(this: any) {\n _super(this);\n this.name = 'ObjectUnsubscribedError';\n this.message = 'object unsubscribed';\n }\n);\n", "import { Operator } from './Operator';\nimport { Observable } from './Observable';\nimport { Subscriber } from './Subscriber';\nimport { Subscription, EMPTY_SUBSCRIPTION } from './Subscription';\nimport { Observer, SubscriptionLike, TeardownLogic } from './types';\nimport { ObjectUnsubscribedError } from './util/ObjectUnsubscribedError';\nimport { arrRemove } from './util/arrRemove';\nimport { errorContext } from './util/errorContext';\n\n/**\n * A Subject is a special type of Observable that allows values to be\n * multicasted to many Observers. Subjects are like EventEmitters.\n *\n * Every Subject is an Observable and an Observer. You can subscribe to a\n * Subject, and you can call next to feed values as well as error and complete.\n */\nexport class Subject extends Observable implements SubscriptionLike {\n closed = false;\n\n private currentObservers: Observer[] | null = null;\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n observers: Observer[] = [];\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n isStopped = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n hasError = false;\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n thrownError: any = null;\n\n /**\n * Creates a \"subject\" by basically gluing an observer to an observable.\n *\n * @nocollapse\n * @deprecated Recommended you do not use. Will be removed at some point in the future. Plans for replacement still under discussion.\n */\n static create: (...args: any[]) => any = (destination: Observer, source: Observable): AnonymousSubject => {\n return new AnonymousSubject(destination, source);\n };\n\n constructor() {\n // NOTE: This must be here to obscure Observable's constructor.\n super();\n }\n\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n lift(operator: Operator): Observable {\n const subject = new AnonymousSubject(this, this);\n subject.operator = operator as any;\n return subject as any;\n }\n\n /** @internal */\n protected _throwIfClosed() {\n if (this.closed) {\n throw new ObjectUnsubscribedError();\n }\n }\n\n next(value: T) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n if (!this.currentObservers) {\n this.currentObservers = Array.from(this.observers);\n }\n for (const observer of this.currentObservers) {\n observer.next(value);\n }\n }\n });\n }\n\n error(err: any) {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.hasError = this.isStopped = true;\n this.thrownError = err;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.error(err);\n }\n }\n });\n }\n\n complete() {\n errorContext(() => {\n this._throwIfClosed();\n if (!this.isStopped) {\n this.isStopped = true;\n const { observers } = this;\n while (observers.length) {\n observers.shift()!.complete();\n }\n }\n });\n }\n\n unsubscribe() {\n this.isStopped = this.closed = true;\n this.observers = this.currentObservers = null!;\n }\n\n get observed() {\n return this.observers?.length > 0;\n }\n\n /** @internal */\n protected _trySubscribe(subscriber: Subscriber): TeardownLogic {\n this._throwIfClosed();\n return super._trySubscribe(subscriber);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._checkFinalizedStatuses(subscriber);\n return this._innerSubscribe(subscriber);\n }\n\n /** @internal */\n protected _innerSubscribe(subscriber: Subscriber) {\n const { hasError, isStopped, observers } = this;\n if (hasError || isStopped) {\n return EMPTY_SUBSCRIPTION;\n }\n this.currentObservers = null;\n observers.push(subscriber);\n return new Subscription(() => {\n this.currentObservers = null;\n arrRemove(observers, subscriber);\n });\n }\n\n /** @internal */\n protected _checkFinalizedStatuses(subscriber: Subscriber) {\n const { hasError, thrownError, isStopped } = this;\n if (hasError) {\n subscriber.error(thrownError);\n } else if (isStopped) {\n subscriber.complete();\n }\n }\n\n /**\n * Creates a new Observable with this Subject as the source. You can do this\n * to create custom Observer-side logic of the Subject and conceal it from\n * code that uses the Observable.\n * @return {Observable} Observable that the Subject casts to\n */\n asObservable(): Observable {\n const observable: any = new Observable();\n observable.source = this;\n return observable;\n }\n}\n\n/**\n * @class AnonymousSubject\n */\nexport class AnonymousSubject extends Subject {\n constructor(\n /** @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. */\n public destination?: Observer,\n source?: Observable\n ) {\n super();\n this.source = source;\n }\n\n next(value: T) {\n this.destination?.next?.(value);\n }\n\n error(err: any) {\n this.destination?.error?.(err);\n }\n\n complete() {\n this.destination?.complete?.();\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n return this.source?.subscribe(subscriber) ?? EMPTY_SUBSCRIPTION;\n }\n}\n", "import { TimestampProvider } from '../types';\n\ninterface DateTimestampProvider extends TimestampProvider {\n delegate: TimestampProvider | undefined;\n}\n\nexport const dateTimestampProvider: DateTimestampProvider = {\n now() {\n // Use the variable rather than `this` so that the function can be called\n // without being bound to the provider.\n return (dateTimestampProvider.delegate || Date).now();\n },\n delegate: undefined,\n};\n", "import { Subject } from './Subject';\nimport { TimestampProvider } from './types';\nimport { Subscriber } from './Subscriber';\nimport { Subscription } from './Subscription';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * A variant of {@link Subject} that \"replays\" old values to new subscribers by emitting them when they first subscribe.\n *\n * `ReplaySubject` has an internal buffer that will store a specified number of values that it has observed. Like `Subject`,\n * `ReplaySubject` \"observes\" values by having them passed to its `next` method. When it observes a value, it will store that\n * value for a time determined by the configuration of the `ReplaySubject`, as passed to its constructor.\n *\n * When a new subscriber subscribes to the `ReplaySubject` instance, it will synchronously emit all values in its buffer in\n * a First-In-First-Out (FIFO) manner. The `ReplaySubject` will also complete, if it has observed completion; and it will\n * error if it has observed an error.\n *\n * There are two main configuration items to be concerned with:\n *\n * 1. `bufferSize` - This will determine how many items are stored in the buffer, defaults to infinite.\n * 2. `windowTime` - The amount of time to hold a value in the buffer before removing it from the buffer.\n *\n * Both configurations may exist simultaneously. So if you would like to buffer a maximum of 3 values, as long as the values\n * are less than 2 seconds old, you could do so with a `new ReplaySubject(3, 2000)`.\n *\n * ### Differences with BehaviorSubject\n *\n * `BehaviorSubject` is similar to `new ReplaySubject(1)`, with a couple of exceptions:\n *\n * 1. `BehaviorSubject` comes \"primed\" with a single value upon construction.\n * 2. `ReplaySubject` will replay values, even after observing an error, where `BehaviorSubject` will not.\n *\n * @see {@link Subject}\n * @see {@link BehaviorSubject}\n * @see {@link shareReplay}\n */\nexport class ReplaySubject extends Subject {\n private _buffer: (T | number)[] = [];\n private _infiniteTimeWindow = true;\n\n /**\n * @param bufferSize The size of the buffer to replay on subscription\n * @param windowTime The amount of time the buffered items will stay buffered\n * @param timestampProvider An object with a `now()` method that provides the current timestamp. This is used to\n * calculate the amount of time something has been buffered.\n */\n constructor(\n private _bufferSize = Infinity,\n private _windowTime = Infinity,\n private _timestampProvider: TimestampProvider = dateTimestampProvider\n ) {\n super();\n this._infiniteTimeWindow = _windowTime === Infinity;\n this._bufferSize = Math.max(1, _bufferSize);\n this._windowTime = Math.max(1, _windowTime);\n }\n\n next(value: T): void {\n const { isStopped, _buffer, _infiniteTimeWindow, _timestampProvider, _windowTime } = this;\n if (!isStopped) {\n _buffer.push(value);\n !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);\n }\n this._trimBuffer();\n super.next(value);\n }\n\n /** @internal */\n protected _subscribe(subscriber: Subscriber): Subscription {\n this._throwIfClosed();\n this._trimBuffer();\n\n const subscription = this._innerSubscribe(subscriber);\n\n const { _infiniteTimeWindow, _buffer } = this;\n // We use a copy here, so reentrant code does not mutate our array while we're\n // emitting it to a new subscriber.\n const copy = _buffer.slice();\n for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {\n subscriber.next(copy[i] as T);\n }\n\n this._checkFinalizedStatuses(subscriber);\n\n return subscription;\n }\n\n private _trimBuffer() {\n const { _bufferSize, _timestampProvider, _buffer, _infiniteTimeWindow } = this;\n // If we don't have an infinite buffer size, and we're over the length,\n // use splice to truncate the old buffer values off. Note that we have to\n // double the size for instances where we're not using an infinite time window\n // because we're storing the values and the timestamps in the same array.\n const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;\n _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);\n\n // Now, if we're not in an infinite time window, remove all values where the time is\n // older than what is allowed.\n if (!_infiniteTimeWindow) {\n const now = _timestampProvider.now();\n let last = 0;\n // Search the array for the first timestamp that isn't expired and\n // truncate the buffer up to that point.\n for (let i = 1; i < _buffer.length && (_buffer[i] as number) <= now; i += 2) {\n last = i;\n }\n last && _buffer.splice(0, last + 1);\n }\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Subscription } from '../Subscription';\nimport { SchedulerAction } from '../types';\n\n/**\n * A unit of work to be executed in a `scheduler`. An action is typically\n * created from within a {@link SchedulerLike} and an RxJS user does not need to concern\n * themselves about creating and manipulating an Action.\n *\n * ```ts\n * class Action extends Subscription {\n * new (scheduler: Scheduler, work: (state?: T) => void);\n * schedule(state?: T, delay: number = 0): Subscription;\n * }\n * ```\n *\n * @class Action\n */\nexport class Action extends Subscription {\n constructor(scheduler: Scheduler, work: (this: SchedulerAction, state?: T) => void) {\n super();\n }\n /**\n * Schedules this action on its parent {@link SchedulerLike} for execution. May be passed\n * some context object, `state`. May happen at some point in the future,\n * according to the `delay` parameter, if specified.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler.\n * @return {void}\n */\n public schedule(state?: T, delay: number = 0): Subscription {\n return this;\n }\n}\n", "import type { TimerHandle } from './timerHandle';\ntype SetIntervalFunction = (handler: () => void, timeout?: number, ...args: any[]) => TimerHandle;\ntype ClearIntervalFunction = (handle: TimerHandle) => void;\n\ninterface IntervalProvider {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n delegate:\n | {\n setInterval: SetIntervalFunction;\n clearInterval: ClearIntervalFunction;\n }\n | undefined;\n}\n\nexport const intervalProvider: IntervalProvider = {\n // When accessing the delegate, use the variable rather than `this` so that\n // the functions can be called without being bound to the provider.\n setInterval(handler: () => void, timeout?: number, ...args) {\n const { delegate } = intervalProvider;\n if (delegate?.setInterval) {\n return delegate.setInterval(handler, timeout, ...args);\n }\n return setInterval(handler, timeout, ...args);\n },\n clearInterval(handle) {\n const { delegate } = intervalProvider;\n return (delegate?.clearInterval || clearInterval)(handle as any);\n },\n delegate: undefined,\n};\n", "import { Action } from './Action';\nimport { SchedulerAction } from '../types';\nimport { Subscription } from '../Subscription';\nimport { AsyncScheduler } from './AsyncScheduler';\nimport { intervalProvider } from './intervalProvider';\nimport { arrRemove } from '../util/arrRemove';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncAction extends Action {\n public id: TimerHandle | undefined;\n public state?: T;\n // @ts-ignore: Property has no initializer and is not definitely assigned\n public delay: number;\n protected pending: boolean = false;\n\n constructor(protected scheduler: AsyncScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n public schedule(state?: T, delay: number = 0): Subscription {\n if (this.closed) {\n return this;\n }\n\n // Always replace the current state with the new state.\n this.state = state;\n\n const id = this.id;\n const scheduler = this.scheduler;\n\n //\n // Important implementation note:\n //\n // Actions only execute once by default, unless rescheduled from within the\n // scheduled callback. This allows us to implement single and repeat\n // actions via the same code path, without adding API surface area, as well\n // as mimic traditional recursion but across asynchronous boundaries.\n //\n // However, JS runtimes and timers distinguish between intervals achieved by\n // serial `setTimeout` calls vs. a single `setInterval` call. An interval of\n // serial `setTimeout` calls can be individually delayed, which delays\n // scheduling the next `setTimeout`, and so on. `setInterval` attempts to\n // guarantee the interval callback will be invoked more precisely to the\n // interval period, regardless of load.\n //\n // Therefore, we use `setInterval` to schedule single and repeat actions.\n // If the action reschedules itself with the same delay, the interval is not\n // canceled. If the action doesn't reschedule, or reschedules with a\n // different delay, the interval will be canceled after scheduled callback\n // execution.\n //\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, delay);\n }\n\n // Set the pending flag indicating that this action has been scheduled, or\n // has recursively rescheduled itself.\n this.pending = true;\n\n this.delay = delay;\n // If this action has already an async Id, don't request a new one.\n this.id = this.id ?? this.requestAsyncId(scheduler, this.id, delay);\n\n return this;\n }\n\n protected requestAsyncId(scheduler: AsyncScheduler, _id?: TimerHandle, delay: number = 0): TimerHandle {\n return intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);\n }\n\n protected recycleAsyncId(_scheduler: AsyncScheduler, id?: TimerHandle, delay: number | null = 0): TimerHandle | undefined {\n // If this action is rescheduled with the same delay time, don't clear the interval id.\n if (delay != null && this.delay === delay && this.pending === false) {\n return id;\n }\n // Otherwise, if the action's delay time is different from the current delay,\n // or the action has been rescheduled before it's executed, clear the interval id\n if (id != null) {\n intervalProvider.clearInterval(id);\n }\n\n return undefined;\n }\n\n /**\n * Immediately executes this action and the `work` it contains.\n * @return {any}\n */\n public execute(state: T, delay: number): any {\n if (this.closed) {\n return new Error('executing a cancelled action');\n }\n\n this.pending = false;\n const error = this._execute(state, delay);\n if (error) {\n return error;\n } else if (this.pending === false && this.id != null) {\n // Dequeue if the action didn't reschedule itself. Don't call\n // unsubscribe(), because the action could reschedule later.\n // For example:\n // ```\n // scheduler.schedule(function doWork(counter) {\n // /* ... I'm a busy worker bee ... */\n // var originalAction = this;\n // /* wait 100ms before rescheduling the action */\n // setTimeout(function () {\n // originalAction.schedule(counter + 1);\n // }, 100);\n // }, 1000);\n // ```\n this.id = this.recycleAsyncId(this.scheduler, this.id, null);\n }\n }\n\n protected _execute(state: T, _delay: number): any {\n let errored: boolean = false;\n let errorValue: any;\n try {\n this.work(state);\n } catch (e) {\n errored = true;\n // HACK: Since code elsewhere is relying on the \"truthiness\" of the\n // return here, we can't have it return \"\" or 0 or false.\n // TODO: Clean this up when we refactor schedulers mid-version-8 or so.\n errorValue = e ? e : new Error('Scheduled action threw falsy error');\n }\n if (errored) {\n this.unsubscribe();\n return errorValue;\n }\n }\n\n unsubscribe() {\n if (!this.closed) {\n const { id, scheduler } = this;\n const { actions } = scheduler;\n\n this.work = this.state = this.scheduler = null!;\n this.pending = false;\n\n arrRemove(actions, this);\n if (id != null) {\n this.id = this.recycleAsyncId(scheduler, id, null);\n }\n\n this.delay = null!;\n super.unsubscribe();\n }\n }\n}\n", "import { Action } from './scheduler/Action';\nimport { Subscription } from './Subscription';\nimport { SchedulerLike, SchedulerAction } from './types';\nimport { dateTimestampProvider } from './scheduler/dateTimestampProvider';\n\n/**\n * An execution context and a data structure to order tasks and schedule their\n * execution. Provides a notion of (potentially virtual) time, through the\n * `now()` getter method.\n *\n * Each unit of work in a Scheduler is called an `Action`.\n *\n * ```ts\n * class Scheduler {\n * now(): number;\n * schedule(work, delay?, state?): Subscription;\n * }\n * ```\n *\n * @class Scheduler\n * @deprecated Scheduler is an internal implementation detail of RxJS, and\n * should not be used directly. Rather, create your own class and implement\n * {@link SchedulerLike}. Will be made internal in v8.\n */\nexport class Scheduler implements SchedulerLike {\n public static now: () => number = dateTimestampProvider.now;\n\n constructor(private schedulerActionCtor: typeof Action, now: () => number = Scheduler.now) {\n this.now = now;\n }\n\n /**\n * A getter method that returns a number representing the current time\n * (at the time this function was called) according to the scheduler's own\n * internal clock.\n * @return {number} A number that represents the current time. May or may not\n * have a relation to wall-clock time. May or may not refer to a time unit\n * (e.g. milliseconds).\n */\n public now: () => number;\n\n /**\n * Schedules a function, `work`, for execution. May happen at some point in\n * the future, according to the `delay` parameter, if specified. May be passed\n * some context object, `state`, which will be passed to the `work` function.\n *\n * The given arguments will be processed an stored as an Action object in a\n * queue of actions.\n *\n * @param {function(state: ?T): ?Subscription} work A function representing a\n * task, or some unit of work to be executed by the Scheduler.\n * @param {number} [delay] Time to wait before executing the work, where the\n * time unit is implicit and defined by the Scheduler itself.\n * @param {T} [state] Some contextual data that the `work` function uses when\n * called by the Scheduler.\n * @return {Subscription} A subscription in order to be able to unsubscribe\n * the scheduled work.\n */\n public schedule(work: (this: SchedulerAction, state?: T) => void, delay: number = 0, state?: T): Subscription {\n return new this.schedulerActionCtor(this, work).schedule(state, delay);\n }\n}\n", "import { Scheduler } from '../Scheduler';\nimport { Action } from './Action';\nimport { AsyncAction } from './AsyncAction';\nimport { TimerHandle } from './timerHandle';\n\nexport class AsyncScheduler extends Scheduler {\n public actions: Array> = [];\n /**\n * A flag to indicate whether the Scheduler is currently executing a batch of\n * queued actions.\n * @type {boolean}\n * @internal\n */\n public _active: boolean = false;\n /**\n * An internal ID used to track the latest asynchronous task such as those\n * coming from `setTimeout`, `setInterval`, `requestAnimationFrame`, and\n * others.\n * @type {any}\n * @internal\n */\n public _scheduled: TimerHandle | undefined;\n\n constructor(SchedulerAction: typeof Action, now: () => number = Scheduler.now) {\n super(SchedulerAction, now);\n }\n\n public flush(action: AsyncAction): void {\n const { actions } = this;\n\n if (this._active) {\n actions.push(action);\n return;\n }\n\n let error: any;\n this._active = true;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions.shift()!)); // exhaust the scheduler queue\n\n this._active = false;\n\n if (error) {\n while ((action = actions.shift()!)) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\n/**\n *\n * Async Scheduler\n *\n * Schedule task as if you used setTimeout(task, duration)\n *\n * `async` scheduler schedules tasks asynchronously, by putting them on the JavaScript\n * event loop queue. It is best used to delay tasks in time or to schedule tasks repeating\n * in intervals.\n *\n * If you just want to \"defer\" task, that is to perform it right after currently\n * executing synchronous code ends (commonly achieved by `setTimeout(deferredTask, 0)`),\n * better choice will be the {@link asapScheduler} scheduler.\n *\n * ## Examples\n * Use async scheduler to delay task\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * const task = () => console.log('it works!');\n *\n * asyncScheduler.schedule(task, 2000);\n *\n * // After 2 seconds logs:\n * // \"it works!\"\n * ```\n *\n * Use async scheduler to repeat task in intervals\n * ```ts\n * import { asyncScheduler } from 'rxjs';\n *\n * function task(state) {\n * console.log(state);\n * this.schedule(state + 1, 1000); // `this` references currently executing Action,\n * // which we reschedule with new state and delay\n * }\n *\n * asyncScheduler.schedule(task, 3000, 0);\n *\n * // Logs:\n * // 0 after 3s\n * // 1 after 4s\n * // 2 after 5s\n * // 3 after 6s\n * ```\n */\n\nexport const asyncScheduler = new AsyncScheduler(AsyncAction);\n\n/**\n * @deprecated Renamed to {@link asyncScheduler}. Will be removed in v8.\n */\nexport const async = asyncScheduler;\n", "import { AsyncAction } from './AsyncAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\nimport { SchedulerAction } from '../types';\nimport { animationFrameProvider } from './animationFrameProvider';\nimport { TimerHandle } from './timerHandle';\n\nexport class AnimationFrameAction extends AsyncAction {\n constructor(protected scheduler: AnimationFrameScheduler, protected work: (this: SchedulerAction, state?: T) => void) {\n super(scheduler, work);\n }\n\n protected requestAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle {\n // If delay is greater than 0, request as an async action.\n if (delay !== null && delay > 0) {\n return super.requestAsyncId(scheduler, id, delay);\n }\n // Push the action to the end of the scheduler queue.\n scheduler.actions.push(this);\n // If an animation frame has already been requested, don't request another\n // one. If an animation frame hasn't been requested yet, request one. Return\n // the current animation frame request id.\n return scheduler._scheduled || (scheduler._scheduled = animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));\n }\n\n protected recycleAsyncId(scheduler: AnimationFrameScheduler, id?: TimerHandle, delay: number = 0): TimerHandle | undefined {\n // If delay exists and is greater than 0, or if the delay is null (the\n // action wasn't rescheduled) but was originally scheduled as an async\n // action, then recycle as an async action.\n if (delay != null ? delay > 0 : this.delay > 0) {\n return super.recycleAsyncId(scheduler, id, delay);\n }\n // If the scheduler queue has no remaining actions with the same async id,\n // cancel the requested animation frame and set the scheduled flag to\n // undefined so the next AnimationFrameAction will request its own.\n const { actions } = scheduler;\n if (id != null && actions[actions.length - 1]?.id !== id) {\n animationFrameProvider.cancelAnimationFrame(id as number);\n scheduler._scheduled = undefined;\n }\n // Return undefined so the action knows to request a new async id if it's rescheduled.\n return undefined;\n }\n}\n", "import { AsyncAction } from './AsyncAction';\nimport { AsyncScheduler } from './AsyncScheduler';\n\nexport class AnimationFrameScheduler extends AsyncScheduler {\n public flush(action?: AsyncAction): void {\n this._active = true;\n // The async id that effects a call to flush is stored in _scheduled.\n // Before executing an action, it's necessary to check the action's async\n // id to determine whether it's supposed to be executed in the current\n // flush.\n // Previous implementations of this method used a count to determine this,\n // but that was unsound, as actions that are unsubscribed - i.e. cancelled -\n // are removed from the actions array and that can shift actions that are\n // scheduled to be executed in a subsequent flush into positions at which\n // they are executed within the current flush.\n const flushId = this._scheduled;\n this._scheduled = undefined;\n\n const { actions } = this;\n let error: any;\n action = action || actions.shift()!;\n\n do {\n if ((error = action.execute(action.state, action.delay))) {\n break;\n }\n } while ((action = actions[0]) && action.id === flushId && actions.shift());\n\n this._active = false;\n\n if (error) {\n while ((action = actions[0]) && action.id === flushId && actions.shift()) {\n action.unsubscribe();\n }\n throw error;\n }\n }\n}\n", "import { AnimationFrameAction } from './AnimationFrameAction';\nimport { AnimationFrameScheduler } from './AnimationFrameScheduler';\n\n/**\n *\n * Animation Frame Scheduler\n *\n * Perform task when `window.requestAnimationFrame` would fire\n *\n * When `animationFrame` scheduler is used with delay, it will fall back to {@link asyncScheduler} scheduler\n * behaviour.\n *\n * Without delay, `animationFrame` scheduler can be used to create smooth browser animations.\n * It makes sure scheduled task will happen just before next browser content repaint,\n * thus performing animations as efficiently as possible.\n *\n * ## Example\n * Schedule div height animation\n * ```ts\n * // html:
\n * import { animationFrameScheduler } from 'rxjs';\n *\n * const div = document.querySelector('div');\n *\n * animationFrameScheduler.schedule(function(height) {\n * div.style.height = height + \"px\";\n *\n * this.schedule(height + 1); // `this` references currently executing Action,\n * // which we reschedule with new state\n * }, 0, 0);\n *\n * // You will see a div element growing in height\n * ```\n */\n\nexport const animationFrameScheduler = new AnimationFrameScheduler(AnimationFrameAction);\n\n/**\n * @deprecated Renamed to {@link animationFrameScheduler}. Will be removed in v8.\n */\nexport const animationFrame = animationFrameScheduler;\n", "import { Observable } from '../Observable';\nimport { SchedulerLike } from '../types';\n\n/**\n * A simple Observable that emits no items to the Observer and immediately\n * emits a complete notification.\n *\n * Just emits 'complete', and nothing else.\n *\n * ![](empty.png)\n *\n * A simple Observable that only emits the complete notification. It can be used\n * for composing with other Observables, such as in a {@link mergeMap}.\n *\n * ## Examples\n *\n * Log complete notification\n *\n * ```ts\n * import { EMPTY } from 'rxjs';\n *\n * EMPTY.subscribe({\n * next: () => console.log('Next'),\n * complete: () => console.log('Complete!')\n * });\n *\n * // Outputs\n * // Complete!\n * ```\n *\n * Emit the number 7, then complete\n *\n * ```ts\n * import { EMPTY, startWith } from 'rxjs';\n *\n * const result = EMPTY.pipe(startWith(7));\n * result.subscribe(x => console.log(x));\n *\n * // Outputs\n * // 7\n * ```\n *\n * Map and flatten only odd numbers to the sequence `'a'`, `'b'`, `'c'`\n *\n * ```ts\n * import { interval, mergeMap, of, EMPTY } from 'rxjs';\n *\n * const interval$ = interval(1000);\n * const result = interval$.pipe(\n * mergeMap(x => x % 2 === 1 ? of('a', 'b', 'c') : EMPTY),\n * );\n * result.subscribe(x => console.log(x));\n *\n * // Results in the following to the console:\n * // x is equal to the count on the interval, e.g. (0, 1, 2, 3, ...)\n * // x will occur every 1000ms\n * // if x % 2 is equal to 1, print a, b, c (each on its own)\n * // if x % 2 is not equal to 1, nothing will be output\n * ```\n *\n * @see {@link Observable}\n * @see {@link NEVER}\n * @see {@link of}\n * @see {@link throwError}\n */\nexport const EMPTY = new Observable((subscriber) => subscriber.complete());\n\n/**\n * @param scheduler A {@link SchedulerLike} to use for scheduling\n * the emission of the complete notification.\n * @deprecated Replaced with the {@link EMPTY} constant or {@link scheduled} (e.g. `scheduled([], scheduler)`). Will be removed in v8.\n */\nexport function empty(scheduler?: SchedulerLike) {\n return scheduler ? emptyScheduled(scheduler) : EMPTY;\n}\n\nfunction emptyScheduled(scheduler: SchedulerLike) {\n return new Observable((subscriber) => scheduler.schedule(() => subscriber.complete()));\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport function isScheduler(value: any): value is SchedulerLike {\n return value && isFunction(value.schedule);\n}\n", "import { SchedulerLike } from '../types';\nimport { isFunction } from './isFunction';\nimport { isScheduler } from './isScheduler';\n\nfunction last(arr: T[]): T | undefined {\n return arr[arr.length - 1];\n}\n\nexport function popResultSelector(args: any[]): ((...args: unknown[]) => unknown) | undefined {\n return isFunction(last(args)) ? args.pop() : undefined;\n}\n\nexport function popScheduler(args: any[]): SchedulerLike | undefined {\n return isScheduler(last(args)) ? args.pop() : undefined;\n}\n\nexport function popNumber(args: any[], defaultValue: number): number {\n return typeof last(args) === 'number' ? args.pop()! : defaultValue;\n}\n", "export const isArrayLike = ((x: any): x is ArrayLike => x && typeof x.length === 'number' && typeof x !== 'function');", "import { isFunction } from \"./isFunction\";\n\n/**\n * Tests to see if the object is \"thennable\".\n * @param value the object to test\n */\nexport function isPromise(value: any): value is PromiseLike {\n return isFunction(value?.then);\n}\n", "import { InteropObservable } from '../types';\nimport { observable as Symbol_observable } from '../symbol/observable';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being Observable (but not necessary an Rx Observable) */\nexport function isInteropObservable(input: any): input is InteropObservable {\n return isFunction(input[Symbol_observable]);\n}\n", "import { isFunction } from './isFunction';\n\nexport function isAsyncIterable(obj: any): obj is AsyncIterable {\n return Symbol.asyncIterator && isFunction(obj?.[Symbol.asyncIterator]);\n}\n", "/**\n * Creates the TypeError to throw if an invalid object is passed to `from` or `scheduled`.\n * @param input The object that was passed.\n */\nexport function createInvalidObservableTypeError(input: any) {\n // TODO: We should create error codes that can be looked up, so this can be less verbose.\n return new TypeError(\n `You provided ${\n input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`\n } where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`\n );\n}\n", "export function getSymbolIterator(): symbol {\n if (typeof Symbol !== 'function' || !Symbol.iterator) {\n return '@@iterator' as any;\n }\n\n return Symbol.iterator;\n}\n\nexport const iterator = getSymbolIterator();\n", "import { iterator as Symbol_iterator } from '../symbol/iterator';\nimport { isFunction } from './isFunction';\n\n/** Identifies an input as being an Iterable */\nexport function isIterable(input: any): input is Iterable {\n return isFunction(input?.[Symbol_iterator]);\n}\n", "import { ReadableStreamLike } from '../types';\nimport { isFunction } from './isFunction';\n\nexport async function* readableStreamLikeToAsyncGenerator(readableStream: ReadableStreamLike): AsyncGenerator {\n const reader = readableStream.getReader();\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) {\n return;\n }\n yield value!;\n }\n } finally {\n reader.releaseLock();\n }\n}\n\nexport function isReadableStreamLike(obj: any): obj is ReadableStreamLike {\n // We don't want to use instanceof checks because they would return\n // false for instances from another Realm, like an \n * \n *\n * */\n\n.aspect-ratio {\n height: 0;\n position: relative;\n}\n\n.aspect-ratio--16x9 { padding-bottom: 56.25%; }\n.aspect-ratio--9x16 { padding-bottom: 177.77%; }\n\n.aspect-ratio--4x3 { padding-bottom: 75%; }\n.aspect-ratio--3x4 { padding-bottom: 133.33%; }\n\n.aspect-ratio--6x4 { padding-bottom: 66.6%; }\n.aspect-ratio--4x6 { padding-bottom: 150%; }\n\n.aspect-ratio--8x5 { padding-bottom: 62.5%; }\n.aspect-ratio--5x8 { padding-bottom: 160%; }\n\n.aspect-ratio--7x5 { padding-bottom: 71.42%; }\n.aspect-ratio--5x7 { padding-bottom: 140%; }\n\n.aspect-ratio--1x1 { padding-bottom: 100%; }\n\n.aspect-ratio--object {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 100;\n}\n\n@media #{$breakpoint-not-small}{\n .aspect-ratio-ns {\n height: 0;\n position: relative;\n }\n .aspect-ratio--16x9-ns { padding-bottom: 56.25%; }\n .aspect-ratio--9x16-ns { padding-bottom: 177.77%; }\n .aspect-ratio--4x3-ns { padding-bottom: 75%; }\n .aspect-ratio--3x4-ns { padding-bottom: 133.33%; }\n .aspect-ratio--6x4-ns { padding-bottom: 66.6%; }\n .aspect-ratio--4x6-ns { padding-bottom: 150%; }\n .aspect-ratio--8x5-ns { padding-bottom: 62.5%; }\n .aspect-ratio--5x8-ns { padding-bottom: 160%; }\n .aspect-ratio--7x5-ns { padding-bottom: 71.42%; }\n .aspect-ratio--5x7-ns { padding-bottom: 140%; }\n .aspect-ratio--1x1-ns { padding-bottom: 100%; }\n .aspect-ratio--object-ns {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 100;\n }\n}\n\n@media #{$breakpoint-medium}{\n .aspect-ratio-m {\n height: 0;\n position: relative;\n }\n .aspect-ratio--16x9-m { padding-bottom: 56.25%; }\n .aspect-ratio--9x16-m { padding-bottom: 177.77%; }\n .aspect-ratio--4x3-m { padding-bottom: 75%; }\n .aspect-ratio--3x4-m { padding-bottom: 133.33%; }\n .aspect-ratio--6x4-m { padding-bottom: 66.6%; }\n .aspect-ratio--4x6-m { padding-bottom: 150%; }\n .aspect-ratio--8x5-m { padding-bottom: 62.5%; }\n .aspect-ratio--5x8-m { padding-bottom: 160%; }\n .aspect-ratio--7x5-m { padding-bottom: 71.42%; }\n .aspect-ratio--5x7-m { padding-bottom: 140%; }\n .aspect-ratio--1x1-m { padding-bottom: 100%; }\n .aspect-ratio--object-m {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 100;\n }\n}\n\n@media #{$breakpoint-large}{\n .aspect-ratio-l {\n height: 0;\n position: relative;\n }\n .aspect-ratio--16x9-l { padding-bottom: 56.25%; }\n .aspect-ratio--9x16-l { padding-bottom: 177.77%; }\n .aspect-ratio--4x3-l { padding-bottom: 75%; }\n .aspect-ratio--3x4-l { padding-bottom: 133.33%; }\n .aspect-ratio--6x4-l { padding-bottom: 66.6%; }\n .aspect-ratio--4x6-l { padding-bottom: 150%; }\n .aspect-ratio--8x5-l { padding-bottom: 62.5%; }\n .aspect-ratio--5x8-l { padding-bottom: 160%; }\n .aspect-ratio--7x5-l { padding-bottom: 71.42%; }\n .aspect-ratio--5x7-l { padding-bottom: 140%; }\n .aspect-ratio--1x1-l { padding-bottom: 100%; }\n .aspect-ratio--object-l {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: 100;\n }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n IMAGES\n Docs: http://tachyons.io/docs/elements/images/\n\n*/\n\n/* Responsive images! */\n\nimg { max-width: 100%; }\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BACKGROUND SIZE\n Docs: http://tachyons.io/docs/themes/background-size/\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n/*\n Often used in combination with background image set as an inline style\n on an html element.\n*/\n\n .cover { background-size: cover!important; }\n .contain { background-size: contain!important; }\n\n@media #{$breakpoint-not-small} {\n .cover-ns { background-size: cover!important; }\n .contain-ns { background-size: contain!important; }\n}\n\n@media #{$breakpoint-medium} {\n .cover-m { background-size: cover!important; }\n .contain-m { background-size: contain!important; }\n}\n\n@media #{$breakpoint-large} {\n .cover-l { background-size: cover!important; }\n .contain-l { background-size: contain!important; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BACKGROUND POSITION\n\n Base:\n bg = background\n\n Modifiers:\n -center = center center\n -top = top center\n -right = center right\n -bottom = bottom center\n -left = center left\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n */\n\n.bg-center { \n background-repeat: no-repeat;\n background-position: center center; \n}\n\n.bg-top { \n background-repeat: no-repeat; \n background-position: top center; \n}\n\n.bg-right { \n background-repeat: no-repeat; \n background-position: center right; \n}\n\n.bg-bottom { \n background-repeat: no-repeat; \n background-position: bottom center; \n}\n\n.bg-left { \n background-repeat: no-repeat; \n background-position: center left; \n}\n\n@media #{$breakpoint-not-small} {\n .bg-center-ns { \n background-repeat: no-repeat;\n background-position: center center; \n }\n\n .bg-top-ns { \n background-repeat: no-repeat; \n background-position: top center; \n }\n\n .bg-right-ns { \n background-repeat: no-repeat; \n background-position: center right; \n }\n\n .bg-bottom-ns { \n background-repeat: no-repeat; \n background-position: bottom center; \n }\n\n .bg-left-ns { \n background-repeat: no-repeat; \n background-position: center left; \n }\n}\n\n@media #{$breakpoint-medium} {\n .bg-center-m { \n background-repeat: no-repeat;\n background-position: center center; \n }\n\n .bg-top-m { \n background-repeat: no-repeat; \n background-position: top center; \n }\n\n .bg-right-m { \n background-repeat: no-repeat; \n background-position: center right; \n }\n\n .bg-bottom-m { \n background-repeat: no-repeat; \n background-position: bottom center; \n }\n\n .bg-left-m { \n background-repeat: no-repeat; \n background-position: center left; \n }\n}\n\n@media #{$breakpoint-large} {\n .bg-center-l { \n background-repeat: no-repeat;\n background-position: center center; \n }\n\n .bg-top-l { \n background-repeat: no-repeat; \n background-position: top center; \n }\n\n .bg-right-l { \n background-repeat: no-repeat; \n background-position: center right; \n }\n\n .bg-bottom-l { \n background-repeat: no-repeat; \n background-position: bottom center; \n }\n\n .bg-left-l { \n background-repeat: no-repeat; \n background-position: center left; \n }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n OUTLINES\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.outline { outline: 1px solid; }\n.outline-transparent { outline: 1px solid transparent; }\n.outline-0 { outline: 0; }\n\n@media #{$breakpoint-not-small} {\n .outline-ns { outline: 1px solid; }\n .outline-transparent-ns { outline: 1px solid transparent; }\n .outline-0-ns { outline: 0; }\n}\n\n@media #{$breakpoint-medium} {\n .outline-m { outline: 1px solid; }\n .outline-transparent-m { outline: 1px solid transparent; }\n .outline-0-m { outline: 0; }\n}\n\n@media #{$breakpoint-large} {\n .outline-l { outline: 1px solid; }\n .outline-transparent-l { outline: 1px solid transparent; }\n .outline-0-l { outline: 0; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BORDERS\n Docs: http://tachyons.io/docs/themes/borders/\n\n Base:\n b = border\n\n Modifiers:\n a = all\n t = top\n r = right\n b = bottom\n l = left\n n = none\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n .ba { border-style: solid; border-width: 1px; }\n .bt { border-top-style: solid; border-top-width: 1px; }\n .br { border-right-style: solid; border-right-width: 1px; }\n .bb { border-bottom-style: solid; border-bottom-width: 1px; }\n .bl { border-left-style: solid; border-left-width: 1px; }\n .bn { border-style: none; border-width: 0; }\n\n\n@media #{$breakpoint-not-small} {\n .ba-ns { border-style: solid; border-width: 1px; }\n .bt-ns { border-top-style: solid; border-top-width: 1px; }\n .br-ns { border-right-style: solid; border-right-width: 1px; }\n .bb-ns { border-bottom-style: solid; border-bottom-width: 1px; }\n .bl-ns { border-left-style: solid; border-left-width: 1px; }\n .bn-ns { border-style: none; border-width: 0; }\n}\n\n@media #{$breakpoint-medium} {\n .ba-m { border-style: solid; border-width: 1px; }\n .bt-m { border-top-style: solid; border-top-width: 1px; }\n .br-m { border-right-style: solid; border-right-width: 1px; }\n .bb-m { border-bottom-style: solid; border-bottom-width: 1px; }\n .bl-m { border-left-style: solid; border-left-width: 1px; }\n .bn-m { border-style: none; border-width: 0; }\n}\n\n@media #{$breakpoint-large} {\n .ba-l { border-style: solid; border-width: 1px; }\n .bt-l { border-top-style: solid; border-top-width: 1px; }\n .br-l { border-right-style: solid; border-right-width: 1px; }\n .bb-l { border-bottom-style: solid; border-bottom-width: 1px; }\n .bl-l { border-left-style: solid; border-left-width: 1px; }\n .bn-l { border-style: none; border-width: 0; }\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BORDER COLORS\n Docs: http://tachyons.io/docs/themes/borders/\n\n Border colors can be used to extend the base\n border classes ba,bt,bb,br,bl found in the _borders.css file.\n\n The base border class by default will set the color of the border\n to that of the current text color. These classes are for the cases\n where you desire for the text and border colors to be different.\n\n Base:\n b = border\n\n Modifiers:\n --color-name = each color variable name is also a border color name\n\n*/\n\n.b--black { border-color: $black; }\n.b--near-black { border-color: $near-black; }\n.b--dark-gray { border-color: $dark-gray; }\n.b--mid-gray { border-color: $mid-gray; }\n.b--gray { border-color: $gray; }\n.b--silver { border-color: $silver; }\n.b--light-silver { border-color: $light-silver; }\n.b--moon-gray { border-color: $moon-gray; }\n.b--light-gray { border-color: $light-gray; }\n.b--near-white { border-color: $near-white; }\n.b--white { border-color: $white; }\n\n.b--white-90 { border-color: $white-90; }\n.b--white-80 { border-color: $white-80; }\n.b--white-70 { border-color: $white-70; }\n.b--white-60 { border-color: $white-60; }\n.b--white-50 { border-color: $white-50; }\n.b--white-40 { border-color: $white-40; }\n.b--white-30 { border-color: $white-30; }\n.b--white-20 { border-color: $white-20; }\n.b--white-10 { border-color: $white-10; }\n.b--white-05 { border-color: $white-05; }\n.b--white-025 { border-color: $white-025; }\n.b--white-0125 { border-color: $white-0125; }\n\n.b--black-90 { border-color: $black-90; }\n.b--black-80 { border-color: $black-80; }\n.b--black-70 { border-color: $black-70; }\n.b--black-60 { border-color: $black-60; }\n.b--black-50 { border-color: $black-50; }\n.b--black-40 { border-color: $black-40; }\n.b--black-30 { border-color: $black-30; }\n.b--black-20 { border-color: $black-20; }\n.b--black-10 { border-color: $black-10; }\n.b--black-05 { border-color: $black-05; }\n.b--black-025 { border-color: $black-025; }\n.b--black-0125 { border-color: $black-0125; }\n\n.b--dark-red { border-color: $dark-red; }\n.b--red { border-color: $red; }\n.b--light-red { border-color: $light-red; }\n.b--orange { border-color: $orange; }\n.b--gold { border-color: $gold; }\n.b--yellow { border-color: $yellow; }\n.b--light-yellow { border-color: $light-yellow; }\n.b--purple { border-color: $purple; }\n.b--light-purple { border-color: $light-purple; }\n.b--dark-pink { border-color: $dark-pink; }\n.b--hot-pink { border-color: $hot-pink; }\n.b--pink { border-color: $pink; }\n.b--light-pink { border-color: $light-pink; }\n.b--dark-green { border-color: $dark-green; }\n.b--green { border-color: $green; }\n.b--light-green { border-color: $light-green; }\n.b--navy { border-color: $navy; }\n.b--dark-blue { border-color: $dark-blue; }\n.b--blue { border-color: $blue; }\n.b--light-blue { border-color: $light-blue; }\n.b--lightest-blue { border-color: $lightest-blue; }\n.b--washed-blue { border-color: $washed-blue; }\n.b--washed-green { border-color: $washed-green; }\n.b--washed-yellow { border-color: $washed-yellow; }\n.b--washed-red { border-color: $washed-red; }\n\n.b--transparent { border-color: $transparent; }\n.b--inherit { border-color: inherit; }\n","\n// Converted Variables\n\n$sans-serif: -apple-system, BlinkMacSystemFont, 'avenir next', avenir, helvetica, 'helvetica neue', ubuntu, roboto, noto, 'segoe ui', arial, sans-serif !default;\n$serif: georgia, serif !default;\n$code: consolas, monaco, monospace !default;\n$font-size-headline: 6rem !default;\n$font-size-subheadline: 5rem !default;\n$font-size-1: 3rem !default;\n$font-size-2: 2.25rem !default;\n$font-size-3: 1.5rem !default;\n$font-size-4: 1.25rem !default;\n$font-size-5: 1rem !default;\n$font-size-6: .875rem !default;\n$font-size-7: .75rem !default;\n$letter-spacing-tight: -.05em !default;\n$letter-spacing-1: .1em !default;\n$letter-spacing-2: .25em !default;\n$line-height-solid: 1 !default;\n$line-height-title: 1.25 !default;\n$line-height-copy: 1.5 !default;\n$measure: 30em !default;\n$measure-narrow: 20em !default;\n$measure-wide: 34em !default;\n$spacing-none: 0 !default;\n$spacing-extra-small: .25rem !default;\n$spacing-small: .5rem !default;\n$spacing-medium: 1rem !default;\n$spacing-large: 2rem !default;\n$spacing-extra-large: 4rem !default;\n$spacing-extra-extra-large: 8rem !default;\n$spacing-extra-extra-extra-large: 16rem !default;\n$spacing-copy-separator: 1.5em !default;\n$height-1: 1rem !default;\n$height-2: 2rem !default;\n$height-3: 4rem !default;\n$height-4: 8rem !default;\n$height-5: 16rem !default;\n$width-1: 1rem !default;\n$width-2: 2rem !default;\n$width-3: 4rem !default;\n$width-4: 8rem !default;\n$width-5: 16rem !default;\n$max-width-1: 1rem !default;\n$max-width-2: 2rem !default;\n$max-width-3: 4rem !default;\n$max-width-4: 8rem !default;\n$max-width-5: 16rem !default;\n$max-width-6: 32rem !default;\n$max-width-7: 48rem !default;\n$max-width-8: 64rem !default;\n$max-width-9: 96rem !default;\n$border-radius-none: 0 !default;\n$border-radius-1: .125rem !default;\n$border-radius-2: .25rem !default;\n$border-radius-3: .5rem !default;\n$border-radius-4: 1rem !default;\n$border-radius-circle: 100% !default;\n$border-radius-pill: 9999px !default;\n$border-width-none: 0 !default;\n$border-width-1: .125rem !default;\n$border-width-2: .25rem !default;\n$border-width-3: .5rem !default;\n$border-width-4: 1rem !default;\n$border-width-5: 2rem !default;\n$box-shadow-1: 0px 0px 4px 2px rgba( 0, 0, 0, 0.2 ) !default;\n$box-shadow-2: 0px 0px 8px 2px rgba( 0, 0, 0, 0.2 ) !default;\n$box-shadow-3: 2px 2px 4px 2px rgba( 0, 0, 0, 0.2 ) !default;\n$box-shadow-4: 2px 2px 8px 0px rgba( 0, 0, 0, 0.2 ) !default;\n$box-shadow-5: 4px 4px 8px 0px rgba( 0, 0, 0, 0.2 ) !default;\n$black: #000 !default;\n$near-black: #111 !default;\n$dark-gray: #333 !default;\n$mid-gray: #555 !default;\n$gray: #777 !default;\n$silver: #999 !default;\n$light-silver: #aaa !default;\n$moon-gray: #ccc !default;\n$light-gray: #eee !default;\n$near-white: #f4f4f4 !default;\n$white: #fff !default;\n$transparent: transparent !default;\n$black-90: rgba(0,0,0,.9) !default;\n$black-80: rgba(0,0,0,.8) !default;\n$black-70: rgba(0,0,0,.7) !default;\n$black-60: rgba(0,0,0,.6) !default;\n$black-50: rgba(0,0,0,.5) !default;\n$black-40: rgba(0,0,0,.4) !default;\n$black-30: rgba(0,0,0,.3) !default;\n$black-20: rgba(0,0,0,.2) !default;\n$black-10: rgba(0,0,0,.1) !default;\n$black-05: rgba(0,0,0,.05) !default;\n$black-025: rgba(0,0,0,.025) !default;\n$black-0125: rgba(0,0,0,.0125) !default;\n$white-90: rgba(255,255,255,.9) !default;\n$white-80: rgba(255,255,255,.8) !default;\n$white-70: rgba(255,255,255,.7) !default;\n$white-60: rgba(255,255,255,.6) !default;\n$white-50: rgba(255,255,255,.5) !default;\n$white-40: rgba(255,255,255,.4) !default;\n$white-30: rgba(255,255,255,.3) !default;\n$white-20: rgba(255,255,255,.2) !default;\n$white-10: rgba(255,255,255,.1) !default;\n$white-05: rgba(255,255,255,.05) !default;\n$white-025: rgba(255,255,255,.025) !default;\n$white-0125: rgba(255,255,255,.0125) !default;\n$dark-red: #e7040f !default;\n$red: #ff4136 !default;\n$light-red: #ff725c !default;\n$orange: #ff6300 !default;\n$gold: #ffb700 !default;\n$yellow: #ffd700 !default;\n$light-yellow: #fbf1a9 !default;\n$purple: #5e2ca5 !default;\n$light-purple: #a463f2 !default;\n$dark-pink: #d5008f !default;\n$hot-pink: #ff41b4 !default;\n$pink: #ff80cc !default;\n$light-pink: #ffa3d7 !default;\n$dark-green: #137752 !default;\n$green: #19a974 !default;\n$light-green: #9eebcf !default;\n$navy: #001b44 !default;\n$dark-blue: #00449e !default;\n$blue: #357edd !default;\n$light-blue: #96ccff !default;\n$lightest-blue: #cdecff !default;\n$washed-blue: #f6fffe !default;\n$washed-green: #e8fdf5 !default;\n$washed-yellow: #fffceb !default;\n$washed-red: #ffdfdf !default;\n\n// Custom Media Query Variables\n\n$breakpoint-not-small: 'screen and (min-width: 30em)' !default;\n$breakpoint-medium: 'screen and (min-width: 30em) and (max-width: 60em)' !default;\n$breakpoint-large: 'screen and (min-width: 60em)' !default;\n\n/*\n\n VARIABLES\n\n*/\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BORDER RADIUS\n Docs: http://tachyons.io/docs/themes/border-radius/\n\n Base:\n br = border-radius\n\n Modifiers:\n 0 = 0/none\n 1 = 1st step in scale\n 2 = 2nd step in scale\n 3 = 3rd step in scale\n 4 = 4th step in scale\n\n Literal values:\n -100 = 100%\n -pill = 9999px\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n .br0 { border-radius: $border-radius-none }\n .br1 { border-radius: $border-radius-1; }\n .br2 { border-radius: $border-radius-2; }\n .br3 { border-radius: $border-radius-3; }\n .br4 { border-radius: $border-radius-4; }\n .br-100 { border-radius: $border-radius-circle; }\n .br-pill { border-radius: $border-radius-pill; }\n .br--bottom {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n .br--top {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n .br--right {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .br--left {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n@media #{$breakpoint-not-small} {\n .br0-ns { border-radius: $border-radius-none }\n .br1-ns { border-radius: $border-radius-1; }\n .br2-ns { border-radius: $border-radius-2; }\n .br3-ns { border-radius: $border-radius-3; }\n .br4-ns { border-radius: $border-radius-4; }\n .br-100-ns { border-radius: $border-radius-circle; }\n .br-pill-ns { border-radius: $border-radius-pill; }\n .br--bottom-ns {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n .br--top-ns {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n .br--right-ns {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .br--left-ns {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n}\n\n@media #{$breakpoint-medium} {\n .br0-m { border-radius: $border-radius-none }\n .br1-m { border-radius: $border-radius-1; }\n .br2-m { border-radius: $border-radius-2; }\n .br3-m { border-radius: $border-radius-3; }\n .br4-m { border-radius: $border-radius-4; }\n .br-100-m { border-radius: $border-radius-circle; }\n .br-pill-m { border-radius: $border-radius-pill; }\n .br--bottom-m {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n .br--top-m {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n .br--right-m {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .br--left-m {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n}\n\n@media #{$breakpoint-large} {\n .br0-l { border-radius: $border-radius-none }\n .br1-l { border-radius: $border-radius-1; }\n .br2-l { border-radius: $border-radius-2; }\n .br3-l { border-radius: $border-radius-3; }\n .br4-l { border-radius: $border-radius-4; }\n .br-100-l { border-radius: $border-radius-circle; }\n .br-pill-l { border-radius: $border-radius-pill; }\n .br--bottom-l {\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n .br--top-l {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n }\n .br--right-l {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n .br--left-l {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BORDER STYLES\n Docs: http://tachyons.io/docs/themes/borders/\n\n Depends on base border module in _borders.css\n\n Base:\n b = border-style\n\n Modifiers:\n --none = none\n --dotted = dotted\n --dashed = dashed\n --solid = solid\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n */\n\n.b--dotted { border-style: dotted; }\n.b--dashed { border-style: dashed; }\n.b--solid { border-style: solid; }\n.b--none { border-style: none; }\n\n@media #{$breakpoint-not-small} {\n .b--dotted-ns { border-style: dotted; }\n .b--dashed-ns { border-style: dashed; }\n .b--solid-ns { border-style: solid; }\n .b--none-ns { border-style: none; }\n}\n\n@media #{$breakpoint-medium} {\n .b--dotted-m { border-style: dotted; }\n .b--dashed-m { border-style: dashed; }\n .b--solid-m { border-style: solid; }\n .b--none-m { border-style: none; }\n}\n\n@media #{$breakpoint-large} {\n .b--dotted-l { border-style: dotted; }\n .b--dashed-l { border-style: dashed; }\n .b--solid-l { border-style: solid; }\n .b--none-l { border-style: none; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BORDER WIDTHS\n Docs: http://tachyons.io/docs/themes/borders/\n\n Base:\n bw = border-width\n\n Modifiers:\n 0 = 0 width border\n 1 = 1st step in border-width scale\n 2 = 2nd step in border-width scale\n 3 = 3rd step in border-width scale\n 4 = 4th step in border-width scale\n 5 = 5th step in border-width scale\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.bw0 { border-width: $border-width-none; }\n.bw1 { border-width: $border-width-1; }\n.bw2 { border-width: $border-width-2; }\n.bw3 { border-width: $border-width-3; }\n.bw4 { border-width: $border-width-4; }\n.bw5 { border-width: $border-width-5; }\n\n/* Resets */\n.bt-0 { border-top-width: $border-width-none }\n.br-0 { border-right-width: $border-width-none }\n.bb-0 { border-bottom-width: $border-width-none }\n.bl-0 { border-left-width: $border-width-none }\n\n@media #{$breakpoint-not-small} {\n .bw0-ns { border-width: $border-width-none; }\n .bw1-ns { border-width: $border-width-1; }\n .bw2-ns { border-width: $border-width-2; }\n .bw3-ns { border-width: $border-width-3; }\n .bw4-ns { border-width: $border-width-4; }\n .bw5-ns { border-width: $border-width-5; }\n .bt-0-ns { border-top-width: $border-width-none }\n .br-0-ns { border-right-width: $border-width-none }\n .bb-0-ns { border-bottom-width: $border-width-none }\n .bl-0-ns { border-left-width: $border-width-none }\n}\n\n@media #{$breakpoint-medium} {\n .bw0-m { border-width: $border-width-none; }\n .bw1-m { border-width: $border-width-1; }\n .bw2-m { border-width: $border-width-2; }\n .bw3-m { border-width: $border-width-3; }\n .bw4-m { border-width: $border-width-4; }\n .bw5-m { border-width: $border-width-5; }\n .bt-0-m { border-top-width: $border-width-none }\n .br-0-m { border-right-width: $border-width-none }\n .bb-0-m { border-bottom-width: $border-width-none }\n .bl-0-m { border-left-width: $border-width-none }\n}\n\n@media #{$breakpoint-large} {\n .bw0-l { border-width: $border-width-none; }\n .bw1-l { border-width: $border-width-1; }\n .bw2-l { border-width: $border-width-2; }\n .bw3-l { border-width: $border-width-3; }\n .bw4-l { border-width: $border-width-4; }\n .bw5-l { border-width: $border-width-5; }\n .bt-0-l { border-top-width: $border-width-none }\n .br-0-l { border-right-width: $border-width-none }\n .bb-0-l { border-bottom-width: $border-width-none }\n .bl-0-l { border-left-width: $border-width-none }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n BOX-SHADOW\n Docs: http://tachyons.io/docs/themes/box-shadow/\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n */\n\n.shadow-1 { box-shadow: $box-shadow-1; }\n.shadow-2 { box-shadow: $box-shadow-2; }\n.shadow-3 { box-shadow: $box-shadow-3; }\n.shadow-4 { box-shadow: $box-shadow-4; }\n.shadow-5 { box-shadow: $box-shadow-5; }\n\n@media #{$breakpoint-not-small} {\n .shadow-1-ns { box-shadow: $box-shadow-1; }\n .shadow-2-ns { box-shadow: $box-shadow-2; }\n .shadow-3-ns { box-shadow: $box-shadow-3; }\n .shadow-4-ns { box-shadow: $box-shadow-4; }\n .shadow-5-ns { box-shadow: $box-shadow-5; }\n}\n\n@media #{$breakpoint-medium} {\n .shadow-1-m { box-shadow: $box-shadow-1; }\n .shadow-2-m { box-shadow: $box-shadow-2; }\n .shadow-3-m { box-shadow: $box-shadow-3; }\n .shadow-4-m { box-shadow: $box-shadow-4; }\n .shadow-5-m { box-shadow: $box-shadow-5; }\n}\n\n@media #{$breakpoint-large} {\n .shadow-1-l { box-shadow: $box-shadow-1; }\n .shadow-2-l { box-shadow: $box-shadow-2; }\n .shadow-3-l { box-shadow: $box-shadow-3; }\n .shadow-4-l { box-shadow: $box-shadow-4; }\n .shadow-5-l { box-shadow: $box-shadow-5; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n CODE\n\n*/\n\n.pre {\n overflow-x: auto;\n overflow-y: hidden;\n overflow: scroll;\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n COORDINATES\n Docs: http://tachyons.io/docs/layout/position/\n\n Use in combination with the position module.\n\n Base:\n top\n bottom\n right\n left\n\n Modifiers:\n -0 = literal value 0\n -1 = literal value 1\n -2 = literal value 2\n --1 = literal value -1\n --2 = literal value -2\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.top-0 { top: 0; }\n.right-0 { right: 0; }\n.bottom-0 { bottom: 0; }\n.left-0 { left: 0; }\n\n.top-1 { top: 1rem; }\n.right-1 { right: 1rem; }\n.bottom-1 { bottom: 1rem; }\n.left-1 { left: 1rem; }\n\n.top-2 { top: 2rem; }\n.right-2 { right: 2rem; }\n.bottom-2 { bottom: 2rem; }\n.left-2 { left: 2rem; }\n\n.top--1 { top: -1rem; }\n.right--1 { right: -1rem; }\n.bottom--1 { bottom: -1rem; }\n.left--1 { left: -1rem; }\n\n.top--2 { top: -2rem; }\n.right--2 { right: -2rem; }\n.bottom--2 { bottom: -2rem; }\n.left--2 { left: -2rem; }\n\n\n.absolute--fill {\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n}\n\n@media #{$breakpoint-not-small} {\n .top-0-ns { top: 0; }\n .left-0-ns { left: 0; }\n .right-0-ns { right: 0; }\n .bottom-0-ns { bottom: 0; }\n .top-1-ns { top: 1rem; }\n .left-1-ns { left: 1rem; }\n .right-1-ns { right: 1rem; }\n .bottom-1-ns { bottom: 1rem; }\n .top-2-ns { top: 2rem; }\n .left-2-ns { left: 2rem; }\n .right-2-ns { right: 2rem; }\n .bottom-2-ns { bottom: 2rem; }\n .top--1-ns { top: -1rem; }\n .right--1-ns { right: -1rem; }\n .bottom--1-ns { bottom: -1rem; }\n .left--1-ns { left: -1rem; }\n .top--2-ns { top: -2rem; }\n .right--2-ns { right: -2rem; }\n .bottom--2-ns { bottom: -2rem; }\n .left--2-ns { left: -2rem; }\n .absolute--fill-ns {\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n}\n\n@media #{$breakpoint-medium} {\n .top-0-m { top: 0; }\n .left-0-m { left: 0; }\n .right-0-m { right: 0; }\n .bottom-0-m { bottom: 0; }\n .top-1-m { top: 1rem; }\n .left-1-m { left: 1rem; }\n .right-1-m { right: 1rem; }\n .bottom-1-m { bottom: 1rem; }\n .top-2-m { top: 2rem; }\n .left-2-m { left: 2rem; }\n .right-2-m { right: 2rem; }\n .bottom-2-m { bottom: 2rem; }\n .top--1-m { top: -1rem; }\n .right--1-m { right: -1rem; }\n .bottom--1-m { bottom: -1rem; }\n .left--1-m { left: -1rem; }\n .top--2-m { top: -2rem; }\n .right--2-m { right: -2rem; }\n .bottom--2-m { bottom: -2rem; }\n .left--2-m { left: -2rem; }\n .absolute--fill-m {\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n}\n\n@media #{$breakpoint-large} {\n .top-0-l { top: 0; }\n .left-0-l { left: 0; }\n .right-0-l { right: 0; }\n .bottom-0-l { bottom: 0; }\n .top-1-l { top: 1rem; }\n .left-1-l { left: 1rem; }\n .right-1-l { right: 1rem; }\n .bottom-1-l { bottom: 1rem; }\n .top-2-l { top: 2rem; }\n .left-2-l { left: 2rem; }\n .right-2-l { right: 2rem; }\n .bottom-2-l { bottom: 2rem; }\n .top--1-l { top: -1rem; }\n .right--1-l { right: -1rem; }\n .bottom--1-l { bottom: -1rem; }\n .left--1-l { left: -1rem; }\n .top--2-l { top: -2rem; }\n .right--2-l { right: -2rem; }\n .bottom--2-l { bottom: -2rem; }\n .left--2-l { left: -2rem; }\n .absolute--fill-l {\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n CLEARFIX\n http://tachyons.io/docs/layout/clearfix/\n\n*/\n\n/* Nicolas Gallaghers Clearfix solution\n Ref: http://nicolasgallagher.com/micro-clearfix-hack/ */\n\n.cf:before,\n.cf:after { content: \" \"; display: table; }\n.cf:after { clear: both; }\n.cf { zoom: 1; }\n\n.cl { clear: left; }\n.cr { clear: right; }\n.cb { clear: both; }\n.cn { clear: none; }\n\n@media #{$breakpoint-not-small} {\n .cl-ns { clear: left; }\n .cr-ns { clear: right; }\n .cb-ns { clear: both; }\n .cn-ns { clear: none; }\n}\n\n@media #{$breakpoint-medium} {\n .cl-m { clear: left; }\n .cr-m { clear: right; }\n .cb-m { clear: both; }\n .cn-m { clear: none; }\n}\n\n@media #{$breakpoint-large} {\n .cl-l { clear: left; }\n .cr-l { clear: right; }\n .cb-l { clear: both; }\n .cn-l { clear: none; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n FLEXBOX\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.flex { display: flex; }\n.inline-flex { display: inline-flex; }\n\n/* 1. Fix for Chrome 44 bug.\n * https://code.google.com/p/chromium/issues/detail?id=506893 */\n.flex-auto {\n flex: 1 1 auto;\n min-width: 0; /* 1 */\n min-height: 0; /* 1 */\n}\n\n.flex-none { flex: none; }\n\n.flex-column { flex-direction: column; }\n.flex-row { flex-direction: row; }\n.flex-wrap { flex-wrap: wrap; }\n.flex-nowrap { flex-wrap: nowrap; }\n.flex-wrap-reverse { flex-wrap: wrap-reverse; }\n.flex-column-reverse { flex-direction: column-reverse; }\n.flex-row-reverse { flex-direction: row-reverse; }\n\n.items-start { align-items: flex-start; }\n.items-end { align-items: flex-end; }\n.items-center { align-items: center; }\n.items-baseline { align-items: baseline; }\n.items-stretch { align-items: stretch; }\n\n.self-start { align-self: flex-start; }\n.self-end { align-self: flex-end; }\n.self-center { align-self: center; }\n.self-baseline { align-self: baseline; }\n.self-stretch { align-self: stretch; }\n\n.justify-start { justify-content: flex-start; }\n.justify-end { justify-content: flex-end; }\n.justify-center { justify-content: center; }\n.justify-between { justify-content: space-between; }\n.justify-around { justify-content: space-around; }\n\n.content-start { align-content: flex-start; }\n.content-end { align-content: flex-end; }\n.content-center { align-content: center; }\n.content-between { align-content: space-between; }\n.content-around { align-content: space-around; }\n.content-stretch { align-content: stretch; }\n\n.order-0 { order: 0; }\n.order-1 { order: 1; }\n.order-2 { order: 2; }\n.order-3 { order: 3; }\n.order-4 { order: 4; }\n.order-5 { order: 5; }\n.order-6 { order: 6; }\n.order-7 { order: 7; }\n.order-8 { order: 8; }\n.order-last { order: 99999; }\n\n.flex-grow-0 { flex-grow: 0; }\n.flex-grow-1 { flex-grow: 1; }\n\n.flex-shrink-0 { flex-shrink: 0; }\n.flex-shrink-1 { flex-shrink: 1; }\n\n@media #{$breakpoint-not-small} {\n .flex-ns { display: flex; }\n .inline-flex-ns { display: inline-flex; }\n .flex-auto-ns {\n flex: 1 1 auto;\n min-width: 0; /* 1 */\n min-height: 0; /* 1 */\n }\n .flex-none-ns { flex: none; }\n .flex-column-ns { flex-direction: column; }\n .flex-row-ns { flex-direction: row; }\n .flex-wrap-ns { flex-wrap: wrap; }\n .flex-nowrap-ns { flex-wrap: nowrap; }\n .flex-wrap-reverse-ns { flex-wrap: wrap-reverse; }\n .flex-column-reverse-ns { flex-direction: column-reverse; }\n .flex-row-reverse-ns { flex-direction: row-reverse; }\n .items-start-ns { align-items: flex-start; }\n .items-end-ns { align-items: flex-end; }\n .items-center-ns { align-items: center; }\n .items-baseline-ns { align-items: baseline; }\n .items-stretch-ns { align-items: stretch; }\n\n .self-start-ns { align-self: flex-start; }\n .self-end-ns { align-self: flex-end; }\n .self-center-ns { align-self: center; }\n .self-baseline-ns { align-self: baseline; }\n .self-stretch-ns { align-self: stretch; }\n\n .justify-start-ns { justify-content: flex-start; }\n .justify-end-ns { justify-content: flex-end; }\n .justify-center-ns { justify-content: center; }\n .justify-between-ns { justify-content: space-between; }\n .justify-around-ns { justify-content: space-around; }\n\n .content-start-ns { align-content: flex-start; }\n .content-end-ns { align-content: flex-end; }\n .content-center-ns { align-content: center; }\n .content-between-ns { align-content: space-between; }\n .content-around-ns { align-content: space-around; }\n .content-stretch-ns { align-content: stretch; }\n\n .order-0-ns { order: 0; }\n .order-1-ns { order: 1; }\n .order-2-ns { order: 2; }\n .order-3-ns { order: 3; }\n .order-4-ns { order: 4; }\n .order-5-ns { order: 5; }\n .order-6-ns { order: 6; }\n .order-7-ns { order: 7; }\n .order-8-ns { order: 8; }\n .order-last-ns { order: 99999; }\n\n .flex-grow-0-ns { flex-grow: 0; }\n .flex-grow-1-ns { flex-grow: 1; }\n\n .flex-shrink-0-ns { flex-shrink: 0; }\n .flex-shrink-1-ns { flex-shrink: 1; }\n}\n@media #{$breakpoint-medium} {\n .flex-m { display: flex; }\n .inline-flex-m { display: inline-flex; }\n .flex-auto-m {\n flex: 1 1 auto;\n min-width: 0; /* 1 */\n min-height: 0; /* 1 */\n }\n .flex-none-m { flex: none; }\n .flex-column-m { flex-direction: column; }\n .flex-row-m { flex-direction: row; }\n .flex-wrap-m { flex-wrap: wrap; }\n .flex-nowrap-m { flex-wrap: nowrap; }\n .flex-wrap-reverse-m { flex-wrap: wrap-reverse; }\n .flex-column-reverse-m { flex-direction: column-reverse; }\n .flex-row-reverse-m { flex-direction: row-reverse; }\n .items-start-m { align-items: flex-start; }\n .items-end-m { align-items: flex-end; }\n .items-center-m { align-items: center; }\n .items-baseline-m { align-items: baseline; }\n .items-stretch-m { align-items: stretch; }\n\n .self-start-m { align-self: flex-start; }\n .self-end-m { align-self: flex-end; }\n .self-center-m { align-self: center; }\n .self-baseline-m { align-self: baseline; }\n .self-stretch-m { align-self: stretch; }\n\n .justify-start-m { justify-content: flex-start; }\n .justify-end-m { justify-content: flex-end; }\n .justify-center-m { justify-content: center; }\n .justify-between-m { justify-content: space-between; }\n .justify-around-m { justify-content: space-around; }\n\n .content-start-m { align-content: flex-start; }\n .content-end-m { align-content: flex-end; }\n .content-center-m { align-content: center; }\n .content-between-m { align-content: space-between; }\n .content-around-m { align-content: space-around; }\n .content-stretch-m { align-content: stretch; }\n\n .order-0-m { order: 0; }\n .order-1-m { order: 1; }\n .order-2-m { order: 2; }\n .order-3-m { order: 3; }\n .order-4-m { order: 4; }\n .order-5-m { order: 5; }\n .order-6-m { order: 6; }\n .order-7-m { order: 7; }\n .order-8-m { order: 8; }\n .order-last-m { order: 99999; }\n\n .flex-grow-0-m { flex-grow: 0; }\n .flex-grow-1-m { flex-grow: 1; }\n\n .flex-shrink-0-m { flex-shrink: 0; }\n .flex-shrink-1-m { flex-shrink: 1; }\n}\n\n@media #{$breakpoint-large} {\n .flex-l { display: flex; }\n .inline-flex-l { display: inline-flex; }\n .flex-auto-l {\n flex: 1 1 auto;\n min-width: 0; /* 1 */\n min-height: 0; /* 1 */\n }\n .flex-none-l { flex: none; }\n .flex-column-l { flex-direction: column; }\n .flex-row-l { flex-direction: row; }\n .flex-wrap-l { flex-wrap: wrap; }\n .flex-nowrap-l { flex-wrap: nowrap; }\n .flex-wrap-reverse-l { flex-wrap: wrap-reverse; }\n .flex-column-reverse-l { flex-direction: column-reverse; }\n .flex-row-reverse-l { flex-direction: row-reverse; }\n\n .items-start-l { align-items: flex-start; }\n .items-end-l { align-items: flex-end; }\n .items-center-l { align-items: center; }\n .items-baseline-l { align-items: baseline; }\n .items-stretch-l { align-items: stretch; }\n\n .self-start-l { align-self: flex-start; }\n .self-end-l { align-self: flex-end; }\n .self-center-l { align-self: center; }\n .self-baseline-l { align-self: baseline; }\n .self-stretch-l { align-self: stretch; }\n\n .justify-start-l { justify-content: flex-start; }\n .justify-end-l { justify-content: flex-end; }\n .justify-center-l { justify-content: center; }\n .justify-between-l { justify-content: space-between; }\n .justify-around-l { justify-content: space-around; }\n\n .content-start-l { align-content: flex-start; }\n .content-end-l { align-content: flex-end; }\n .content-center-l { align-content: center; }\n .content-between-l { align-content: space-between; }\n .content-around-l { align-content: space-around; }\n .content-stretch-l { align-content: stretch; }\n\n .order-0-l { order: 0; }\n .order-1-l { order: 1; }\n .order-2-l { order: 2; }\n .order-3-l { order: 3; }\n .order-4-l { order: 4; }\n .order-5-l { order: 5; }\n .order-6-l { order: 6; }\n .order-7-l { order: 7; }\n .order-8-l { order: 8; }\n .order-last-l { order: 99999; }\n\n .flex-grow-0-l { flex-grow: 0; }\n .flex-grow-1-l { flex-grow: 1; }\n\n .flex-shrink-0-l { flex-shrink: 0; }\n .flex-shrink-1-l { flex-shrink: 1; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n DISPLAY\n Docs: http://tachyons.io/docs/layout/display\n\n Base:\n d = display\n\n Modifiers:\n n = none\n b = block\n ib = inline-block\n it = inline-table\n t = table\n tc = table-cell\n tr = table-row\n tcol = table-column\n tcolg = table-column-group\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.dn { display: none; }\n.di { display: inline; }\n.db { display: block; }\n.dib { display: inline-block; }\n.dit { display: inline-table; }\n.dt { display: table; }\n.dtc { display: table-cell; }\n.dt-row { display: table-row; }\n.dt-row-group { display: table-row-group; }\n.dt-column { display: table-column; }\n.dt-column-group { display: table-column-group; }\n\n/*\n This will set table to full width and then\n all cells will be equal width\n*/\n.dt--fixed {\n table-layout: fixed;\n width: 100%;\n}\n\n@media #{$breakpoint-not-small} {\n .dn-ns { display: none; }\n .di-ns { display: inline; }\n .db-ns { display: block; }\n .dib-ns { display: inline-block; }\n .dit-ns { display: inline-table; }\n .dt-ns { display: table; }\n .dtc-ns { display: table-cell; }\n .dt-row-ns { display: table-row; }\n .dt-row-group-ns { display: table-row-group; }\n .dt-column-ns { display: table-column; }\n .dt-column-group-ns { display: table-column-group; }\n\n .dt--fixed-ns {\n table-layout: fixed;\n width: 100%;\n }\n}\n\n@media #{$breakpoint-medium} {\n .dn-m { display: none; }\n .di-m { display: inline; }\n .db-m { display: block; }\n .dib-m { display: inline-block; }\n .dit-m { display: inline-table; }\n .dt-m { display: table; }\n .dtc-m { display: table-cell; }\n .dt-row-m { display: table-row; }\n .dt-row-group-m { display: table-row-group; }\n .dt-column-m { display: table-column; }\n .dt-column-group-m { display: table-column-group; }\n\n .dt--fixed-m {\n table-layout: fixed;\n width: 100%;\n }\n}\n\n@media #{$breakpoint-large} {\n .dn-l { display: none; }\n .di-l { display: inline; }\n .db-l { display: block; }\n .dib-l { display: inline-block; }\n .dit-l { display: inline-table; }\n .dt-l { display: table; }\n .dtc-l { display: table-cell; }\n .dt-row-l { display: table-row; }\n .dt-row-group-l { display: table-row-group; }\n .dt-column-l { display: table-column; }\n .dt-column-group-l { display: table-column-group; }\n\n .dt--fixed-l {\n table-layout: fixed;\n width: 100%;\n }\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n FLOATS\n http://tachyons.io/docs/layout/floats/\n\n 1. Floated elements are automatically rendered as block level elements.\n Setting floats to display inline will fix the double margin bug in\n ie6. You know... just in case.\n\n 2. Don't forget to clearfix your floats with .cf\n\n Base:\n f = float\n\n Modifiers:\n l = left\n r = right\n n = none\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n\n\n.fl { float: left; _display: inline; }\n.fr { float: right; _display: inline; }\n.fn { float: none; }\n\n@media #{$breakpoint-not-small} {\n .fl-ns { float: left; _display: inline; }\n .fr-ns { float: right; _display: inline; }\n .fn-ns { float: none; }\n}\n\n@media #{$breakpoint-medium} {\n .fl-m { float: left; _display: inline; }\n .fr-m { float: right; _display: inline; }\n .fn-m { float: none; }\n}\n\n@media #{$breakpoint-large} {\n .fl-l { float: left; _display: inline; }\n .fr-l { float: right; _display: inline; }\n .fn-l { float: none; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n FONT FAMILY GROUPS\n Docs: http://tachyons.io/docs/typography/font-family/\n\n*/\n\n\n.sans-serif {\n font-family: $sans-serif;\n}\n\n.serif {\n font-family: $serif;\n}\n\n.system-sans-serif {\n font-family: sans-serif;\n}\n\n.system-serif {\n font-family: serif;\n}\n\n\n/* Monospaced Typefaces (for code) */\n\n/* From http://cssfontstack.com */\ncode, .code {\n font-family: Consolas,\n monaco,\n monospace;\n}\n\n.courier {\n font-family: 'Courier Next',\n courier,\n monospace;\n}\n\n\n/* Sans-Serif Typefaces */\n\n.helvetica {\n font-family: 'helvetica neue', helvetica,\n sans-serif;\n}\n\n.avenir {\n font-family: 'avenir next', avenir,\n sans-serif;\n}\n\n\n/* Serif Typefaces */\n\n.athelas {\n font-family: athelas,\n georgia,\n serif;\n}\n\n.georgia {\n font-family: georgia,\n serif;\n}\n\n.times {\n font-family: times,\n serif;\n}\n\n.bodoni {\n font-family: \"Bodoni MT\",\n serif;\n}\n\n.calisto {\n font-family: \"Calisto MT\",\n serif;\n}\n\n.garamond {\n font-family: garamond,\n serif;\n}\n\n.baskerville {\n font-family: baskerville,\n serif;\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n FONT STYLE\n Docs: http://tachyons.io/docs/typography/font-style/\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.i { font-style: italic; }\n.fs-normal { font-style: normal; }\n\n@media #{$breakpoint-not-small} {\n .i-ns { font-style: italic; }\n .fs-normal-ns { font-style: normal; }\n}\n\n@media #{$breakpoint-medium} {\n .i-m { font-style: italic; }\n .fs-normal-m { font-style: normal; }\n}\n\n@media #{$breakpoint-large} {\n .i-l { font-style: italic; }\n .fs-normal-l { font-style: normal; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n FONT WEIGHT\n Docs: http://tachyons.io/docs/typography/font-weight/\n\n Base\n fw = font-weight\n\n Modifiers:\n 1 = literal value 100\n 2 = literal value 200\n 3 = literal value 300\n 4 = literal value 400\n 5 = literal value 500\n 6 = literal value 600\n 7 = literal value 700\n 8 = literal value 800\n 9 = literal value 900\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.normal { font-weight: normal; }\n.b { font-weight: bold; }\n.fw1 { font-weight: 100; }\n.fw2 { font-weight: 200; }\n.fw3 { font-weight: 300; }\n.fw4 { font-weight: 400; }\n.fw5 { font-weight: 500; }\n.fw6 { font-weight: 600; }\n.fw7 { font-weight: 700; }\n.fw8 { font-weight: 800; }\n.fw9 { font-weight: 900; }\n\n\n@media #{$breakpoint-not-small} {\n .normal-ns { font-weight: normal; }\n .b-ns { font-weight: bold; }\n .fw1-ns { font-weight: 100; }\n .fw2-ns { font-weight: 200; }\n .fw3-ns { font-weight: 300; }\n .fw4-ns { font-weight: 400; }\n .fw5-ns { font-weight: 500; }\n .fw6-ns { font-weight: 600; }\n .fw7-ns { font-weight: 700; }\n .fw8-ns { font-weight: 800; }\n .fw9-ns { font-weight: 900; }\n}\n\n@media #{$breakpoint-medium} {\n .normal-m { font-weight: normal; }\n .b-m { font-weight: bold; }\n .fw1-m { font-weight: 100; }\n .fw2-m { font-weight: 200; }\n .fw3-m { font-weight: 300; }\n .fw4-m { font-weight: 400; }\n .fw5-m { font-weight: 500; }\n .fw6-m { font-weight: 600; }\n .fw7-m { font-weight: 700; }\n .fw8-m { font-weight: 800; }\n .fw9-m { font-weight: 900; }\n}\n\n@media #{$breakpoint-large} {\n .normal-l { font-weight: normal; }\n .b-l { font-weight: bold; }\n .fw1-l { font-weight: 100; }\n .fw2-l { font-weight: 200; }\n .fw3-l { font-weight: 300; }\n .fw4-l { font-weight: 400; }\n .fw5-l { font-weight: 500; }\n .fw6-l { font-weight: 600; }\n .fw7-l { font-weight: 700; }\n .fw8-l { font-weight: 800; }\n .fw9-l { font-weight: 900; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n FORMS\n \n*/\n\n.input-reset {\n -webkit-appearance: none;\n -moz-appearance: none;\n}\n\n.button-reset::-moz-focus-inner,\n.input-reset::-moz-focus-inner {\n border: 0;\n padding: 0;\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n HEIGHTS\n Docs: http://tachyons.io/docs/layout/heights/\n\n Base:\n h = height\n min-h = min-height\n min-vh = min-height vertical screen height\n vh = vertical screen height\n\n Modifiers\n 1 = 1st step in height scale\n 2 = 2nd step in height scale\n 3 = 3rd step in height scale\n 4 = 4th step in height scale\n 5 = 5th step in height scale\n\n -25 = literal value 25%\n -50 = literal value 50%\n -75 = literal value 75%\n -100 = literal value 100%\n\n -auto = string value of auto\n -inherit = string value of inherit\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n/* Height Scale */\n\n.h1 { height: $height-1; }\n.h2 { height: $height-2; }\n.h3 { height: $height-3; }\n.h4 { height: $height-4; }\n.h5 { height: $height-5; }\n\n/* Height Percentages - Based off of height of parent */\n\n.h-25 { height: 25%; }\n.h-50 { height: 50%; }\n.h-75 { height: 75%; }\n.h-100 { height: 100%; }\n\n.min-h-100 { min-height: 100%; }\n\n/* Screen Height Percentage */\n\n.vh-25 { height: 25vh; }\n.vh-50 { height: 50vh; }\n.vh-75 { height: 75vh; }\n.vh-100 { height: 100vh; }\n\n.min-vh-100 { min-height: 100vh; }\n\n\n/* String Properties */\n\n.h-auto { height: auto; }\n.h-inherit { height: inherit; }\n\n@media #{$breakpoint-not-small} {\n .h1-ns { height: $height-1; }\n .h2-ns { height: $height-2; }\n .h3-ns { height: $height-3; }\n .h4-ns { height: $height-4; }\n .h5-ns { height: $height-5; }\n .h-25-ns { height: 25%; }\n .h-50-ns { height: 50%; }\n .h-75-ns { height: 75%; }\n .h-100-ns { height: 100%; }\n .min-h-100-ns { min-height: 100%; }\n .vh-25-ns { height: 25vh; }\n .vh-50-ns { height: 50vh; }\n .vh-75-ns { height: 75vh; }\n .vh-100-ns { height: 100vh; }\n .min-vh-100-ns { min-height: 100vh; }\n .h-auto-ns { height: auto; }\n .h-inherit-ns { height: inherit; }\n}\n\n@media #{$breakpoint-medium} {\n .h1-m { height: $height-1; }\n .h2-m { height: $height-2; }\n .h3-m { height: $height-3; }\n .h4-m { height: $height-4; }\n .h5-m { height: $height-5; }\n .h-25-m { height: 25%; }\n .h-50-m { height: 50%; }\n .h-75-m { height: 75%; }\n .h-100-m { height: 100%; }\n .min-h-100-m { min-height: 100%; }\n .vh-25-m { height: 25vh; }\n .vh-50-m { height: 50vh; }\n .vh-75-m { height: 75vh; }\n .vh-100-m { height: 100vh; }\n .min-vh-100-m { min-height: 100vh; }\n .h-auto-m { height: auto; }\n .h-inherit-m { height: inherit; }\n}\n\n@media #{$breakpoint-large} {\n .h1-l { height: $height-1; }\n .h2-l { height: $height-2; }\n .h3-l { height: $height-3; }\n .h4-l { height: $height-4; }\n .h5-l { height: $height-5; }\n .h-25-l { height: 25%; }\n .h-50-l { height: 50%; }\n .h-75-l { height: 75%; }\n .h-100-l { height: 100%; }\n .min-h-100-l { min-height: 100%; }\n .vh-25-l { height: 25vh; }\n .vh-50-l { height: 50vh; }\n .vh-75-l { height: 75vh; }\n .vh-100-l { height: 100vh; }\n .min-vh-100-l { min-height: 100vh; }\n .h-auto-l { height: auto; }\n .h-inherit-l { height: inherit; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n LETTER SPACING\n Docs: http://tachyons.io/docs/typography/tracking/\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.tracked { letter-spacing: $letter-spacing-1; }\n.tracked-tight { letter-spacing: $letter-spacing-tight; }\n.tracked-mega { letter-spacing: $letter-spacing-2; }\n\n@media #{$breakpoint-not-small} {\n .tracked-ns { letter-spacing: $letter-spacing-1; }\n .tracked-tight-ns { letter-spacing: $letter-spacing-tight; }\n .tracked-mega-ns { letter-spacing: $letter-spacing-2; }\n}\n\n@media #{$breakpoint-medium} {\n .tracked-m { letter-spacing: $letter-spacing-1; }\n .tracked-tight-m { letter-spacing: $letter-spacing-tight; }\n .tracked-mega-m { letter-spacing: $letter-spacing-2; }\n}\n\n@media #{$breakpoint-large} {\n .tracked-l { letter-spacing: $letter-spacing-1; }\n .tracked-tight-l { letter-spacing: $letter-spacing-tight; }\n .tracked-mega-l { letter-spacing: $letter-spacing-2; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n LINE HEIGHT / LEADING\n Docs: http://tachyons.io/docs/typography/line-height\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n .lh-solid { line-height: $line-height-solid; }\n .lh-title { line-height: $line-height-title; }\n .lh-copy { line-height: $line-height-copy; }\n\n@media #{$breakpoint-not-small} {\n .lh-solid-ns { line-height: $line-height-solid; }\n .lh-title-ns { line-height: $line-height-title; }\n .lh-copy-ns { line-height: $line-height-copy; }\n}\n\n@media #{$breakpoint-medium} {\n .lh-solid-m { line-height: $line-height-solid; }\n .lh-title-m { line-height: $line-height-title; }\n .lh-copy-m { line-height: $line-height-copy; }\n}\n\n@media #{$breakpoint-large} {\n .lh-solid-l { line-height: $line-height-solid; }\n .lh-title-l { line-height: $line-height-title; }\n .lh-copy-l { line-height: $line-height-copy; }\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n LINKS\n Docs: http://tachyons.io/docs/elements/links/\n\n*/\n\n.link {\n text-decoration: none;\n transition: color .15s ease-in;\n}\n\n.link:link,\n.link:visited {\n transition: color .15s ease-in;\n}\n.link:hover {\n transition: color .15s ease-in;\n}\n.link:active {\n transition: color .15s ease-in;\n}\n.link:focus {\n transition: color .15s ease-in;\n outline: 1px dotted currentColor;\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n LISTS\n http://tachyons.io/docs/elements/lists/\n\n*/\n\n.list { list-style-type: none; }\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n MAX WIDTHS\n Docs: http://tachyons.io/docs/layout/max-widths/\n\n Base:\n mw = max-width\n\n Modifiers\n 1 = 1st step in width scale\n 2 = 2nd step in width scale\n 3 = 3rd step in width scale\n 4 = 4th step in width scale\n 5 = 5th step in width scale\n 6 = 6st step in width scale\n 7 = 7nd step in width scale\n 8 = 8rd step in width scale\n 9 = 9th step in width scale\n\n -100 = literal value 100%\n\n -none = string value none\n\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n/* Max Width Percentages */\n\n.mw-100 { max-width: 100%; }\n\n/* Max Width Scale */\n\n.mw1 { max-width: $max-width-1; }\n.mw2 { max-width: $max-width-2; }\n.mw3 { max-width: $max-width-3; }\n.mw4 { max-width: $max-width-4; }\n.mw5 { max-width: $max-width-5; }\n.mw6 { max-width: $max-width-6; }\n.mw7 { max-width: $max-width-7; }\n.mw8 { max-width: $max-width-8; }\n.mw9 { max-width: $max-width-9; }\n\n/* Max Width String Properties */\n\n.mw-none { max-width: none; }\n\n@media #{$breakpoint-not-small} {\n .mw-100-ns { max-width: 100%; }\n\n .mw1-ns { max-width: $max-width-1; }\n .mw2-ns { max-width: $max-width-2; }\n .mw3-ns { max-width: $max-width-3; }\n .mw4-ns { max-width: $max-width-4; }\n .mw5-ns { max-width: $max-width-5; }\n .mw6-ns { max-width: $max-width-6; }\n .mw7-ns { max-width: $max-width-7; }\n .mw8-ns { max-width: $max-width-8; }\n .mw9-ns { max-width: $max-width-9; }\n\n .mw-none-ns { max-width: none; }\n}\n\n@media #{$breakpoint-medium} {\n .mw-100-m { max-width: 100%; }\n\n .mw1-m { max-width: $max-width-1; }\n .mw2-m { max-width: $max-width-2; }\n .mw3-m { max-width: $max-width-3; }\n .mw4-m { max-width: $max-width-4; }\n .mw5-m { max-width: $max-width-5; }\n .mw6-m { max-width: $max-width-6; }\n .mw7-m { max-width: $max-width-7; }\n .mw8-m { max-width: $max-width-8; }\n .mw9-m { max-width: $max-width-9; }\n\n .mw-none-m { max-width: none; }\n}\n\n@media #{$breakpoint-large} {\n .mw-100-l { max-width: 100%; }\n\n .mw1-l { max-width: $max-width-1; }\n .mw2-l { max-width: $max-width-2; }\n .mw3-l { max-width: $max-width-3; }\n .mw4-l { max-width: $max-width-4; }\n .mw5-l { max-width: $max-width-5; }\n .mw6-l { max-width: $max-width-6; }\n .mw7-l { max-width: $max-width-7; }\n .mw8-l { max-width: $max-width-8; }\n .mw9-l { max-width: $max-width-9; }\n\n .mw-none-l { max-width: none; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n WIDTHS\n Docs: http://tachyons.io/docs/layout/widths/\n\n Base:\n w = width\n\n Modifiers\n 1 = 1st step in width scale\n 2 = 2nd step in width scale\n 3 = 3rd step in width scale\n 4 = 4th step in width scale\n 5 = 5th step in width scale\n\n -10 = literal value 10%\n -20 = literal value 20%\n -25 = literal value 25%\n -30 = literal value 30%\n -33 = literal value 33%\n -34 = literal value 34%\n -40 = literal value 40%\n -50 = literal value 50%\n -60 = literal value 60%\n -70 = literal value 70%\n -75 = literal value 75%\n -80 = literal value 80%\n -90 = literal value 90%\n -100 = literal value 100%\n\n -third = 100% / 3 (Not supported in opera mini or IE8)\n -two-thirds = 100% / 1.5 (Not supported in opera mini or IE8)\n -auto = string value auto\n\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n */\n\n/* Width Scale */\n\n.w1 { width: $width-1; }\n.w2 { width: $width-2; }\n.w3 { width: $width-3; }\n.w4 { width: $width-4; }\n.w5 { width: $width-5; }\n\n.w-10 { width: 10%; }\n.w-20 { width: 20%; }\n.w-25 { width: 25%; }\n.w-30 { width: 30%; }\n.w-33 { width: 33%; }\n.w-34 { width: 34%; }\n.w-40 { width: 40%; }\n.w-50 { width: 50%; }\n.w-60 { width: 60%; }\n.w-70 { width: 70%; }\n.w-75 { width: 75%; }\n.w-80 { width: 80%; }\n.w-90 { width: 90%; }\n.w-100 { width: 100%; }\n\n.w-third { width: (100% / 3); }\n.w-two-thirds { width: (100% / 1.5); }\n.w-auto { width: auto; }\n\n@media #{$breakpoint-not-small} {\n .w1-ns { width: $width-1; }\n .w2-ns { width: $width-2; }\n .w3-ns { width: $width-3; }\n .w4-ns { width: $width-4; }\n .w5-ns { width: $width-5; }\n .w-10-ns { width: 10%; }\n .w-20-ns { width: 20%; }\n .w-25-ns { width: 25%; }\n .w-30-ns { width: 30%; }\n .w-33-ns { width: 33%; }\n .w-34-ns { width: 34%; }\n .w-40-ns { width: 40%; }\n .w-50-ns { width: 50%; }\n .w-60-ns { width: 60%; }\n .w-70-ns { width: 70%; }\n .w-75-ns { width: 75%; }\n .w-80-ns { width: 80%; }\n .w-90-ns { width: 90%; }\n .w-100-ns { width: 100%; }\n .w-third-ns { width: (100% / 3); }\n .w-two-thirds-ns { width: (100% / 1.5); }\n .w-auto-ns { width: auto; }\n}\n\n@media #{$breakpoint-medium} {\n .w1-m { width: $width-1; }\n .w2-m { width: $width-2; }\n .w3-m { width: $width-3; }\n .w4-m { width: $width-4; }\n .w5-m { width: $width-5; }\n .w-10-m { width: 10%; }\n .w-20-m { width: 20%; }\n .w-25-m { width: 25%; }\n .w-30-m { width: 30%; }\n .w-33-m { width: 33%; }\n .w-34-m { width: 34%; }\n .w-40-m { width: 40%; }\n .w-50-m { width: 50%; }\n .w-60-m { width: 60%; }\n .w-70-m { width: 70%; }\n .w-75-m { width: 75%; }\n .w-80-m { width: 80%; }\n .w-90-m { width: 90%; }\n .w-100-m { width: 100%; }\n .w-third-m { width: (100% / 3); }\n .w-two-thirds-m { width: (100% / 1.5); }\n .w-auto-m { width: auto; }\n}\n\n@media #{$breakpoint-large} {\n .w1-l { width: $width-1; }\n .w2-l { width: $width-2; }\n .w3-l { width: $width-3; }\n .w4-l { width: $width-4; }\n .w5-l { width: $width-5; }\n .w-10-l { width: 10%; }\n .w-20-l { width: 20%; }\n .w-25-l { width: 25%; }\n .w-30-l { width: 30%; }\n .w-33-l { width: 33%; }\n .w-34-l { width: 34%; }\n .w-40-l { width: 40%; }\n .w-50-l { width: 50%; }\n .w-60-l { width: 60%; }\n .w-70-l { width: 70%; }\n .w-75-l { width: 75%; }\n .w-80-l { width: 80%; }\n .w-90-l { width: 90%; }\n .w-100-l { width: 100%; }\n .w-third-l { width: (100% / 3); }\n .w-two-thirds-l { width: (100% / 1.5); }\n .w-auto-l { width: auto; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n OVERFLOW\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n */\n\n.overflow-visible { overflow: visible; }\n.overflow-hidden { overflow: hidden; }\n.overflow-scroll { overflow: scroll; }\n.overflow-auto { overflow: auto; }\n\n.overflow-x-visible { overflow-x: visible; }\n.overflow-x-hidden { overflow-x: hidden; }\n.overflow-x-scroll { overflow-x: scroll; }\n.overflow-x-auto { overflow-x: auto; }\n\n.overflow-y-visible { overflow-y: visible; }\n.overflow-y-hidden { overflow-y: hidden; }\n.overflow-y-scroll { overflow-y: scroll; }\n.overflow-y-auto { overflow-y: auto; }\n\n@media #{$breakpoint-not-small} {\n .overflow-visible-ns { overflow: visible; }\n .overflow-hidden-ns { overflow: hidden; }\n .overflow-scroll-ns { overflow: scroll; }\n .overflow-auto-ns { overflow: auto; }\n .overflow-x-visible-ns { overflow-x: visible; }\n .overflow-x-hidden-ns { overflow-x: hidden; }\n .overflow-x-scroll-ns { overflow-x: scroll; }\n .overflow-x-auto-ns { overflow-x: auto; }\n\n .overflow-y-visible-ns { overflow-y: visible; }\n .overflow-y-hidden-ns { overflow-y: hidden; }\n .overflow-y-scroll-ns { overflow-y: scroll; }\n .overflow-y-auto-ns { overflow-y: auto; }\n}\n\n@media #{$breakpoint-medium} {\n .overflow-visible-m { overflow: visible; }\n .overflow-hidden-m { overflow: hidden; }\n .overflow-scroll-m { overflow: scroll; }\n .overflow-auto-m { overflow: auto; }\n\n .overflow-x-visible-m { overflow-x: visible; }\n .overflow-x-hidden-m { overflow-x: hidden; }\n .overflow-x-scroll-m { overflow-x: scroll; }\n .overflow-x-auto-m { overflow-x: auto; }\n\n .overflow-y-visible-m { overflow-y: visible; }\n .overflow-y-hidden-m { overflow-y: hidden; }\n .overflow-y-scroll-m { overflow-y: scroll; }\n .overflow-y-auto-m { overflow-y: auto; }\n}\n\n@media #{$breakpoint-large} {\n .overflow-visible-l { overflow: visible; }\n .overflow-hidden-l { overflow: hidden; }\n .overflow-scroll-l { overflow: scroll; }\n .overflow-auto-l { overflow: auto; }\n\n .overflow-x-visible-l { overflow-x: visible; }\n .overflow-x-hidden-l { overflow-x: hidden; }\n .overflow-x-scroll-l { overflow-x: scroll; }\n .overflow-x-auto-l { overflow-x: auto; }\n\n .overflow-y-visible-l { overflow-y: visible; }\n .overflow-y-hidden-l { overflow-y: hidden; }\n .overflow-y-scroll-l { overflow-y: scroll; }\n .overflow-y-auto-l { overflow-y: auto; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n POSITIONING\n Docs: http://tachyons.io/docs/layout/position/\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.static { position: static; }\n.relative { position: relative; }\n.absolute { position: absolute; }\n.fixed { position: fixed; }\n\n@media #{$breakpoint-not-small} {\n .static-ns { position: static; }\n .relative-ns { position: relative; }\n .absolute-ns { position: absolute; }\n .fixed-ns { position: fixed; }\n}\n\n@media #{$breakpoint-medium} {\n .static-m { position: static; }\n .relative-m { position: relative; }\n .absolute-m { position: absolute; }\n .fixed-m { position: fixed; }\n}\n\n@media #{$breakpoint-large} {\n .static-l { position: static; }\n .relative-l { position: relative; }\n .absolute-l { position: absolute; }\n .fixed-l { position: fixed; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n OPACITY\n Docs: http://tachyons.io/docs/themes/opacity/\n\n*/\n\n.o-100 { opacity: 1; }\n.o-90 { opacity: .9; }\n.o-80 { opacity: .8; }\n.o-70 { opacity: .7; }\n.o-60 { opacity: .6; }\n.o-50 { opacity: .5; }\n.o-40 { opacity: .4; }\n.o-30 { opacity: .3; }\n.o-20 { opacity: .2; }\n.o-10 { opacity: .1; }\n.o-05 { opacity: .05; }\n.o-025 { opacity: .025; }\n.o-0 { opacity: 0; }\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n ROTATIONS\n\n*/\n\n.rotate-45 { transform: rotate(45deg); }\n.rotate-90 { transform: rotate(90deg); }\n.rotate-135 { transform: rotate(135deg); }\n.rotate-180 { transform: rotate(180deg); }\n.rotate-225 { transform: rotate(225deg); }\n.rotate-270 { transform: rotate(270deg); }\n.rotate-315 { transform: rotate(315deg); }\n\n@media #{$breakpoint-not-small}{\n .rotate-45-ns { transform: rotate(45deg); }\n .rotate-90-ns { transform: rotate(90deg); }\n .rotate-135-ns { transform: rotate(135deg); }\n .rotate-180-ns { transform: rotate(180deg); }\n .rotate-225-ns { transform: rotate(225deg); }\n .rotate-270-ns { transform: rotate(270deg); }\n .rotate-315-ns { transform: rotate(315deg); }\n}\n\n@media #{$breakpoint-medium}{\n .rotate-45-m { transform: rotate(45deg); }\n .rotate-90-m { transform: rotate(90deg); }\n .rotate-135-m { transform: rotate(135deg); }\n .rotate-180-m { transform: rotate(180deg); }\n .rotate-225-m { transform: rotate(225deg); }\n .rotate-270-m { transform: rotate(270deg); }\n .rotate-315-m { transform: rotate(315deg); }\n}\n\n@media #{$breakpoint-large}{\n .rotate-45-l { transform: rotate(45deg); }\n .rotate-90-l { transform: rotate(90deg); }\n .rotate-135-l { transform: rotate(135deg); }\n .rotate-180-l { transform: rotate(180deg); }\n .rotate-225-l { transform: rotate(225deg); }\n .rotate-270-l { transform: rotate(270deg); }\n .rotate-315-l { transform: rotate(315deg); }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n SKINS\n Docs: http://tachyons.io/docs/themes/skins/\n\n Classes for setting foreground and background colors on elements.\n If you haven't declared a border color, but set border on an element, it will\n be set to the current text color.\n\n*/\n\n/* Text colors */\n\n.black-90 { color: $black-90; }\n.black-80 { color: $black-80; }\n.black-70 { color: $black-70; }\n.black-60 { color: $black-60; }\n.black-50 { color: $black-50; }\n.black-40 { color: $black-40; }\n.black-30 { color: $black-30; }\n.black-20 { color: $black-20; }\n.black-10 { color: $black-10; }\n.black-05 { color: $black-05; }\n\n.white-90 { color: $white-90; }\n.white-80 { color: $white-80; }\n.white-70 { color: $white-70; }\n.white-60 { color: $white-60; }\n.white-50 { color: $white-50; }\n.white-40 { color: $white-40; }\n.white-30 { color: $white-30; }\n.white-20 { color: $white-20; }\n.white-10 { color: $white-10; }\n\n.black { color: $black; }\n.near-black { color: $near-black; }\n.dark-gray { color: $dark-gray; }\n.mid-gray { color: $mid-gray; }\n.gray { color: $gray; }\n.silver { color: $silver; }\n.light-silver { color: $light-silver; }\n.moon-gray { color: $moon-gray; }\n.light-gray { color: $light-gray; }\n.near-white { color: $near-white; }\n.white { color: $white; }\n\n.dark-red { color: $dark-red; }\n.red { color: $red; }\n.light-red { color: $light-red; }\n.orange { color: $orange; }\n.gold { color: $gold; }\n.yellow { color: $yellow; }\n.light-yellow { color: $light-yellow; }\n.purple { color: $purple; }\n.light-purple { color: $light-purple; }\n.dark-pink { color: $dark-pink; }\n.hot-pink { color: $hot-pink; }\n.pink { color: $pink; }\n.light-pink { color: $light-pink; }\n.dark-green { color: $dark-green; }\n.green { color: $green; }\n.light-green { color: $light-green; }\n.navy { color: $navy; }\n.dark-blue { color: $dark-blue; }\n.blue { color: $blue; }\n.light-blue { color: $light-blue; }\n.lightest-blue { color: $lightest-blue; }\n.washed-blue { color: $washed-blue; }\n.washed-green { color: $washed-green; }\n.washed-yellow { color: $washed-yellow; }\n.washed-red { color: $washed-red; }\n.color-inherit { color: inherit; }\n\n.bg-black-90 { background-color: $black-90; }\n.bg-black-80 { background-color: $black-80; }\n.bg-black-70 { background-color: $black-70; }\n.bg-black-60 { background-color: $black-60; }\n.bg-black-50 { background-color: $black-50; }\n.bg-black-40 { background-color: $black-40; }\n.bg-black-30 { background-color: $black-30; }\n.bg-black-20 { background-color: $black-20; }\n.bg-black-10 { background-color: $black-10; }\n.bg-black-05 { background-color: $black-05; }\n.bg-white-90 { background-color: $white-90; }\n.bg-white-80 { background-color: $white-80; }\n.bg-white-70 { background-color: $white-70; }\n.bg-white-60 { background-color: $white-60; }\n.bg-white-50 { background-color: $white-50; }\n.bg-white-40 { background-color: $white-40; }\n.bg-white-30 { background-color: $white-30; }\n.bg-white-20 { background-color: $white-20; }\n.bg-white-10 { background-color: $white-10; }\n\n\n\n/* Background colors */\n\n.bg-black { background-color: $black; }\n.bg-near-black { background-color: $near-black; }\n.bg-dark-gray { background-color: $dark-gray; }\n.bg-mid-gray { background-color: $mid-gray; }\n.bg-gray { background-color: $gray; }\n.bg-silver { background-color: $silver; }\n.bg-light-silver { background-color: $light-silver; }\n.bg-moon-gray { background-color: $moon-gray; }\n.bg-light-gray { background-color: $light-gray; }\n.bg-near-white { background-color: $near-white; }\n.bg-white { background-color: $white; }\n.bg-transparent { background-color: $transparent; }\n\n.bg-dark-red { background-color: $dark-red; }\n.bg-red { background-color: $red; }\n.bg-light-red { background-color: $light-red; }\n.bg-orange { background-color: $orange; }\n.bg-gold { background-color: $gold; }\n.bg-yellow { background-color: $yellow; }\n.bg-light-yellow { background-color: $light-yellow; }\n.bg-purple { background-color: $purple; }\n.bg-light-purple { background-color: $light-purple; }\n.bg-dark-pink { background-color: $dark-pink; }\n.bg-hot-pink { background-color: $hot-pink; }\n.bg-pink { background-color: $pink; }\n.bg-light-pink { background-color: $light-pink; }\n.bg-dark-green { background-color: $dark-green; }\n.bg-green { background-color: $green; }\n.bg-light-green { background-color: $light-green; }\n.bg-navy { background-color: $navy; }\n.bg-dark-blue { background-color: $dark-blue; }\n.bg-blue { background-color: $blue; }\n.bg-light-blue { background-color: $light-blue; }\n.bg-lightest-blue { background-color: $lightest-blue; }\n.bg-washed-blue { background-color: $washed-blue; }\n.bg-washed-green { background-color: $washed-green; }\n.bg-washed-yellow { background-color: $washed-yellow; }\n.bg-washed-red { background-color: $washed-red; }\n.bg-inherit { background-color: inherit; }\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n SKINS:PSEUDO\n\n Customize the color of an element when\n it is focused or hovered over.\n\n */\n\n.hover-black:hover,\n.hover-black:focus { color: $black; }\n.hover-near-black:hover,\n.hover-near-black:focus { color: $near-black; }\n.hover-dark-gray:hover,\n.hover-dark-gray:focus { color: $dark-gray; }\n.hover-mid-gray:hover,\n.hover-mid-gray:focus { color: $mid-gray; }\n.hover-gray:hover,\n.hover-gray:focus { color: $gray; }\n.hover-silver:hover,\n.hover-silver:focus { color: $silver; }\n.hover-light-silver:hover,\n.hover-light-silver:focus { color: $light-silver; }\n.hover-moon-gray:hover,\n.hover-moon-gray:focus { color: $moon-gray; }\n.hover-light-gray:hover,\n.hover-light-gray:focus { color: $light-gray; }\n.hover-near-white:hover,\n.hover-near-white:focus { color: $near-white; }\n.hover-white:hover,\n.hover-white:focus { color: $white; }\n\n.hover-black-90:hover,\n.hover-black-90:focus { color: $black-90; }\n.hover-black-80:hover,\n.hover-black-80:focus { color: $black-80; }\n.hover-black-70:hover,\n.hover-black-70:focus { color: $black-70; }\n.hover-black-60:hover,\n.hover-black-60:focus { color: $black-60; }\n.hover-black-50:hover,\n.hover-black-50:focus { color: $black-50; }\n.hover-black-40:hover,\n.hover-black-40:focus { color: $black-40; }\n.hover-black-30:hover,\n.hover-black-30:focus { color: $black-30; }\n.hover-black-20:hover,\n.hover-black-20:focus { color: $black-20; }\n.hover-black-10:hover,\n.hover-black-10:focus { color: $black-10; }\n.hover-white-90:hover,\n.hover-white-90:focus { color: $white-90; }\n.hover-white-80:hover,\n.hover-white-80:focus { color: $white-80; }\n.hover-white-70:hover,\n.hover-white-70:focus { color: $white-70; }\n.hover-white-60:hover,\n.hover-white-60:focus { color: $white-60; }\n.hover-white-50:hover,\n.hover-white-50:focus { color: $white-50; }\n.hover-white-40:hover,\n.hover-white-40:focus { color: $white-40; }\n.hover-white-30:hover,\n.hover-white-30:focus { color: $white-30; }\n.hover-white-20:hover,\n.hover-white-20:focus { color: $white-20; }\n.hover-white-10:hover,\n.hover-white-10:focus { color: $white-10; }\n.hover-inherit:hover,\n.hover-inherit:focus { color: inherit; }\n\n.hover-bg-black:hover,\n.hover-bg-black:focus { background-color: $black; }\n.hover-bg-near-black:hover,\n.hover-bg-near-black:focus { background-color: $near-black; }\n.hover-bg-dark-gray:hover,\n.hover-bg-dark-gray:focus { background-color: $dark-gray; }\n.hover-bg-mid-gray:hover,\n.hover-bg-mid-gray:focus { background-color: $mid-gray; }\n.hover-bg-gray:hover,\n.hover-bg-gray:focus { background-color: $gray; }\n.hover-bg-silver:hover,\n.hover-bg-silver:focus { background-color: $silver; }\n.hover-bg-light-silver:hover,\n.hover-bg-light-silver:focus { background-color: $light-silver; }\n.hover-bg-moon-gray:hover,\n.hover-bg-moon-gray:focus { background-color: $moon-gray; }\n.hover-bg-light-gray:hover,\n.hover-bg-light-gray:focus { background-color: $light-gray; }\n.hover-bg-near-white:hover,\n.hover-bg-near-white:focus { background-color: $near-white; }\n.hover-bg-white:hover,\n.hover-bg-white:focus { background-color: $white; }\n.hover-bg-transparent:hover,\n.hover-bg-transparent:focus { background-color: $transparent; }\n\n.hover-bg-black-90:hover,\n.hover-bg-black-90:focus { background-color: $black-90; }\n.hover-bg-black-80:hover,\n.hover-bg-black-80:focus { background-color: $black-80; }\n.hover-bg-black-70:hover,\n.hover-bg-black-70:focus { background-color: $black-70; }\n.hover-bg-black-60:hover,\n.hover-bg-black-60:focus { background-color: $black-60; }\n.hover-bg-black-50:hover,\n.hover-bg-black-50:focus { background-color: $black-50; }\n.hover-bg-black-40:hover,\n.hover-bg-black-40:focus { background-color: $black-40; }\n.hover-bg-black-30:hover,\n.hover-bg-black-30:focus { background-color: $black-30; }\n.hover-bg-black-20:hover,\n.hover-bg-black-20:focus { background-color: $black-20; }\n.hover-bg-black-10:hover,\n.hover-bg-black-10:focus { background-color: $black-10; }\n.hover-bg-white-90:hover,\n.hover-bg-white-90:focus { background-color: $white-90; }\n.hover-bg-white-80:hover,\n.hover-bg-white-80:focus { background-color: $white-80; }\n.hover-bg-white-70:hover,\n.hover-bg-white-70:focus { background-color: $white-70; }\n.hover-bg-white-60:hover,\n.hover-bg-white-60:focus { background-color: $white-60; }\n.hover-bg-white-50:hover,\n.hover-bg-white-50:focus { background-color: $white-50; }\n.hover-bg-white-40:hover,\n.hover-bg-white-40:focus { background-color: $white-40; }\n.hover-bg-white-30:hover,\n.hover-bg-white-30:focus { background-color: $white-30; }\n.hover-bg-white-20:hover,\n.hover-bg-white-20:focus { background-color: $white-20; }\n.hover-bg-white-10:hover,\n.hover-bg-white-10:focus { background-color: $white-10; }\n\n.hover-dark-red:hover,\n.hover-dark-red:focus { color: $dark-red; }\n.hover-red:hover,\n.hover-red:focus { color: $red; }\n.hover-light-red:hover,\n.hover-light-red:focus { color: $light-red; }\n.hover-orange:hover,\n.hover-orange:focus { color: $orange; }\n.hover-gold:hover,\n.hover-gold:focus { color: $gold; }\n.hover-yellow:hover,\n.hover-yellow:focus { color: $yellow; }\n.hover-light-yellow:hover,\n.hover-light-yellow:focus { color: $light-yellow; }\n.hover-purple:hover,\n.hover-purple:focus { color: $purple; }\n.hover-light-purple:hover,\n.hover-light-purple:focus { color: $light-purple; }\n.hover-dark-pink:hover,\n.hover-dark-pink:focus { color: $dark-pink; }\n.hover-hot-pink:hover,\n.hover-hot-pink:focus { color: $hot-pink; }\n.hover-pink:hover,\n.hover-pink:focus { color: $pink; }\n.hover-light-pink:hover,\n.hover-light-pink:focus { color: $light-pink; }\n.hover-dark-green:hover,\n.hover-dark-green:focus { color: $dark-green; }\n.hover-green:hover,\n.hover-green:focus { color: $green; }\n.hover-light-green:hover,\n.hover-light-green:focus { color: $light-green; }\n.hover-navy:hover,\n.hover-navy:focus { color: $navy; }\n.hover-dark-blue:hover,\n.hover-dark-blue:focus { color: $dark-blue; }\n.hover-blue:hover,\n.hover-blue:focus { color: $blue; }\n.hover-light-blue:hover,\n.hover-light-blue:focus { color: $light-blue; }\n.hover-lightest-blue:hover,\n.hover-lightest-blue:focus { color: $lightest-blue; }\n.hover-washed-blue:hover,\n.hover-washed-blue:focus { color: $washed-blue; }\n.hover-washed-green:hover,\n.hover-washed-green:focus { color: $washed-green; }\n.hover-washed-yellow:hover,\n.hover-washed-yellow:focus { color: $washed-yellow; }\n.hover-washed-red:hover,\n.hover-washed-red:focus { color: $washed-red; }\n\n.hover-bg-dark-red:hover,\n.hover-bg-dark-red:focus { background-color: $dark-red; }\n.hover-bg-red:hover,\n.hover-bg-red:focus { background-color: $red; }\n.hover-bg-light-red:hover,\n.hover-bg-light-red:focus { background-color: $light-red; }\n.hover-bg-orange:hover,\n.hover-bg-orange:focus { background-color: $orange; }\n.hover-bg-gold:hover,\n.hover-bg-gold:focus { background-color: $gold; }\n.hover-bg-yellow:hover,\n.hover-bg-yellow:focus { background-color: $yellow; }\n.hover-bg-light-yellow:hover,\n.hover-bg-light-yellow:focus { background-color: $light-yellow; }\n.hover-bg-purple:hover,\n.hover-bg-purple:focus { background-color: $purple; }\n.hover-bg-light-purple:hover,\n.hover-bg-light-purple:focus { background-color: $light-purple; }\n.hover-bg-dark-pink:hover,\n.hover-bg-dark-pink:focus { background-color: $dark-pink; }\n.hover-bg-hot-pink:hover,\n.hover-bg-hot-pink:focus { background-color: $hot-pink; }\n.hover-bg-pink:hover,\n.hover-bg-pink:focus { background-color: $pink; }\n.hover-bg-light-pink:hover,\n.hover-bg-light-pink:focus { background-color: $light-pink; }\n.hover-bg-dark-green:hover,\n.hover-bg-dark-green:focus { background-color: $dark-green; }\n.hover-bg-green:hover,\n.hover-bg-green:focus { background-color: $green; }\n.hover-bg-light-green:hover,\n.hover-bg-light-green:focus { background-color: $light-green; }\n.hover-bg-navy:hover,\n.hover-bg-navy:focus { background-color: $navy; }\n.hover-bg-dark-blue:hover,\n.hover-bg-dark-blue:focus { background-color: $dark-blue; }\n.hover-bg-blue:hover,\n.hover-bg-blue:focus { background-color: $blue; }\n.hover-bg-light-blue:hover,\n.hover-bg-light-blue:focus { background-color: $light-blue; }\n.hover-bg-lightest-blue:hover,\n.hover-bg-lightest-blue:focus { background-color: $lightest-blue; }\n.hover-bg-washed-blue:hover,\n.hover-bg-washed-blue:focus { background-color: $washed-blue; }\n.hover-bg-washed-green:hover,\n.hover-bg-washed-green:focus { background-color: $washed-green; }\n.hover-bg-washed-yellow:hover,\n.hover-bg-washed-yellow:focus { background-color: $washed-yellow; }\n.hover-bg-washed-red:hover,\n.hover-bg-washed-red:focus { background-color: $washed-red; }\n.hover-bg-inherit:hover,\n.hover-bg-inherit:focus { background-color: inherit; }\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/* Variables */\n\n/*\n SPACING\n Docs: http://tachyons.io/docs/layout/spacing/\n\n An eight step powers of two scale ranging from 0 to 16rem.\n\n Base:\n p = padding\n m = margin\n\n Modifiers:\n a = all\n h = horizontal\n v = vertical\n t = top\n r = right\n b = bottom\n l = left\n\n 0 = none\n 1 = 1st step in spacing scale\n 2 = 2nd step in spacing scale\n 3 = 3rd step in spacing scale\n 4 = 4th step in spacing scale\n 5 = 5th step in spacing scale\n 6 = 6th step in spacing scale\n 7 = 7th step in spacing scale\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n\n.pa0 { padding: $spacing-none; }\n.pa1 { padding: $spacing-extra-small; }\n.pa2 { padding: $spacing-small; }\n.pa3 { padding: $spacing-medium; }\n.pa4 { padding: $spacing-large; }\n.pa5 { padding: $spacing-extra-large; }\n.pa6 { padding: $spacing-extra-extra-large; }\n.pa7 { padding: $spacing-extra-extra-extra-large; }\n\n.pl0 { padding-left: $spacing-none; }\n.pl1 { padding-left: $spacing-extra-small; }\n.pl2 { padding-left: $spacing-small; }\n.pl3 { padding-left: $spacing-medium; }\n.pl4 { padding-left: $spacing-large; }\n.pl5 { padding-left: $spacing-extra-large; }\n.pl6 { padding-left: $spacing-extra-extra-large; }\n.pl7 { padding-left: $spacing-extra-extra-extra-large; }\n\n.pr0 { padding-right: $spacing-none; }\n.pr1 { padding-right: $spacing-extra-small; }\n.pr2 { padding-right: $spacing-small; }\n.pr3 { padding-right: $spacing-medium; }\n.pr4 { padding-right: $spacing-large; }\n.pr5 { padding-right: $spacing-extra-large; }\n.pr6 { padding-right: $spacing-extra-extra-large; }\n.pr7 { padding-right: $spacing-extra-extra-extra-large; }\n\n.pb0 { padding-bottom: $spacing-none; }\n.pb1 { padding-bottom: $spacing-extra-small; }\n.pb2 { padding-bottom: $spacing-small; }\n.pb3 { padding-bottom: $spacing-medium; }\n.pb4 { padding-bottom: $spacing-large; }\n.pb5 { padding-bottom: $spacing-extra-large; }\n.pb6 { padding-bottom: $spacing-extra-extra-large; }\n.pb7 { padding-bottom: $spacing-extra-extra-extra-large; }\n\n.pt0 { padding-top: $spacing-none; }\n.pt1 { padding-top: $spacing-extra-small; }\n.pt2 { padding-top: $spacing-small; }\n.pt3 { padding-top: $spacing-medium; }\n.pt4 { padding-top: $spacing-large; }\n.pt5 { padding-top: $spacing-extra-large; }\n.pt6 { padding-top: $spacing-extra-extra-large; }\n.pt7 { padding-top: $spacing-extra-extra-extra-large; }\n\n.pv0 {\n padding-top: $spacing-none;\n padding-bottom: $spacing-none;\n}\n.pv1 {\n padding-top: $spacing-extra-small;\n padding-bottom: $spacing-extra-small;\n}\n.pv2 {\n padding-top: $spacing-small;\n padding-bottom: $spacing-small;\n}\n.pv3 {\n padding-top: $spacing-medium;\n padding-bottom: $spacing-medium;\n}\n.pv4 {\n padding-top: $spacing-large;\n padding-bottom: $spacing-large;\n}\n.pv5 {\n padding-top: $spacing-extra-large;\n padding-bottom: $spacing-extra-large;\n}\n.pv6 {\n padding-top: $spacing-extra-extra-large;\n padding-bottom: $spacing-extra-extra-large;\n}\n\n.pv7 {\n padding-top: $spacing-extra-extra-extra-large;\n padding-bottom: $spacing-extra-extra-extra-large;\n}\n\n.ph0 {\n padding-left: $spacing-none;\n padding-right: $spacing-none;\n}\n\n.ph1 {\n padding-left: $spacing-extra-small;\n padding-right: $spacing-extra-small;\n}\n\n.ph2 {\n padding-left: $spacing-small;\n padding-right: $spacing-small;\n}\n\n.ph3 {\n padding-left: $spacing-medium;\n padding-right: $spacing-medium;\n}\n\n.ph4 {\n padding-left: $spacing-large;\n padding-right: $spacing-large;\n}\n\n.ph5 {\n padding-left: $spacing-extra-large;\n padding-right: $spacing-extra-large;\n}\n\n.ph6 {\n padding-left: $spacing-extra-extra-large;\n padding-right: $spacing-extra-extra-large;\n}\n\n.ph7 {\n padding-left: $spacing-extra-extra-extra-large;\n padding-right: $spacing-extra-extra-extra-large;\n}\n\n.ma0 { margin: $spacing-none; }\n.ma1 { margin: $spacing-extra-small; }\n.ma2 { margin: $spacing-small; }\n.ma3 { margin: $spacing-medium; }\n.ma4 { margin: $spacing-large; }\n.ma5 { margin: $spacing-extra-large; }\n.ma6 { margin: $spacing-extra-extra-large; }\n.ma7 { margin: $spacing-extra-extra-extra-large; }\n\n.ml0 { margin-left: $spacing-none; }\n.ml1 { margin-left: $spacing-extra-small; }\n.ml2 { margin-left: $spacing-small; }\n.ml3 { margin-left: $spacing-medium; }\n.ml4 { margin-left: $spacing-large; }\n.ml5 { margin-left: $spacing-extra-large; }\n.ml6 { margin-left: $spacing-extra-extra-large; }\n.ml7 { margin-left: $spacing-extra-extra-extra-large; }\n\n.mr0 { margin-right: $spacing-none; }\n.mr1 { margin-right: $spacing-extra-small; }\n.mr2 { margin-right: $spacing-small; }\n.mr3 { margin-right: $spacing-medium; }\n.mr4 { margin-right: $spacing-large; }\n.mr5 { margin-right: $spacing-extra-large; }\n.mr6 { margin-right: $spacing-extra-extra-large; }\n.mr7 { margin-right: $spacing-extra-extra-extra-large; }\n\n.mb0 { margin-bottom: $spacing-none; }\n.mb1 { margin-bottom: $spacing-extra-small; }\n.mb2 { margin-bottom: $spacing-small; }\n.mb3 { margin-bottom: $spacing-medium; }\n.mb4 { margin-bottom: $spacing-large; }\n.mb5 { margin-bottom: $spacing-extra-large; }\n.mb6 { margin-bottom: $spacing-extra-extra-large; }\n.mb7 { margin-bottom: $spacing-extra-extra-extra-large; }\n\n.mt0 { margin-top: $spacing-none; }\n.mt1 { margin-top: $spacing-extra-small; }\n.mt2 { margin-top: $spacing-small; }\n.mt3 { margin-top: $spacing-medium; }\n.mt4 { margin-top: $spacing-large; }\n.mt5 { margin-top: $spacing-extra-large; }\n.mt6 { margin-top: $spacing-extra-extra-large; }\n.mt7 { margin-top: $spacing-extra-extra-extra-large; }\n\n.mv0 {\n margin-top: $spacing-none;\n margin-bottom: $spacing-none;\n}\n.mv1 {\n margin-top: $spacing-extra-small;\n margin-bottom: $spacing-extra-small;\n}\n.mv2 {\n margin-top: $spacing-small;\n margin-bottom: $spacing-small;\n}\n.mv3 {\n margin-top: $spacing-medium;\n margin-bottom: $spacing-medium;\n}\n.mv4 {\n margin-top: $spacing-large;\n margin-bottom: $spacing-large;\n}\n.mv5 {\n margin-top: $spacing-extra-large;\n margin-bottom: $spacing-extra-large;\n}\n.mv6 {\n margin-top: $spacing-extra-extra-large;\n margin-bottom: $spacing-extra-extra-large;\n}\n.mv7 {\n margin-top: $spacing-extra-extra-extra-large;\n margin-bottom: $spacing-extra-extra-extra-large;\n}\n\n.mh0 {\n margin-left: $spacing-none;\n margin-right: $spacing-none;\n}\n.mh1 {\n margin-left: $spacing-extra-small;\n margin-right: $spacing-extra-small;\n}\n.mh2 {\n margin-left: $spacing-small;\n margin-right: $spacing-small;\n}\n.mh3 {\n margin-left: $spacing-medium;\n margin-right: $spacing-medium;\n}\n.mh4 {\n margin-left: $spacing-large;\n margin-right: $spacing-large;\n}\n.mh5 {\n margin-left: $spacing-extra-large;\n margin-right: $spacing-extra-large;\n}\n.mh6 {\n margin-left: $spacing-extra-extra-large;\n margin-right: $spacing-extra-extra-large;\n}\n.mh7 {\n margin-left: $spacing-extra-extra-extra-large;\n margin-right: $spacing-extra-extra-extra-large;\n}\n\n@media #{$breakpoint-not-small} {\n .pa0-ns { padding: $spacing-none; }\n .pa1-ns { padding: $spacing-extra-small; }\n .pa2-ns { padding: $spacing-small; }\n .pa3-ns { padding: $spacing-medium; }\n .pa4-ns { padding: $spacing-large; }\n .pa5-ns { padding: $spacing-extra-large; }\n .pa6-ns { padding: $spacing-extra-extra-large; }\n .pa7-ns { padding: $spacing-extra-extra-extra-large; }\n\n .pl0-ns { padding-left: $spacing-none; }\n .pl1-ns { padding-left: $spacing-extra-small; }\n .pl2-ns { padding-left: $spacing-small; }\n .pl3-ns { padding-left: $spacing-medium; }\n .pl4-ns { padding-left: $spacing-large; }\n .pl5-ns { padding-left: $spacing-extra-large; }\n .pl6-ns { padding-left: $spacing-extra-extra-large; }\n .pl7-ns { padding-left: $spacing-extra-extra-extra-large; }\n\n .pr0-ns { padding-right: $spacing-none; }\n .pr1-ns { padding-right: $spacing-extra-small; }\n .pr2-ns { padding-right: $spacing-small; }\n .pr3-ns { padding-right: $spacing-medium; }\n .pr4-ns { padding-right: $spacing-large; }\n .pr5-ns { padding-right: $spacing-extra-large; }\n .pr6-ns { padding-right: $spacing-extra-extra-large; }\n .pr7-ns { padding-right: $spacing-extra-extra-extra-large; }\n\n .pb0-ns { padding-bottom: $spacing-none; }\n .pb1-ns { padding-bottom: $spacing-extra-small; }\n .pb2-ns { padding-bottom: $spacing-small; }\n .pb3-ns { padding-bottom: $spacing-medium; }\n .pb4-ns { padding-bottom: $spacing-large; }\n .pb5-ns { padding-bottom: $spacing-extra-large; }\n .pb6-ns { padding-bottom: $spacing-extra-extra-large; }\n .pb7-ns { padding-bottom: $spacing-extra-extra-extra-large; }\n\n .pt0-ns { padding-top: $spacing-none; }\n .pt1-ns { padding-top: $spacing-extra-small; }\n .pt2-ns { padding-top: $spacing-small; }\n .pt3-ns { padding-top: $spacing-medium; }\n .pt4-ns { padding-top: $spacing-large; }\n .pt5-ns { padding-top: $spacing-extra-large; }\n .pt6-ns { padding-top: $spacing-extra-extra-large; }\n .pt7-ns { padding-top: $spacing-extra-extra-extra-large; }\n\n .pv0-ns {\n padding-top: $spacing-none;\n padding-bottom: $spacing-none;\n }\n .pv1-ns {\n padding-top: $spacing-extra-small;\n padding-bottom: $spacing-extra-small;\n }\n .pv2-ns {\n padding-top: $spacing-small;\n padding-bottom: $spacing-small;\n }\n .pv3-ns {\n padding-top: $spacing-medium;\n padding-bottom: $spacing-medium;\n }\n .pv4-ns {\n padding-top: $spacing-large;\n padding-bottom: $spacing-large;\n }\n .pv5-ns {\n padding-top: $spacing-extra-large;\n padding-bottom: $spacing-extra-large;\n }\n .pv6-ns {\n padding-top: $spacing-extra-extra-large;\n padding-bottom: $spacing-extra-extra-large;\n }\n .pv7-ns {\n padding-top: $spacing-extra-extra-extra-large;\n padding-bottom: $spacing-extra-extra-extra-large;\n }\n .ph0-ns {\n padding-left: $spacing-none;\n padding-right: $spacing-none;\n }\n .ph1-ns {\n padding-left: $spacing-extra-small;\n padding-right: $spacing-extra-small;\n }\n .ph2-ns {\n padding-left: $spacing-small;\n padding-right: $spacing-small;\n }\n .ph3-ns {\n padding-left: $spacing-medium;\n padding-right: $spacing-medium;\n }\n .ph4-ns {\n padding-left: $spacing-large;\n padding-right: $spacing-large;\n }\n .ph5-ns {\n padding-left: $spacing-extra-large;\n padding-right: $spacing-extra-large;\n }\n .ph6-ns {\n padding-left: $spacing-extra-extra-large;\n padding-right: $spacing-extra-extra-large;\n }\n .ph7-ns {\n padding-left: $spacing-extra-extra-extra-large;\n padding-right: $spacing-extra-extra-extra-large;\n }\n\n .ma0-ns { margin: $spacing-none; }\n .ma1-ns { margin: $spacing-extra-small; }\n .ma2-ns { margin: $spacing-small; }\n .ma3-ns { margin: $spacing-medium; }\n .ma4-ns { margin: $spacing-large; }\n .ma5-ns { margin: $spacing-extra-large; }\n .ma6-ns { margin: $spacing-extra-extra-large; }\n .ma7-ns { margin: $spacing-extra-extra-extra-large; }\n\n .ml0-ns { margin-left: $spacing-none; }\n .ml1-ns { margin-left: $spacing-extra-small; }\n .ml2-ns { margin-left: $spacing-small; }\n .ml3-ns { margin-left: $spacing-medium; }\n .ml4-ns { margin-left: $spacing-large; }\n .ml5-ns { margin-left: $spacing-extra-large; }\n .ml6-ns { margin-left: $spacing-extra-extra-large; }\n .ml7-ns { margin-left: $spacing-extra-extra-extra-large; }\n\n .mr0-ns { margin-right: $spacing-none; }\n .mr1-ns { margin-right: $spacing-extra-small; }\n .mr2-ns { margin-right: $spacing-small; }\n .mr3-ns { margin-right: $spacing-medium; }\n .mr4-ns { margin-right: $spacing-large; }\n .mr5-ns { margin-right: $spacing-extra-large; }\n .mr6-ns { margin-right: $spacing-extra-extra-large; }\n .mr7-ns { margin-right: $spacing-extra-extra-extra-large; }\n\n .mb0-ns { margin-bottom: $spacing-none; }\n .mb1-ns { margin-bottom: $spacing-extra-small; }\n .mb2-ns { margin-bottom: $spacing-small; }\n .mb3-ns { margin-bottom: $spacing-medium; }\n .mb4-ns { margin-bottom: $spacing-large; }\n .mb5-ns { margin-bottom: $spacing-extra-large; }\n .mb6-ns { margin-bottom: $spacing-extra-extra-large; }\n .mb7-ns { margin-bottom: $spacing-extra-extra-extra-large; }\n\n .mt0-ns { margin-top: $spacing-none; }\n .mt1-ns { margin-top: $spacing-extra-small; }\n .mt2-ns { margin-top: $spacing-small; }\n .mt3-ns { margin-top: $spacing-medium; }\n .mt4-ns { margin-top: $spacing-large; }\n .mt5-ns { margin-top: $spacing-extra-large; }\n .mt6-ns { margin-top: $spacing-extra-extra-large; }\n .mt7-ns { margin-top: $spacing-extra-extra-extra-large; }\n\n .mv0-ns {\n margin-top: $spacing-none;\n margin-bottom: $spacing-none;\n }\n .mv1-ns {\n margin-top: $spacing-extra-small;\n margin-bottom: $spacing-extra-small;\n }\n .mv2-ns {\n margin-top: $spacing-small;\n margin-bottom: $spacing-small;\n }\n .mv3-ns {\n margin-top: $spacing-medium;\n margin-bottom: $spacing-medium;\n }\n .mv4-ns {\n margin-top: $spacing-large;\n margin-bottom: $spacing-large;\n }\n .mv5-ns {\n margin-top: $spacing-extra-large;\n margin-bottom: $spacing-extra-large;\n }\n .mv6-ns {\n margin-top: $spacing-extra-extra-large;\n margin-bottom: $spacing-extra-extra-large;\n }\n .mv7-ns {\n margin-top: $spacing-extra-extra-extra-large;\n margin-bottom: $spacing-extra-extra-extra-large;\n }\n\n .mh0-ns {\n margin-left: $spacing-none;\n margin-right: $spacing-none;\n }\n .mh1-ns {\n margin-left: $spacing-extra-small;\n margin-right: $spacing-extra-small;\n }\n .mh2-ns {\n margin-left: $spacing-small;\n margin-right: $spacing-small;\n }\n .mh3-ns {\n margin-left: $spacing-medium;\n margin-right: $spacing-medium;\n }\n .mh4-ns {\n margin-left: $spacing-large;\n margin-right: $spacing-large;\n }\n .mh5-ns {\n margin-left: $spacing-extra-large;\n margin-right: $spacing-extra-large;\n }\n .mh6-ns {\n margin-left: $spacing-extra-extra-large;\n margin-right: $spacing-extra-extra-large;\n }\n .mh7-ns {\n margin-left: $spacing-extra-extra-extra-large;\n margin-right: $spacing-extra-extra-extra-large;\n }\n\n}\n\n@media #{$breakpoint-medium} {\n .pa0-m { padding: $spacing-none; }\n .pa1-m { padding: $spacing-extra-small; }\n .pa2-m { padding: $spacing-small; }\n .pa3-m { padding: $spacing-medium; }\n .pa4-m { padding: $spacing-large; }\n .pa5-m { padding: $spacing-extra-large; }\n .pa6-m { padding: $spacing-extra-extra-large; }\n .pa7-m { padding: $spacing-extra-extra-extra-large; }\n\n .pl0-m { padding-left: $spacing-none; }\n .pl1-m { padding-left: $spacing-extra-small; }\n .pl2-m { padding-left: $spacing-small; }\n .pl3-m { padding-left: $spacing-medium; }\n .pl4-m { padding-left: $spacing-large; }\n .pl5-m { padding-left: $spacing-extra-large; }\n .pl6-m { padding-left: $spacing-extra-extra-large; }\n .pl7-m { padding-left: $spacing-extra-extra-extra-large; }\n\n .pr0-m { padding-right: $spacing-none; }\n .pr1-m { padding-right: $spacing-extra-small; }\n .pr2-m { padding-right: $spacing-small; }\n .pr3-m { padding-right: $spacing-medium; }\n .pr4-m { padding-right: $spacing-large; }\n .pr5-m { padding-right: $spacing-extra-large; }\n .pr6-m { padding-right: $spacing-extra-extra-large; }\n .pr7-m { padding-right: $spacing-extra-extra-extra-large; }\n\n .pb0-m { padding-bottom: $spacing-none; }\n .pb1-m { padding-bottom: $spacing-extra-small; }\n .pb2-m { padding-bottom: $spacing-small; }\n .pb3-m { padding-bottom: $spacing-medium; }\n .pb4-m { padding-bottom: $spacing-large; }\n .pb5-m { padding-bottom: $spacing-extra-large; }\n .pb6-m { padding-bottom: $spacing-extra-extra-large; }\n .pb7-m { padding-bottom: $spacing-extra-extra-extra-large; }\n\n .pt0-m { padding-top: $spacing-none; }\n .pt1-m { padding-top: $spacing-extra-small; }\n .pt2-m { padding-top: $spacing-small; }\n .pt3-m { padding-top: $spacing-medium; }\n .pt4-m { padding-top: $spacing-large; }\n .pt5-m { padding-top: $spacing-extra-large; }\n .pt6-m { padding-top: $spacing-extra-extra-large; }\n .pt7-m { padding-top: $spacing-extra-extra-extra-large; }\n\n .pv0-m {\n padding-top: $spacing-none;\n padding-bottom: $spacing-none;\n }\n .pv1-m {\n padding-top: $spacing-extra-small;\n padding-bottom: $spacing-extra-small;\n }\n .pv2-m {\n padding-top: $spacing-small;\n padding-bottom: $spacing-small;\n }\n .pv3-m {\n padding-top: $spacing-medium;\n padding-bottom: $spacing-medium;\n }\n .pv4-m {\n padding-top: $spacing-large;\n padding-bottom: $spacing-large;\n }\n .pv5-m {\n padding-top: $spacing-extra-large;\n padding-bottom: $spacing-extra-large;\n }\n .pv6-m {\n padding-top: $spacing-extra-extra-large;\n padding-bottom: $spacing-extra-extra-large;\n }\n .pv7-m {\n padding-top: $spacing-extra-extra-extra-large;\n padding-bottom: $spacing-extra-extra-extra-large;\n }\n\n .ph0-m {\n padding-left: $spacing-none;\n padding-right: $spacing-none;\n }\n .ph1-m {\n padding-left: $spacing-extra-small;\n padding-right: $spacing-extra-small;\n }\n .ph2-m {\n padding-left: $spacing-small;\n padding-right: $spacing-small;\n }\n .ph3-m {\n padding-left: $spacing-medium;\n padding-right: $spacing-medium;\n }\n .ph4-m {\n padding-left: $spacing-large;\n padding-right: $spacing-large;\n }\n .ph5-m {\n padding-left: $spacing-extra-large;\n padding-right: $spacing-extra-large;\n }\n .ph6-m {\n padding-left: $spacing-extra-extra-large;\n padding-right: $spacing-extra-extra-large;\n }\n .ph7-m {\n padding-left: $spacing-extra-extra-extra-large;\n padding-right: $spacing-extra-extra-extra-large;\n }\n\n .ma0-m { margin: $spacing-none; }\n .ma1-m { margin: $spacing-extra-small; }\n .ma2-m { margin: $spacing-small; }\n .ma3-m { margin: $spacing-medium; }\n .ma4-m { margin: $spacing-large; }\n .ma5-m { margin: $spacing-extra-large; }\n .ma6-m { margin: $spacing-extra-extra-large; }\n .ma7-m { margin: $spacing-extra-extra-extra-large; }\n\n .ml0-m { margin-left: $spacing-none; }\n .ml1-m { margin-left: $spacing-extra-small; }\n .ml2-m { margin-left: $spacing-small; }\n .ml3-m { margin-left: $spacing-medium; }\n .ml4-m { margin-left: $spacing-large; }\n .ml5-m { margin-left: $spacing-extra-large; }\n .ml6-m { margin-left: $spacing-extra-extra-large; }\n .ml7-m { margin-left: $spacing-extra-extra-extra-large; }\n\n .mr0-m { margin-right: $spacing-none; }\n .mr1-m { margin-right: $spacing-extra-small; }\n .mr2-m { margin-right: $spacing-small; }\n .mr3-m { margin-right: $spacing-medium; }\n .mr4-m { margin-right: $spacing-large; }\n .mr5-m { margin-right: $spacing-extra-large; }\n .mr6-m { margin-right: $spacing-extra-extra-large; }\n .mr7-m { margin-right: $spacing-extra-extra-extra-large; }\n\n .mb0-m { margin-bottom: $spacing-none; }\n .mb1-m { margin-bottom: $spacing-extra-small; }\n .mb2-m { margin-bottom: $spacing-small; }\n .mb3-m { margin-bottom: $spacing-medium; }\n .mb4-m { margin-bottom: $spacing-large; }\n .mb5-m { margin-bottom: $spacing-extra-large; }\n .mb6-m { margin-bottom: $spacing-extra-extra-large; }\n .mb7-m { margin-bottom: $spacing-extra-extra-extra-large; }\n\n .mt0-m { margin-top: $spacing-none; }\n .mt1-m { margin-top: $spacing-extra-small; }\n .mt2-m { margin-top: $spacing-small; }\n .mt3-m { margin-top: $spacing-medium; }\n .mt4-m { margin-top: $spacing-large; }\n .mt5-m { margin-top: $spacing-extra-large; }\n .mt6-m { margin-top: $spacing-extra-extra-large; }\n .mt7-m { margin-top: $spacing-extra-extra-extra-large; }\n\n .mv0-m {\n margin-top: $spacing-none;\n margin-bottom: $spacing-none;\n }\n .mv1-m {\n margin-top: $spacing-extra-small;\n margin-bottom: $spacing-extra-small;\n }\n .mv2-m {\n margin-top: $spacing-small;\n margin-bottom: $spacing-small;\n }\n .mv3-m {\n margin-top: $spacing-medium;\n margin-bottom: $spacing-medium;\n }\n .mv4-m {\n margin-top: $spacing-large;\n margin-bottom: $spacing-large;\n }\n .mv5-m {\n margin-top: $spacing-extra-large;\n margin-bottom: $spacing-extra-large;\n }\n .mv6-m {\n margin-top: $spacing-extra-extra-large;\n margin-bottom: $spacing-extra-extra-large;\n }\n .mv7-m {\n margin-top: $spacing-extra-extra-extra-large;\n margin-bottom: $spacing-extra-extra-extra-large;\n }\n\n .mh0-m {\n margin-left: $spacing-none;\n margin-right: $spacing-none;\n }\n .mh1-m {\n margin-left: $spacing-extra-small;\n margin-right: $spacing-extra-small;\n }\n .mh2-m {\n margin-left: $spacing-small;\n margin-right: $spacing-small;\n }\n .mh3-m {\n margin-left: $spacing-medium;\n margin-right: $spacing-medium;\n }\n .mh4-m {\n margin-left: $spacing-large;\n margin-right: $spacing-large;\n }\n .mh5-m {\n margin-left: $spacing-extra-large;\n margin-right: $spacing-extra-large;\n }\n .mh6-m {\n margin-left: $spacing-extra-extra-large;\n margin-right: $spacing-extra-extra-large;\n }\n .mh7-m {\n margin-left: $spacing-extra-extra-extra-large;\n margin-right: $spacing-extra-extra-extra-large;\n }\n\n}\n\n@media #{$breakpoint-large} {\n .pa0-l { padding: $spacing-none; }\n .pa1-l { padding: $spacing-extra-small; }\n .pa2-l { padding: $spacing-small; }\n .pa3-l { padding: $spacing-medium; }\n .pa4-l { padding: $spacing-large; }\n .pa5-l { padding: $spacing-extra-large; }\n .pa6-l { padding: $spacing-extra-extra-large; }\n .pa7-l { padding: $spacing-extra-extra-extra-large; }\n\n .pl0-l { padding-left: $spacing-none; }\n .pl1-l { padding-left: $spacing-extra-small; }\n .pl2-l { padding-left: $spacing-small; }\n .pl3-l { padding-left: $spacing-medium; }\n .pl4-l { padding-left: $spacing-large; }\n .pl5-l { padding-left: $spacing-extra-large; }\n .pl6-l { padding-left: $spacing-extra-extra-large; }\n .pl7-l { padding-left: $spacing-extra-extra-extra-large; }\n\n .pr0-l { padding-right: $spacing-none; }\n .pr1-l { padding-right: $spacing-extra-small; }\n .pr2-l { padding-right: $spacing-small; }\n .pr3-l { padding-right: $spacing-medium; }\n .pr4-l { padding-right: $spacing-large; }\n .pr5-l { padding-right: $spacing-extra-large; }\n .pr6-l { padding-right: $spacing-extra-extra-large; }\n .pr7-l { padding-right: $spacing-extra-extra-extra-large; }\n\n .pb0-l { padding-bottom: $spacing-none; }\n .pb1-l { padding-bottom: $spacing-extra-small; }\n .pb2-l { padding-bottom: $spacing-small; }\n .pb3-l { padding-bottom: $spacing-medium; }\n .pb4-l { padding-bottom: $spacing-large; }\n .pb5-l { padding-bottom: $spacing-extra-large; }\n .pb6-l { padding-bottom: $spacing-extra-extra-large; }\n .pb7-l { padding-bottom: $spacing-extra-extra-extra-large; }\n\n .pt0-l { padding-top: $spacing-none; }\n .pt1-l { padding-top: $spacing-extra-small; }\n .pt2-l { padding-top: $spacing-small; }\n .pt3-l { padding-top: $spacing-medium; }\n .pt4-l { padding-top: $spacing-large; }\n .pt5-l { padding-top: $spacing-extra-large; }\n .pt6-l { padding-top: $spacing-extra-extra-large; }\n .pt7-l { padding-top: $spacing-extra-extra-extra-large; }\n\n .pv0-l {\n padding-top: $spacing-none;\n padding-bottom: $spacing-none;\n }\n .pv1-l {\n padding-top: $spacing-extra-small;\n padding-bottom: $spacing-extra-small;\n }\n .pv2-l {\n padding-top: $spacing-small;\n padding-bottom: $spacing-small;\n }\n .pv3-l {\n padding-top: $spacing-medium;\n padding-bottom: $spacing-medium;\n }\n .pv4-l {\n padding-top: $spacing-large;\n padding-bottom: $spacing-large;\n }\n .pv5-l {\n padding-top: $spacing-extra-large;\n padding-bottom: $spacing-extra-large;\n }\n .pv6-l {\n padding-top: $spacing-extra-extra-large;\n padding-bottom: $spacing-extra-extra-large;\n }\n .pv7-l {\n padding-top: $spacing-extra-extra-extra-large;\n padding-bottom: $spacing-extra-extra-extra-large;\n }\n\n .ph0-l {\n padding-left: $spacing-none;\n padding-right: $spacing-none;\n }\n .ph1-l {\n padding-left: $spacing-extra-small;\n padding-right: $spacing-extra-small;\n }\n .ph2-l {\n padding-left: $spacing-small;\n padding-right: $spacing-small;\n }\n .ph3-l {\n padding-left: $spacing-medium;\n padding-right: $spacing-medium;\n }\n .ph4-l {\n padding-left: $spacing-large;\n padding-right: $spacing-large;\n }\n .ph5-l {\n padding-left: $spacing-extra-large;\n padding-right: $spacing-extra-large;\n }\n .ph6-l {\n padding-left: $spacing-extra-extra-large;\n padding-right: $spacing-extra-extra-large;\n }\n .ph7-l {\n padding-left: $spacing-extra-extra-extra-large;\n padding-right: $spacing-extra-extra-extra-large;\n }\n\n .ma0-l { margin: $spacing-none; }\n .ma1-l { margin: $spacing-extra-small; }\n .ma2-l { margin: $spacing-small; }\n .ma3-l { margin: $spacing-medium; }\n .ma4-l { margin: $spacing-large; }\n .ma5-l { margin: $spacing-extra-large; }\n .ma6-l { margin: $spacing-extra-extra-large; }\n .ma7-l { margin: $spacing-extra-extra-extra-large; }\n\n .ml0-l { margin-left: $spacing-none; }\n .ml1-l { margin-left: $spacing-extra-small; }\n .ml2-l { margin-left: $spacing-small; }\n .ml3-l { margin-left: $spacing-medium; }\n .ml4-l { margin-left: $spacing-large; }\n .ml5-l { margin-left: $spacing-extra-large; }\n .ml6-l { margin-left: $spacing-extra-extra-large; }\n .ml7-l { margin-left: $spacing-extra-extra-extra-large; }\n\n .mr0-l { margin-right: $spacing-none; }\n .mr1-l { margin-right: $spacing-extra-small; }\n .mr2-l { margin-right: $spacing-small; }\n .mr3-l { margin-right: $spacing-medium; }\n .mr4-l { margin-right: $spacing-large; }\n .mr5-l { margin-right: $spacing-extra-large; }\n .mr6-l { margin-right: $spacing-extra-extra-large; }\n .mr7-l { margin-right: $spacing-extra-extra-extra-large; }\n\n .mb0-l { margin-bottom: $spacing-none; }\n .mb1-l { margin-bottom: $spacing-extra-small; }\n .mb2-l { margin-bottom: $spacing-small; }\n .mb3-l { margin-bottom: $spacing-medium; }\n .mb4-l { margin-bottom: $spacing-large; }\n .mb5-l { margin-bottom: $spacing-extra-large; }\n .mb6-l { margin-bottom: $spacing-extra-extra-large; }\n .mb7-l { margin-bottom: $spacing-extra-extra-extra-large; }\n\n .mt0-l { margin-top: $spacing-none; }\n .mt1-l { margin-top: $spacing-extra-small; }\n .mt2-l { margin-top: $spacing-small; }\n .mt3-l { margin-top: $spacing-medium; }\n .mt4-l { margin-top: $spacing-large; }\n .mt5-l { margin-top: $spacing-extra-large; }\n .mt6-l { margin-top: $spacing-extra-extra-large; }\n .mt7-l { margin-top: $spacing-extra-extra-extra-large; }\n\n .mv0-l {\n margin-top: $spacing-none;\n margin-bottom: $spacing-none;\n }\n .mv1-l {\n margin-top: $spacing-extra-small;\n margin-bottom: $spacing-extra-small;\n }\n .mv2-l {\n margin-top: $spacing-small;\n margin-bottom: $spacing-small;\n }\n .mv3-l {\n margin-top: $spacing-medium;\n margin-bottom: $spacing-medium;\n }\n .mv4-l {\n margin-top: $spacing-large;\n margin-bottom: $spacing-large;\n }\n .mv5-l {\n margin-top: $spacing-extra-large;\n margin-bottom: $spacing-extra-large;\n }\n .mv6-l {\n margin-top: $spacing-extra-extra-large;\n margin-bottom: $spacing-extra-extra-large;\n }\n .mv7-l {\n margin-top: $spacing-extra-extra-extra-large;\n margin-bottom: $spacing-extra-extra-extra-large;\n }\n\n .mh0-l {\n margin-left: $spacing-none;\n margin-right: $spacing-none;\n }\n .mh1-l {\n margin-left: $spacing-extra-small;\n margin-right: $spacing-extra-small;\n }\n .mh2-l {\n margin-left: $spacing-small;\n margin-right: $spacing-small;\n }\n .mh3-l {\n margin-left: $spacing-medium;\n margin-right: $spacing-medium;\n }\n .mh4-l {\n margin-left: $spacing-large;\n margin-right: $spacing-large;\n }\n .mh5-l {\n margin-left: $spacing-extra-large;\n margin-right: $spacing-extra-large;\n }\n .mh6-l {\n margin-left: $spacing-extra-extra-large;\n margin-right: $spacing-extra-extra-large;\n }\n .mh7-l {\n margin-left: $spacing-extra-extra-extra-large;\n margin-right: $spacing-extra-extra-extra-large;\n }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n NEGATIVE MARGINS\n\n Base:\n n = negative\n\n Modifiers:\n a = all\n t = top\n r = right\n b = bottom\n l = left\n\n 1 = 1st step in spacing scale\n 2 = 2nd step in spacing scale\n 3 = 3rd step in spacing scale\n 4 = 4th step in spacing scale\n 5 = 5th step in spacing scale\n 6 = 6th step in spacing scale\n 7 = 7th step in spacing scale\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n\n\n.na1 { margin: -$spacing-extra-small; }\n.na2 { margin: -$spacing-small; }\n.na3 { margin: -$spacing-medium; }\n.na4 { margin: -$spacing-large; }\n.na5 { margin: -$spacing-extra-large; }\n.na6 { margin: -$spacing-extra-extra-large; }\n.na7 { margin: -$spacing-extra-extra-extra-large; }\n\n.nl1 { margin-left: -$spacing-extra-small; }\n.nl2 { margin-left: -$spacing-small; }\n.nl3 { margin-left: -$spacing-medium; }\n.nl4 { margin-left: -$spacing-large; }\n.nl5 { margin-left: -$spacing-extra-large; }\n.nl6 { margin-left: -$spacing-extra-extra-large; }\n.nl7 { margin-left: -$spacing-extra-extra-extra-large; }\n\n.nr1 { margin-right: -$spacing-extra-small; }\n.nr2 { margin-right: -$spacing-small; }\n.nr3 { margin-right: -$spacing-medium; }\n.nr4 { margin-right: -$spacing-large; }\n.nr5 { margin-right: -$spacing-extra-large; }\n.nr6 { margin-right: -$spacing-extra-extra-large; }\n.nr7 { margin-right: -$spacing-extra-extra-extra-large; }\n\n.nb1 { margin-bottom: -$spacing-extra-small; }\n.nb2 { margin-bottom: -$spacing-small; }\n.nb3 { margin-bottom: -$spacing-medium; }\n.nb4 { margin-bottom: -$spacing-large; }\n.nb5 { margin-bottom: -$spacing-extra-large; }\n.nb6 { margin-bottom: -$spacing-extra-extra-large; }\n.nb7 { margin-bottom: -$spacing-extra-extra-extra-large; }\n\n.nt1 { margin-top: -$spacing-extra-small; }\n.nt2 { margin-top: -$spacing-small; }\n.nt3 { margin-top: -$spacing-medium; }\n.nt4 { margin-top: -$spacing-large; }\n.nt5 { margin-top: -$spacing-extra-large; }\n.nt6 { margin-top: -$spacing-extra-extra-large; }\n.nt7 { margin-top: -$spacing-extra-extra-extra-large; }\n\n@media #{$breakpoint-not-small} {\n\n .na1-ns { margin: -$spacing-extra-small; }\n .na2-ns { margin: -$spacing-small; }\n .na3-ns { margin: -$spacing-medium; }\n .na4-ns { margin: -$spacing-large; }\n .na5-ns { margin: -$spacing-extra-large; }\n .na6-ns { margin: -$spacing-extra-extra-large; }\n .na7-ns { margin: -$spacing-extra-extra-extra-large; }\n\n .nl1-ns { margin-left: -$spacing-extra-small; }\n .nl2-ns { margin-left: -$spacing-small; }\n .nl3-ns { margin-left: -$spacing-medium; }\n .nl4-ns { margin-left: -$spacing-large; }\n .nl5-ns { margin-left: -$spacing-extra-large; }\n .nl6-ns { margin-left: -$spacing-extra-extra-large; }\n .nl7-ns { margin-left: -$spacing-extra-extra-extra-large; }\n\n .nr1-ns { margin-right: -$spacing-extra-small; }\n .nr2-ns { margin-right: -$spacing-small; }\n .nr3-ns { margin-right: -$spacing-medium; }\n .nr4-ns { margin-right: -$spacing-large; }\n .nr5-ns { margin-right: -$spacing-extra-large; }\n .nr6-ns { margin-right: -$spacing-extra-extra-large; }\n .nr7-ns { margin-right: -$spacing-extra-extra-extra-large; }\n\n .nb1-ns { margin-bottom: -$spacing-extra-small; }\n .nb2-ns { margin-bottom: -$spacing-small; }\n .nb3-ns { margin-bottom: -$spacing-medium; }\n .nb4-ns { margin-bottom: -$spacing-large; }\n .nb5-ns { margin-bottom: -$spacing-extra-large; }\n .nb6-ns { margin-bottom: -$spacing-extra-extra-large; }\n .nb7-ns { margin-bottom: -$spacing-extra-extra-extra-large; }\n\n .nt1-ns { margin-top: -$spacing-extra-small; }\n .nt2-ns { margin-top: -$spacing-small; }\n .nt3-ns { margin-top: -$spacing-medium; }\n .nt4-ns { margin-top: -$spacing-large; }\n .nt5-ns { margin-top: -$spacing-extra-large; }\n .nt6-ns { margin-top: -$spacing-extra-extra-large; }\n .nt7-ns { margin-top: -$spacing-extra-extra-extra-large; }\n\n}\n\n@media #{$breakpoint-medium} {\n .na1-m { margin: -$spacing-extra-small; }\n .na2-m { margin: -$spacing-small; }\n .na3-m { margin: -$spacing-medium; }\n .na4-m { margin: -$spacing-large; }\n .na5-m { margin: -$spacing-extra-large; }\n .na6-m { margin: -$spacing-extra-extra-large; }\n .na7-m { margin: -$spacing-extra-extra-extra-large; }\n\n .nl1-m { margin-left: -$spacing-extra-small; }\n .nl2-m { margin-left: -$spacing-small; }\n .nl3-m { margin-left: -$spacing-medium; }\n .nl4-m { margin-left: -$spacing-large; }\n .nl5-m { margin-left: -$spacing-extra-large; }\n .nl6-m { margin-left: -$spacing-extra-extra-large; }\n .nl7-m { margin-left: -$spacing-extra-extra-extra-large; }\n\n .nr1-m { margin-right: -$spacing-extra-small; }\n .nr2-m { margin-right: -$spacing-small; }\n .nr3-m { margin-right: -$spacing-medium; }\n .nr4-m { margin-right: -$spacing-large; }\n .nr5-m { margin-right: -$spacing-extra-large; }\n .nr6-m { margin-right: -$spacing-extra-extra-large; }\n .nr7-m { margin-right: -$spacing-extra-extra-extra-large; }\n\n .nb1-m { margin-bottom: -$spacing-extra-small; }\n .nb2-m { margin-bottom: -$spacing-small; }\n .nb3-m { margin-bottom: -$spacing-medium; }\n .nb4-m { margin-bottom: -$spacing-large; }\n .nb5-m { margin-bottom: -$spacing-extra-large; }\n .nb6-m { margin-bottom: -$spacing-extra-extra-large; }\n .nb7-m { margin-bottom: -$spacing-extra-extra-extra-large; }\n\n .nt1-m { margin-top: -$spacing-extra-small; }\n .nt2-m { margin-top: -$spacing-small; }\n .nt3-m { margin-top: -$spacing-medium; }\n .nt4-m { margin-top: -$spacing-large; }\n .nt5-m { margin-top: -$spacing-extra-large; }\n .nt6-m { margin-top: -$spacing-extra-extra-large; }\n .nt7-m { margin-top: -$spacing-extra-extra-extra-large; }\n\n}\n\n@media #{$breakpoint-large} {\n .na1-l { margin: -$spacing-extra-small; }\n .na2-l { margin: -$spacing-small; }\n .na3-l { margin: -$spacing-medium; }\n .na4-l { margin: -$spacing-large; }\n .na5-l { margin: -$spacing-extra-large; }\n .na6-l { margin: -$spacing-extra-extra-large; }\n .na7-l { margin: -$spacing-extra-extra-extra-large; }\n\n .nl1-l { margin-left: -$spacing-extra-small; }\n .nl2-l { margin-left: -$spacing-small; }\n .nl3-l { margin-left: -$spacing-medium; }\n .nl4-l { margin-left: -$spacing-large; }\n .nl5-l { margin-left: -$spacing-extra-large; }\n .nl6-l { margin-left: -$spacing-extra-extra-large; }\n .nl7-l { margin-left: -$spacing-extra-extra-extra-large; }\n\n .nr1-l { margin-right: -$spacing-extra-small; }\n .nr2-l { margin-right: -$spacing-small; }\n .nr3-l { margin-right: -$spacing-medium; }\n .nr4-l { margin-right: -$spacing-large; }\n .nr5-l { margin-right: -$spacing-extra-large; }\n .nr6-l { margin-right: -$spacing-extra-extra-large; }\n .nr7-l { margin-right: -$spacing-extra-extra-extra-large; }\n\n .nb1-l { margin-bottom: -$spacing-extra-small; }\n .nb2-l { margin-bottom: -$spacing-small; }\n .nb3-l { margin-bottom: -$spacing-medium; }\n .nb4-l { margin-bottom: -$spacing-large; }\n .nb5-l { margin-bottom: -$spacing-extra-large; }\n .nb6-l { margin-bottom: -$spacing-extra-extra-large; }\n .nb7-l { margin-bottom: -$spacing-extra-extra-extra-large; }\n\n .nt1-l { margin-top: -$spacing-extra-small; }\n .nt2-l { margin-top: -$spacing-small; }\n .nt3-l { margin-top: -$spacing-medium; }\n .nt4-l { margin-top: -$spacing-large; }\n .nt5-l { margin-top: -$spacing-extra-large; }\n .nt6-l { margin-top: -$spacing-extra-extra-large; }\n .nt7-l { margin-top: -$spacing-extra-extra-extra-large; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n TABLES\n Docs: http://tachyons.io/docs/elements/tables/\n\n*/\n\n.collapse {\n border-collapse: collapse;\n border-spacing: 0;\n}\n\n.striped--light-silver:nth-child(odd) {\n background-color: $light-silver;\n}\n\n.striped--moon-gray:nth-child(odd) {\n background-color: $moon-gray;\n}\n\n.striped--light-gray:nth-child(odd) {\n background-color: $light-gray;\n}\n\n.striped--near-white:nth-child(odd) {\n background-color: $near-white;\n}\n\n.stripe-light:nth-child(odd) {\n background-color: $white-10;\n}\n\n.stripe-dark:nth-child(odd) {\n background-color: $black-10;\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n TEXT DECORATION\n Docs: http://tachyons.io/docs/typography/text-decoration/\n\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.strike { text-decoration: line-through; }\n.underline { text-decoration: underline; }\n.no-underline { text-decoration: none; }\n\n\n@media #{$breakpoint-not-small} {\n .strike-ns { text-decoration: line-through; }\n .underline-ns { text-decoration: underline; }\n .no-underline-ns { text-decoration: none; }\n}\n\n@media #{$breakpoint-medium} {\n .strike-m { text-decoration: line-through; }\n .underline-m { text-decoration: underline; }\n .no-underline-m { text-decoration: none; }\n}\n\n@media #{$breakpoint-large} {\n .strike-l { text-decoration: line-through; }\n .underline-l { text-decoration: underline; }\n .no-underline-l { text-decoration: none; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n TEXT ALIGN\n Docs: http://tachyons.io/docs/typography/text-align/\n\n Base\n t = text-align\n\n Modifiers\n l = left\n r = right\n c = center\n j = justify\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.tl { text-align: left; }\n.tr { text-align: right; }\n.tc { text-align: center; }\n.tj { text-align: justify; }\n\n@media #{$breakpoint-not-small} {\n .tl-ns { text-align: left; }\n .tr-ns { text-align: right; }\n .tc-ns { text-align: center; }\n .tj-ns { text-align: justify; }\n}\n\n@media #{$breakpoint-medium} {\n .tl-m { text-align: left; }\n .tr-m { text-align: right; }\n .tc-m { text-align: center; }\n .tj-m { text-align: justify; }\n}\n\n@media #{$breakpoint-large} {\n .tl-l { text-align: left; }\n .tr-l { text-align: right; }\n .tc-l { text-align: center; }\n .tj-l { text-align: justify; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n TEXT TRANSFORM\n Docs: http://tachyons.io/docs/typography/text-transform/\n\n Base:\n tt = text-transform\n\n Modifiers\n c = capitalize\n l = lowercase\n u = uppercase\n n = none\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.ttc { text-transform: capitalize; }\n.ttl { text-transform: lowercase; }\n.ttu { text-transform: uppercase; }\n.ttn { text-transform: none; }\n\n@media #{$breakpoint-not-small} {\n .ttc-ns { text-transform: capitalize; }\n .ttl-ns { text-transform: lowercase; }\n .ttu-ns { text-transform: uppercase; }\n .ttn-ns { text-transform: none; }\n}\n\n@media #{$breakpoint-medium} {\n .ttc-m { text-transform: capitalize; }\n .ttl-m { text-transform: lowercase; }\n .ttu-m { text-transform: uppercase; }\n .ttn-m { text-transform: none; }\n}\n\n@media #{$breakpoint-large} {\n .ttc-l { text-transform: capitalize; }\n .ttl-l { text-transform: lowercase; }\n .ttu-l { text-transform: uppercase; }\n .ttn-l { text-transform: none; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n TYPE SCALE\n Docs: http://tachyons.io/docs/typography/scale/\n\n Base:\n f = font-size\n\n Modifiers\n 1 = 1st step in size scale\n 2 = 2nd step in size scale\n 3 = 3rd step in size scale\n 4 = 4th step in size scale\n 5 = 5th step in size scale\n 6 = 6th step in size scale\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n*/\n\n/*\n * For Hero/Marketing Titles\n *\n * These generally are too large for mobile\n * so be careful using them on smaller screens.\n * */\n\n.f-6,\n.f-headline {\n font-size: $font-size-headline;\n}\n.f-5,\n.f-subheadline {\n font-size: $font-size-subheadline;\n}\n\n\n/* Type Scale */\n\n\n.f1 { font-size: $font-size-1; }\n.f2 { font-size: $font-size-2; }\n.f3 { font-size: $font-size-3; }\n.f4 { font-size: $font-size-4; }\n.f5 { font-size: $font-size-5; }\n.f6 { font-size: $font-size-6; }\n.f7 { font-size: $font-size-7; }\n\n@media #{$breakpoint-not-small}{\n .f-6-ns,\n .f-headline-ns { font-size: $font-size-headline; }\n .f-5-ns,\n .f-subheadline-ns { font-size: $font-size-subheadline; }\n .f1-ns { font-size: $font-size-1; }\n .f2-ns { font-size: $font-size-2; }\n .f3-ns { font-size: $font-size-3; }\n .f4-ns { font-size: $font-size-4; }\n .f5-ns { font-size: $font-size-5; }\n .f6-ns { font-size: $font-size-6; }\n .f7-ns { font-size: $font-size-7; }\n}\n\n@media #{$breakpoint-medium} {\n .f-6-m,\n .f-headline-m { font-size: $font-size-headline; }\n .f-5-m,\n .f-subheadline-m { font-size: $font-size-subheadline; }\n .f1-m { font-size: $font-size-1; }\n .f2-m { font-size: $font-size-2; }\n .f3-m { font-size: $font-size-3; }\n .f4-m { font-size: $font-size-4; }\n .f5-m { font-size: $font-size-5; }\n .f6-m { font-size: $font-size-6; }\n .f7-m { font-size: $font-size-7; }\n}\n\n@media #{$breakpoint-large} {\n .f-6-l,\n .f-headline-l {\n font-size: $font-size-headline;\n }\n .f-5-l,\n .f-subheadline-l {\n font-size: $font-size-subheadline;\n }\n .f1-l { font-size: $font-size-1; }\n .f2-l { font-size: $font-size-2; }\n .f3-l { font-size: $font-size-3; }\n .f4-l { font-size: $font-size-4; }\n .f5-l { font-size: $font-size-5; }\n .f6-l { font-size: $font-size-6; }\n .f7-l { font-size: $font-size-7; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n TYPOGRAPHY\n http://tachyons.io/docs/typography/measure/\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n\n\n/* Measure is limited to ~66 characters */\n.measure {\n max-width: $measure;\n}\n\n/* Measure is limited to ~80 characters */\n.measure-wide {\n max-width: $measure-wide;\n}\n\n/* Measure is limited to ~45 characters */\n.measure-narrow {\n max-width: $measure-narrow;\n}\n\n/* Book paragraph style - paragraphs are indented with no vertical spacing. */\n.indent {\n text-indent: 1em;\n margin-top: 0;\n margin-bottom: 0;\n}\n\n.small-caps {\n font-variant: small-caps;\n}\n\n/* Combine this class with a width to truncate text (or just leave as is to truncate at width of containing element. */\n\n.truncate {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n@media #{$breakpoint-not-small} {\n .measure-ns {\n max-width: $measure;\n }\n .measure-wide-ns {\n max-width: $measure-wide;\n }\n .measure-narrow-ns {\n max-width: $measure-narrow;\n }\n .indent-ns {\n text-indent: 1em;\n margin-top: 0;\n margin-bottom: 0;\n }\n .small-caps-ns {\n font-variant: small-caps;\n }\n .truncate-ns {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n}\n\n@media #{$breakpoint-medium} {\n .measure-m {\n max-width: $measure;\n }\n .measure-wide-m {\n max-width: $measure-wide;\n }\n .measure-narrow-m {\n max-width: $measure-narrow;\n }\n .indent-m {\n text-indent: 1em;\n margin-top: 0;\n margin-bottom: 0;\n }\n .small-caps-m {\n font-variant: small-caps;\n }\n .truncate-m {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n}\n\n@media #{$breakpoint-large} {\n .measure-l {\n max-width: $measure;\n }\n .measure-wide-l {\n max-width: $measure-wide;\n }\n .measure-narrow-l {\n max-width: $measure-narrow;\n }\n .indent-l {\n text-indent: 1em;\n margin-top: 0;\n margin-bottom: 0;\n }\n .small-caps-l {\n font-variant: small-caps;\n }\n .truncate-l {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n UTILITIES\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n/* Equivalent to .overflow-y-scroll */\n.overflow-container {\n overflow-y: scroll;\n}\n\n.center {\n margin-right: auto;\n margin-left: auto;\n}\n\n.mr-auto { margin-right: auto; }\n.ml-auto { margin-left: auto; }\n\n@media #{$breakpoint-not-small}{\n .center-ns {\n margin-right: auto;\n margin-left: auto;\n }\n .mr-auto-ns { margin-right: auto; }\n .ml-auto-ns { margin-left: auto; }\n}\n\n@media #{$breakpoint-medium}{\n .center-m {\n margin-right: auto;\n margin-left: auto;\n }\n .mr-auto-m { margin-right: auto; }\n .ml-auto-m { margin-left: auto; }\n}\n\n@media #{$breakpoint-large}{\n .center-l {\n margin-right: auto;\n margin-left: auto;\n }\n .mr-auto-l { margin-right: auto; }\n .ml-auto-l { margin-left: auto; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n VISIBILITY\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n\n/*\n Text that is hidden but accessible\n Ref: http://snook.ca/archives/html_and_css/hiding-content-for-accessibility\n*/\n\n.clip {\n position: fixed !important;\n _position: absolute !important;\n clip: rect(1px 1px 1px 1px); /* IE6, IE7 */\n clip: rect(1px, 1px, 1px, 1px);\n}\n\n@media #{$breakpoint-not-small} {\n .clip-ns {\n position: fixed !important;\n _position: absolute !important;\n clip: rect(1px 1px 1px 1px); /* IE6, IE7 */\n clip: rect(1px, 1px, 1px, 1px);\n }\n}\n\n@media #{$breakpoint-medium} {\n .clip-m {\n position: fixed !important;\n _position: absolute !important;\n clip: rect(1px 1px 1px 1px); /* IE6, IE7 */\n clip: rect(1px, 1px, 1px, 1px);\n }\n}\n\n@media #{$breakpoint-large} {\n .clip-l {\n position: fixed !important;\n _position: absolute !important;\n clip: rect(1px 1px 1px 1px); /* IE6, IE7 */\n clip: rect(1px, 1px, 1px, 1px);\n }\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n WHITE SPACE\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n\n.ws-normal { white-space: normal; }\n.nowrap { white-space: nowrap; }\n.pre { white-space: pre; }\n\n@media #{$breakpoint-not-small} {\n .ws-normal-ns { white-space: normal; }\n .nowrap-ns { white-space: nowrap; }\n .pre-ns { white-space: pre; }\n}\n\n@media #{$breakpoint-medium} {\n .ws-normal-m { white-space: normal; }\n .nowrap-m { white-space: nowrap; }\n .pre-m { white-space: pre; }\n}\n\n@media #{$breakpoint-large} {\n .ws-normal-l { white-space: normal; }\n .nowrap-l { white-space: nowrap; }\n .pre-l { white-space: pre; }\n}\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n VERTICAL ALIGN\n\n Media Query Extensions:\n -ns = not-small\n -m = medium\n -l = large\n\n*/\n\n.v-base { vertical-align: baseline; }\n.v-mid { vertical-align: middle; }\n.v-top { vertical-align: top; }\n.v-btm { vertical-align: bottom; }\n\n@media #{$breakpoint-not-small} {\n .v-base-ns { vertical-align: baseline; }\n .v-mid-ns { vertical-align: middle; }\n .v-top-ns { vertical-align: top; }\n .v-btm-ns { vertical-align: bottom; }\n}\n\n@media #{$breakpoint-medium} {\n .v-base-m { vertical-align: baseline; }\n .v-mid-m { vertical-align: middle; }\n .v-top-m { vertical-align: top; }\n .v-btm-m { vertical-align: bottom; }\n}\n\n@media #{$breakpoint-large} {\n .v-base-l { vertical-align: baseline; }\n .v-mid-l { vertical-align: middle; }\n .v-top-l { vertical-align: top; }\n .v-btm-l { vertical-align: bottom; }\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n HOVER EFFECTS\n Docs: http://tachyons.io/docs/themes/hovers/\n\n - Dim\n - Glow\n - Hide Child\n - Underline text\n - Grow\n - Pointer\n - Shadow\n\n*/\n\n/*\n\n Dim element on hover by adding the dim class.\n\n*/\n.dim {\n opacity: 1;\n transition: opacity .15s ease-in;\n}\n.dim:hover,\n.dim:focus {\n opacity: .5;\n transition: opacity .15s ease-in;\n}\n.dim:active {\n opacity: .8; transition: opacity .15s ease-out;\n}\n\n/*\n\n Animate opacity to 100% on hover by adding the glow class.\n\n*/\n.glow {\n transition: opacity .15s ease-in;\n}\n.glow:hover,\n.glow:focus {\n opacity: 1;\n transition: opacity .15s ease-in;\n}\n\n/*\n\n Hide child & reveal on hover:\n\n Put the hide-child class on a parent element and any nested element with the\n child class will be hidden and displayed on hover or focus.\n\n
\n
Hidden until hover or focus
\n
Hidden until hover or focus
\n
Hidden until hover or focus
\n
Hidden until hover or focus
\n
\n*/\n\n.hide-child .child {\n opacity: 0;\n transition: opacity .15s ease-in;\n}\n.hide-child:hover .child,\n.hide-child:focus .child,\n.hide-child:active .child {\n opacity: 1;\n transition: opacity .15s ease-in;\n}\n\n.underline-hover:hover,\n.underline-hover:focus {\n text-decoration: underline;\n}\n\n/* Can combine this with overflow-hidden to make background images grow on hover\n * even if you are using background-size: cover */\n\n.grow {\n -moz-osx-font-smoothing: grayscale;\n backface-visibility: hidden;\n transform: translateZ(0);\n transition: transform 0.25s ease-out;\n}\n\n.grow:hover,\n.grow:focus {\n transform: scale(1.05);\n}\n\n.grow:active {\n transform: scale(.90);\n}\n\n.grow-large {\n -moz-osx-font-smoothing: grayscale;\n backface-visibility: hidden;\n transform: translateZ(0);\n transition: transform .25s ease-in-out;\n}\n\n.grow-large:hover,\n.grow-large:focus {\n transform: scale(1.2);\n}\n\n.grow-large:active {\n transform: scale(.95);\n}\n\n/* Add pointer on hover */\n\n.pointer:hover {\n cursor: pointer;\n}\n\n/*\n Add shadow on hover.\n\n Performant box-shadow animation pattern from\n http://tobiasahlin.com/blog/how-to-animate-box-shadow/\n*/\n\n.shadow-hover {\n cursor: pointer;\n position: relative;\n transition: all 0.5s cubic-bezier(0.165, 0.84, 0.44, 1);\n}\n\n.shadow-hover::after {\n content: '';\n box-shadow: 0px 0px 16px 2px rgba( 0, 0, 0, .2 );\n border-radius: inherit;\n opacity: 0;\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n z-index: -1;\n transition: opacity 0.5s cubic-bezier(0.165, 0.84, 0.44, 1);\n}\n\n.shadow-hover:hover::after,\n.shadow-hover:focus::after {\n opacity: 1;\n}\n\n/* Combine with classes in skins and skins-pseudo for\n * many different transition possibilities. */\n\n.bg-animate,\n.bg-animate:hover,\n.bg-animate:focus {\n transition: background-color .15s ease-in-out;\n}\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n Z-INDEX\n\n Base\n z = z-index\n\n Modifiers\n -0 = literal value 0\n -1 = literal value 1\n -2 = literal value 2\n -3 = literal value 3\n -4 = literal value 4\n -5 = literal value 5\n -999 = literal value 999\n -9999 = literal value 9999\n\n -max = largest accepted z-index value as integer\n\n -inherit = string value inherit\n -initial = string value initial\n -unset = string value unset\n\n MDN: https://developer.mozilla.org/en/docs/Web/CSS/z-index\n Spec: http://www.w3.org/TR/CSS2/zindex.html\n Articles:\n https://philipwalton.com/articles/what-no-one-told-you-about-z-index/\n\n Tips on extending:\n There might be a time worth using negative z-index values.\n Or if you are using tachyons with another project, you might need to\n adjust these values to suit your needs.\n\n*/\n\n.z-0 { z-index: 0; }\n.z-1 { z-index: 1; }\n.z-2 { z-index: 2; }\n.z-3 { z-index: 3; }\n.z-4 { z-index: 4; }\n.z-5 { z-index: 5; }\n\n.z-999 { z-index: 999; }\n.z-9999 { z-index: 9999; }\n\n.z-max {\n z-index: 2147483647;\n}\n\n.z-inherit { z-index: inherit; }\n.z-initial { z-index: initial; }\n.z-unset { z-index: unset; }\n\n","\n// Converted Variables\n\n\n// Custom Media Query Variables\n\n\n/*\n\n NESTED\n Tachyons module for styling nested elements\n that are generated by a cms.\n\n*/\n\n.nested-copy-line-height p,\n.nested-copy-line-height ul,\n.nested-copy-line-height ol {\n line-height: $line-height-copy;\n}\n\n.nested-headline-line-height h1,\n.nested-headline-line-height h2,\n.nested-headline-line-height h3,\n.nested-headline-line-height h4,\n.nested-headline-line-height h5,\n.nested-headline-line-height h6 {\n line-height: $line-height-title;\n}\n\n.nested-list-reset ul,\n.nested-list-reset ol {\n padding-left: 0;\n margin-left: 0;\n list-style-type: none;\n}\n\n.nested-copy-indent p+p {\n text-indent: $letter-spacing-1;\n margin-top: $spacing-none;\n margin-bottom: $spacing-none;\n}\n\n.nested-copy-seperator p+p {\n margin-top: $spacing-copy-separator;\n}\n\n.nested-img img {\n width: 100%;\n max-width: 100%;\n display: block;\n}\n\n.nested-links a {\n color: $blue;\n transition: color .15s ease-in;\n}\n\n.nested-links a:hover,\n.nested-links a:focus {\n color: $light-blue;\n transition: color .15s ease-in;\n}\n",".wrapper\n{\n width: 100%;\n max-width: 1460px;\n margin: 0 auto;\n padding: 0 20px;\n box-sizing: border-box;\n}\n\n.opblock-tag-section\n{\n display: flex;\n flex-direction: column;\n}\n\n.try-out.btn-group {\n padding: 0;\n display: flex;\n flex: 0.1 2 auto;\n}\n\n.try-out__btn {\n margin-left: 1.25rem;\n}\n\n.opblock-tag\n{\n display: flex;\n align-items: center;\n\n padding: 10px 20px 10px 10px;\n\n cursor: pointer;\n transition: all .2s;\n\n border-bottom: 1px solid rgba($opblock-tag-border-bottom-color, .3);\n\n &:hover\n {\n background: rgba($opblock-tag-background-color-hover,.02);\n }\n}\n\n@mixin method($color)\n{\n border-color: $color;\n background: rgba($color, .1);\n\n .opblock-summary-method\n {\n background: $color;\n }\n\n .opblock-summary\n {\n border-color: $color;\n }\n\n .tab-header .tab-item.active h4 span:after\n {\n background: $color;\n }\n}\n\n\n\n\n.opblock-tag\n{\n font-size: 24px;\n\n margin: 0 0 5px 0;\n\n @include text_headline();\n\n &.no-desc\n {\n span\n {\n flex: 1;\n }\n }\n\n svg\n {\n transition: all .4s;\n }\n\n small\n {\n font-size: 14px;\n font-weight: normal;\n\n flex: 2;\n\n padding: 0 10px;\n\n @include text_body();\n }\n\n >div\n {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n flex: 1 1 150px;\n font-weight: 400;\n }\n\n @media (max-width: 640px) {\n small\n {\n flex: 1;\n }\n\n >div\n {\n flex: 1;\n }\n }\n\n .info__externaldocs\n {\n text-align: right;\n }\n}\n\n.parameter__type\n{\n font-size: 12px;\n\n padding: 5px 0;\n\n @include text_code();\n}\n\n.parameter-controls {\n margin-top: 0.75em;\n}\n\n.examples {\n &__title {\n display: block;\n font-size: 1.1em;\n font-weight: bold;\n margin-bottom: 0.75em;\n }\n\n &__section {\n margin-top: 1.5em;\n }\n &__section-header {\n font-weight: bold;\n font-size: .9rem;\n margin-bottom: .5rem;\n // color: #555;\n }\n}\n\n.examples-select {\n margin-bottom: .75em;\n display: inline-block;\n .examples-select-element {\n width: 100%;\n }\n &__section-label {\n font-weight: bold;\n font-size: .9rem;\n margin-right: .5rem;\n }\n}\n\n.example {\n &__section {\n margin-top: 1.5em;\n }\n &__section-header {\n font-weight: bold;\n font-size: .9rem;\n margin-bottom: .5rem;\n // color: #555;\n }\n}\n\n.view-line-link\n{\n position: relative;\n top: 3px;\n\n width: 20px;\n margin: 0 5px;\n\n cursor: pointer;\n transition: all .5s;\n}\n\n\n\n.opblock\n{\n margin: 0 0 15px 0;\n\n border: 1px solid $opblock-border-color;\n border-radius: 4px;\n box-shadow: 0 0 3px rgba($opblock-box-shadow-color,.19);\n\n .tab-header\n {\n display: flex;\n\n flex: 1;\n\n .tab-item\n {\n padding: 0 40px;\n\n cursor: pointer;\n\n &:first-of-type\n {\n padding: 0 40px 0 0;\n }\n &.active\n {\n h4\n {\n span\n {\n position: relative;\n\n\n &:after\n {\n position: absolute;\n bottom: -15px;\n left: 50%;\n\n width: 120%;\n height: 4px;\n\n content: '';\n transform: translateX(-50%);\n\n background: $opblock-tab-header-tab-item-active-h4-span-after-background-color;\n }\n }\n }\n }\n }\n }\n\n\n &.is-open\n {\n .opblock-summary\n {\n border-bottom: 1px solid $opblock-isopen-summary-border-bottom-color;\n }\n }\n\n .opblock-section-header\n {\n display: flex;\n align-items: center;\n\n padding: 8px 20px;\n\n min-height: 50px;\n\n background: rgba($opblock-isopen-section-header-background-color,.8);\n box-shadow: 0 1px 2px rgba($opblock-isopen-section-header-box-shadow-color,.1);\n\n >label\n {\n font-size: 12px;\n font-weight: bold;\n\n display: flex;\n align-items: center;\n\n margin: 0;\n margin-left: auto;\n\n @include text_headline();\n\n >span\n {\n padding: 0 10px 0 0;\n }\n }\n\n h4\n {\n font-size: 14px;\n\n flex: 1;\n\n margin: 0;\n\n @include text_headline();\n }\n }\n\n .opblock-summary-method\n {\n font-size: 14px;\n font-weight: bold;\n @media (max-width: 768px) {\n font-size: 12px;\n }\n\n min-width: 80px;\n padding: 6px 0;\n\n text-align: center;\n\n border-radius: 3px;\n background: $opblock-summary-method-background-color;\n text-shadow: 0 1px 0 rgba($opblock-summary-method-text-shadow-color,.1);\n\n @include text_headline($opblock-summary-method-font-color);\n }\n\n .opblock-summary-path,\n .opblock-summary-operation-id,\n .opblock-summary-path__deprecated\n {\n font-size: 16px;\n @media (max-width: 768px) {\n font-size: 12px;\n }\n\n\n display: flex;\n align-items: center;\n\n word-break: break-word;\n\n @include text_code();\n\n }\n\n .opblock-summary-path\n {\n flex-shrink: 1;\n }\n\n @media (max-width: 640px) {\n .opblock-summary-path\n {\n max-width: 100%;\n }\n }\n\n .opblock-summary-path__deprecated\n {\n text-decoration: line-through;\n }\n\n .opblock-summary-operation-id\n {\n font-size: 14px;\n }\n\n .opblock-summary-description\n {\n font-size: 13px;\n\n word-break: break-word;\n\n @include text_body();\n }\n\n .opblock-summary-path-description-wrapper\n {\n display: flex;\n flex-direction: row;\n align-items: center;\n flex-wrap: wrap;\n gap: 0px 10px;\n\n padding: 0 10px;\n\n width: 100%;\n }\n\n @media (max-width: 550px) {\n .opblock-summary-path-description-wrapper {\n flex-direction: column;\n align-items: flex-start;\n }\n }\n\n .opblock-summary\n {\n display: flex;\n align-items: center;\n\n padding: 5px;\n\n cursor: pointer;\n\n .view-line-link\n {\n position: relative;\n top: 2px;\n\n width: 0;\n margin: 0;\n\n cursor: pointer;\n transition: all .5s;\n }\n\n &:hover\n {\n .view-line-link\n {\n width: 18px;\n margin: 0 5px;\n\n &.copy-to-clipboard {\n width: 24px;\n }\n }\n }\n }\n\n\n\n &.opblock-post\n {\n @include method($_color-post);\n }\n\n &.opblock-put\n {\n @include method($_color-put);\n }\n\n &.opblock-delete\n {\n @include method($_color-delete);\n }\n\n &.opblock-get\n {\n @include method($_color-get);\n }\n\n &.opblock-patch\n {\n @include method($_color-patch);\n }\n\n &.opblock-head\n {\n @include method($_color-head);\n }\n\n &.opblock-options\n {\n @include method($_color-options);\n }\n\n &.opblock-deprecated\n {\n opacity: .6;\n\n @include method($_color-disabled);\n }\n\n .opblock-schemes\n {\n padding: 8px 20px;\n\n .schemes-title\n {\n padding: 0 10px 0 0;\n }\n }\n}\n\n.filter\n{\n .operation-filter-input\n {\n width: 100%;\n margin: 20px 0;\n padding: 10px 10px;\n\n border: 2px solid $operational-filter-input-border-color;\n }\n}\n\n.filter, .download-url-wrapper\n{\n .failed\n {\n color: red;\n }\n\n .loading\n {\n color: #aaa;\n }\n}\n\n.model-example {\n margin-top: 1em;\n}\n\n.tab\n{\n display: flex;\n\n padding: 0;\n\n list-style: none;\n\n li\n {\n font-size: 12px;\n\n min-width: 60px;\n padding: 0;\n\n cursor: pointer;\n\n @include text_headline();\n\n &:first-of-type\n {\n position: relative;\n\n padding-left: 0;\n padding-right: 12px;\n\n &:after\n {\n position: absolute;\n top: 0;\n right: 6px;\n\n width: 1px;\n height: 100%;\n\n content: '';\n\n background: rgba($tab-list-item-first-background-color,.2);\n }\n }\n\n &.active\n {\n font-weight: bold;\n }\n\n button.tablinks\n {\n background: none;\n border: 0;\n padding: 0;\n\n color: inherit;\n font-family: inherit;\n font-weight: inherit;\n }\n }\n}\n\n.opblock-description-wrapper,\n.opblock-external-docs-wrapper,\n.opblock-title_normal\n{\n font-size: 12px;\n\n margin: 0 0 5px 0;\n padding: 15px 20px;\n\n @include text_body();\n\n h4\n {\n font-size: 12px;\n\n margin: 0 0 5px 0;\n\n @include text_body();\n }\n\n p\n {\n font-size: 14px;\n\n margin: 0;\n\n @include text_body();\n }\n}\n\n.opblock-external-docs-wrapper {\n h4 {\n padding-left: 0px;\n }\n}\n\n.execute-wrapper\n{\n padding: 20px;\n\n text-align: right;\n\n .btn\n {\n width: 100%;\n padding: 8px 40px;\n }\n}\n\n.body-param-options\n{\n display: flex;\n flex-direction: column;\n\n .body-param-edit\n {\n padding: 10px 0;\n }\n\n label\n {\n padding: 8px 0;\n select\n {\n margin: 3px 0 0 0;\n }\n }\n}\n\n.responses-inner\n{\n padding: 20px;\n\n h5,\n h4\n {\n font-size: 12px;\n\n margin: 10px 0 5px 0;\n\n @include text_body();\n }\n\n .curl\n {\n white-space: normal;\n }\n}\n\n.response-col_status\n{\n font-size: 14px;\n\n @include text_body();\n\n .response-undocumented\n {\n font-size: 11px;\n\n @include text_code($response-col-status-undocumented-font-color);\n }\n}\n\n.response-col_links\n{\n padding-left: 2em;\n max-width: 40em;\n font-size: 14px;\n\n @include text_body();\n\n .response-undocumented\n {\n font-size: 11px;\n\n @include text_code($response-col-links-font-color);\n }\n\n .operation-link\n {\n margin-bottom: 1.5em;\n\n .description\n {\n margin-bottom: 0.5em;\n }\n }\n}\n\n.opblock-body\n{\n .opblock-loading-animation\n {\n display: block;\n margin: 3em;\n margin-left: auto;\n margin-right: auto;\n }\n}\n\n.opblock-body pre.microlight\n{\n font-size: 12px;\n\n margin: 0;\n padding: 10px;\n\n white-space: pre-wrap;\n word-wrap: break-word;\n word-break: break-all;\n word-break: break-word;\n hyphens: auto;\n\n border-radius: 4px;\n background: $opblock-body-background-color;\n\n overflow-wrap: break-word;\n @include text_code($opblock-body-font-color);\n\n // disabled to have syntax highliting with react-syntax-highlight\n // span\n // {\n // color: $opblock-body-font-color !important;\n // }\n\n .headerline\n {\n display: block;\n }\n}\n\n.highlight-code {\n position: relative;\n\n > .microlight {\n overflow-y: auto;\n max-height: 400px;\n min-height: 6em;\n\n code {\n white-space: pre-wrap !important;\n word-break: break-all;\n }\n }\n}\n.curl-command {\n position: relative;\n}\n\n.download-contents {\n position: absolute;\n bottom: 10px;\n right: 10px;\n background: #7d8293;\n text-align: center;\n padding: 5px;\n border: none;\n border-radius: 4px;\n font-family: sans-serif;\n font-weight: 600;\n color: white;\n font-size: 14px;\n height: 30px;\n justify-content: center;\n align-items: center;\n display: flex;\n}\n\n.scheme-container\n{\n margin: 0 0 20px 0;\n padding: 30px 0;\n\n background: $scheme-container-background-color;\n box-shadow: 0 1px 2px 0 rgba($scheme-container-box-shadow-color,.15);\n\n .schemes\n {\n display: flex;\n align-items: flex-end;\n justify-content: space-between;\n flex-wrap: wrap;\n\n gap: 10px;\n\n /*\n This wraps the servers or schemes selector.\n This was added to make sure the Authorize button is always on the right\n and the servers or schemes selector is always on the left.\n */\n > .schemes-server-container\n {\n display: flex;\n flex-wrap: wrap;\n\n gap: 10px;\n\n > label\n {\n font-size: 12px;\n font-weight: bold;\n\n display: flex;\n flex-direction: column;\n\n margin: -20px 15px 0 0;\n\n @include text_headline();\n\n select\n {\n min-width: 130px;\n\n text-transform: uppercase;\n }\n }\n }\n\n /*\n This checks if the schemes-server-container is not present and\n aligns the authorize button to the right\n */\n &:not(:has(.schemes-server-container))\n {\n justify-content: flex-end;\n }\n\n /*\n Target Authorize Button in schemes wrapper\n This was added here to fix responsiveness issues with the authorize button\n within the schemes wrapper without affecting other instances of it's usage\n */\n .auth-wrapper\n {\n flex: none;\n justify-content: none;\n\n .authorize\n {\n padding-right: 20px;\n margin: 0;\n\n display: flex;\n\n flex-wrap: nowrap;\n }\n }\n }\n}\n\n.loading-container\n{\n padding: 40px 0 60px;\n margin-top: 1em;\n min-height: 1px;\n display: flex;\n justify-content: center;\n align-items: center;\n flex-direction: column;\n\n .loading\n {\n position: relative;\n\n\n &:after\n {\n font-size: 10px;\n font-weight: bold;\n\n position: absolute;\n top: 50%;\n left: 50%;\n\n content: 'loading';\n transform: translate(-50%,-50%);\n text-transform: uppercase;\n\n @include text_headline();\n }\n\n &:before\n {\n position: absolute;\n top: 50%;\n left: 50%;\n\n display: block;\n\n width: 60px;\n height: 60px;\n margin: -30px -30px;\n\n content: '';\n animation: rotation 1s infinite linear, opacity .5s;\n\n opacity: 1;\n border: 2px solid rgba($loading-container-before-border-color, .1);\n border-top-color: rgba($loading-container-before-border-top-color, .6);\n border-radius: 100%;\n\n backface-visibility: hidden;\n\n @keyframes rotation\n {\n to\n {\n transform: rotate(360deg);\n }\n }\n }\n }\n}\n\n.response-controls {\n padding-top: 1em;\n display: flex;\n}\n\n.response-control-media-type {\n margin-right: 1em;\n\n &--accept-controller {\n select {\n border-color: $response-content-type-controls-accept-header-select-border-color;\n }\n }\n\n &__accept-message {\n color: $response-content-type-controls-accept-header-small-font-color;\n font-size: .7em;\n }\n\n &__title {\n display: block;\n margin-bottom: 0.2em;\n font-size: .7em;\n }\n}\n\n.response-control-examples {\n &__title {\n display: block;\n margin-bottom: 0.2em;\n font-size: .7em;\n }\n}\n\n@keyframes blinker\n{\n 50%\n {\n opacity: 0;\n }\n}\n\n.hidden\n{\n display: none;\n}\n\n.no-margin\n{\n height: auto;\n border: none;\n margin: 0;\n padding: 0;\n}\n\n.float-right\n{\n float: right;\n}\n\n.svg-assets\n{\n position: absolute;\n width: 0;\n height: 0;\n}\n\nsection\n{\n h3\n {\n @include text_headline();\n }\n}\n\na.nostyle {\n text-decoration: inherit;\n color: inherit;\n cursor: pointer;\n display: inline;\n\n &:visited {\n text-decoration: inherit;\n color: inherit;\n cursor: pointer;\n }\n}\n\n.fallback\n{\n padding: 1em;\n color: #aaa;\n}\n\n.version-pragma {\n height: 100%;\n padding: 5em 0px;\n\n &__message {\n display: flex;\n justify-content: center;\n height: 100%;\n font-size: 1.2em;\n text-align: center;\n line-height: 1.5em;\n\n padding: 0px .6em;\n\n > div {\n max-width: 55ch;\n flex: 1;\n }\n\n code {\n background-color: #dedede;\n padding: 4px 4px 2px;\n white-space: pre;\n }\n }\n}\n\n.opblock-link\n{\n font-weight: normal;\n\n &.shown\n {\n font-weight: bold;\n }\n}\n\nspan\n{\n &.token-string\n {\n color: #555;\n }\n\n &.token-not-formatted\n {\n color: #555;\n font-weight: bold;\n }\n}\n",".btn\n{\n font-size: 14px;\n font-weight: bold;\n\n padding: 5px 23px;\n\n transition: all .3s;\n\n border: 2px solid $btn-border-color;\n border-radius: 4px;\n background: transparent;\n box-shadow: 0 1px 2px rgba($btn-box-shadow-color,.1);\n\n @include text_headline();\n\n &.btn-sm\n {\n font-size: 12px;\n padding: 4px 23px;\n }\n\n &[disabled]\n {\n cursor: not-allowed;\n\n opacity: .3;\n }\n\n &:hover\n {\n box-shadow: 0 0 5px rgba($btn-box-shadow-color,.3);\n }\n\n &.cancel\n {\n border-color: $btn-cancel-border-color;\n background-color: $btn-cancel-background-color;\n @include text_headline($btn-cancel-font-color);\n }\n\n &.authorize\n {\n line-height: 1;\n\n display: inline;\n\n color: $btn-authorize-font-color;\n border-color: $btn-authorize-border-color;\n background-color: $btn-authorize-background-color;\n\n span\n {\n float: left;\n\n padding: 4px 20px 0 0;\n }\n\n svg\n {\n fill: $btn-authorize-svg-fill-color;\n }\n }\n\n &.execute\n {\n background-color: $btn-execute-background-color-alt;\n color: $btn-execute-font-color;\n border-color: $btn-execute-border-color;\n }\n}\n\n.btn-group\n{\n display: flex;\n\n padding: 30px;\n\n .btn\n {\n flex: 1;\n\n &:first-child\n {\n border-radius: 4px 0 0 4px;\n }\n\n &:last-child\n {\n border-radius: 0 4px 4px 0;\n }\n }\n}\n\n.authorization__btn\n{\n padding: 0 0 0 10px;\n\n border: none;\n background: none;\n\n .locked\n {\n opacity: 1;\n }\n\n .unlocked\n {\n opacity: .4;\n }\n}\n\n.opblock-summary-control,\n.models-control,\n.model-box-control\n{\n all: inherit;\n flex: 1;\n border-bottom: 0;\n padding: 0;\n cursor: pointer;\n\n &:focus {\n outline: auto;\n }\n}\n\n.expand-methods,\n.expand-operation\n{\n border: none;\n background: none;\n\n svg\n {\n width: 20px;\n height: 20px;\n }\n}\n\n.expand-methods\n{\n padding: 0 10px;\n\n &:hover\n {\n svg\n {\n fill: $expand-methods-svg-fill-color-hover;\n }\n }\n\n svg\n {\n transition: all .3s;\n\n fill: $expand-methods-svg-fill-color;\n }\n}\n\nbutton\n{\n cursor: pointer;\n\n &.invalid\n {\n @include invalidFormElement();\n }\n}\n\n.copy-to-clipboard\n{\n position: absolute;\n display: flex;\n justify-content: center;\n align-items: center;\n bottom: 10px;\n right: 100px;\n width: 30px;\n height: 30px;\n background: #7d8293;\n border-radius: 4px;\n border: none;\n\n button\n {\n flex-grow: 1;\n flex-shrink: 1;\n border: none;\n height: 25px;\n background: url(\"data:image/svg+xml, \") center center no-repeat;\n }\n}\n\n.copy-to-clipboard:active\n{\n background: #5e626f;\n}\n\n.opblock-control-arrow\n{\n border: none;\n text-align: center;\n background: none;\n}\n\n// overrides for smaller copy button for curl command\n.curl-command .copy-to-clipboard\n{\n bottom: 5px;\n right: 10px;\n width: 20px;\n height: 20px;\n\n button\n {\n height: 18px;\n }\n}\n\n// overrides for copy to clipboard button\n.opblock .opblock-summary .view-line-link.copy-to-clipboard\n{\n height: 26px;\n position: unset;\n}\n","// - - - - - - - - - - - - - - - - - - -\n// - - _mixins.scss module\n// styles for the _mixins.scss module\n@function calculateRem($size)\n{\n $remSize: $size / 16px;\n @return $remSize * 1rem;\n}\n\n@mixin font-size($size)\n{\n font-size: $size;\n font-size: calculateRem($size);\n}\n\n%clearfix\n{\n &:before,\n &:after\n {\n display: table;\n\n content: ' ';\n }\n &:after\n {\n clear: both;\n }\n}\n\n@mixin size($width, $height: $width)\n{\n width: $width;\n height: $height;\n}\n\n$ease: (\n in-quad: cubic-bezier(.550, .085, .680, .530),\n in-cubic: cubic-bezier(.550, .055, .675, .190),\n in-quart: cubic-bezier(.895, .030, .685, .220),\n in-quint: cubic-bezier(.755, .050, .855, .060),\n in-sine: cubic-bezier(.470, .000, .745, .715),\n in-expo: cubic-bezier(.950, .050, .795, .035),\n in-circ: cubic-bezier(.600, .040, .980, .335),\n in-back: cubic-bezier(.600, -.280, .735, .045),\n out-quad: cubic-bezier(.250, .460, .450, .940),\n out-cubic: cubic-bezier(.215, .610, .355, 1.000),\n out-quart: cubic-bezier(.165, .840, .440, 1.000),\n out-quint: cubic-bezier(.230, 1.000, .320, 1.000),\n out-sine: cubic-bezier(.390, .575, .565, 1.000),\n out-expo: cubic-bezier(.190, 1.000, .220, 1.000),\n out-circ: cubic-bezier(.075, .820, .165, 1.000),\n out-back: cubic-bezier(.175, .885, .320, 1.275),\n in-out-quad: cubic-bezier(.455, .030, .515, .955),\n in-out-cubic: cubic-bezier(.645, .045, .355, 1.000),\n in-out-quart: cubic-bezier(.770, .000, .175, 1.000),\n in-out-quint: cubic-bezier(.860, .000, .070, 1.000),\n in-out-sine: cubic-bezier(.445, .050, .550, .950),\n in-out-expo: cubic-bezier(1.000, .000, .000, 1.000),\n in-out-circ: cubic-bezier(.785, .135, .150, .860),\n in-out-back: cubic-bezier(.680, -.550, .265, 1.550)\n);\n\n@function ease($key)\n{\n @if map-has-key($ease, $key)\n {\n @return map-get($ease, $key);\n }\n\n @warn 'Unkown \\'#{$key}\\' in $ease.';\n @return null;\n}\n\n\n@mixin ease($key)\n{\n transition-timing-function: ease($key);\n}\n\n@mixin text-truncate\n{\n overflow: hidden;\n\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n@mixin aspect-ratio($width, $height)\n{\n position: relative;\n &:before\n {\n display: block;\n\n width: 100%;\n padding-top: ($height / $width) * 100%;\n\n content: '';\n }\n > iframe\n {\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n }\n}\n\n$browser-context: 16;\n\n@function em($pixels, $context: $browser-context)\n{\n @if (unitless($pixels))\n {\n $pixels: $pixels * 1px;\n }\n\n @if (unitless($context))\n {\n $context: $context * 1px;\n }\n\n @return $pixels / $context * 1em;\n}\n\n@mixin maxHeight($height)\n{\n @media (max-height: $height)\n {\n @content;\n }\n}\n\n\n@mixin breakpoint($class)\n{\n @if $class == tablet\n {\n @media (min-width: 768px) and (max-width: 1024px)\n {\n @content;\n }\n }\n\n @else if $class == mobile\n {\n @media (min-width: 320px) and (max-width : 736px)\n {\n @content;\n }\n }\n\n @else if $class == desktop\n {\n @media (min-width: 1400px)\n {\n @content;\n }\n }\n\n @else\n {\n @warn 'Breakpoint mixin supports: tablet, mobile, desktop';\n }\n}\n\n@mixin invalidFormElement() {\n animation: shake .4s 1;\n border-color: $_color-delete;\n background: lighten($_color-delete, 35%);\n}\n","select\n{\n font-size: 14px;\n font-weight: bold;\n\n padding: 5px 40px 5px 10px;\n\n border: 2px solid $form-select-border-color;\n border-radius: 4px;\n background: $form-select-background-color url('data:image/svg+xml, ') right 10px center no-repeat;\n background-size: 20px;\n box-shadow: 0 1px 2px 0 rgba($form-select-box-shadow-color, .25);\n\n @include text_headline();\n appearance: none;\n\n &[multiple]\n {\n margin: 5px 0;\n padding: 5px;\n\n background: $form-select-background-color;\n }\n\n &.invalid {\n @include invalidFormElement();\n }\n}\n\n.opblock-body select\n{\n min-width: 230px;\n @media (max-width: 768px)\n {\n min-width: 180px;\n }\n @media (max-width: 640px)\n {\n width: 100%;\n min-width: 100%;\n }\n}\n\nlabel\n{\n font-size: 12px;\n font-weight: bold;\n\n margin: 0 0 5px 0;\n\n @include text_headline();\n}\n\ninput[type=text],\ninput[type=password],\ninput[type=search],\ninput[type=email],\ninput[type=file]\n{\n line-height: 1;\n\n @media (max-width: 768px) {\n max-width: 175px;\n }\n}\n\n\ninput[type=text],\ninput[type=password],\ninput[type=search],\ninput[type=email],\ninput[type=file],\ntextarea\n{\n min-width: 100px;\n margin: 5px 0;\n padding: 8px 10px;\n\n border: 1px solid $form-input-border-color;\n border-radius: 4px;\n background: $form-input-background-color;\n\n\n &.invalid\n {\n @include invalidFormElement();\n }\n\n}\n\ninput,\ntextarea,\nselect {\n &[disabled] {\n // opacity: 0.85;\n background-color: #fafafa;\n color: #888;\n cursor: not-allowed;\n }\n}\n\nselect[disabled] {\n border-color: #888;\n}\n\ntextarea[disabled] {\n background-color: #41444e;\n color: #fff;\n}\n\n@keyframes shake\n{\n 10%,\n 90%\n {\n transform: translate3d(-1px, 0, 0);\n }\n\n 20%,\n 80%\n {\n transform: translate3d(2px, 0, 0);\n }\n\n 30%,\n 50%,\n 70%\n {\n transform: translate3d(-4px, 0, 0);\n }\n\n 40%,\n 60%\n {\n transform: translate3d(4px, 0, 0);\n }\n}\n\ntextarea\n{\n font-size: 12px;\n\n width: 100%;\n min-height: 280px;\n padding: 10px;\n\n border: none;\n border-radius: 4px;\n outline: none;\n background: rgba($form-textarea-background-color,.8);\n\n @include text_code();\n\n &:focus\n {\n border: 2px solid $form-textarea-focus-border-color;\n }\n\n &.curl\n {\n font-size: 12px;\n\n min-height: 100px;\n margin: 0;\n padding: 10px;\n\n resize: none;\n\n border-radius: 4px;\n background: $form-textarea-curl-background-color;\n\n @include text_code($form-textarea-curl-font-color);\n }\n}\n\n\n.checkbox\n{\n padding: 5px 0 10px;\n\n transition: opacity .5s;\n\n color: $form-checkbox-label-font-color;\n\n label\n {\n display: flex;\n }\n\n p\n {\n font-weight: normal !important;\n font-style: italic;\n\n margin: 0 !important;\n\n @include text_code();\n }\n\n input[type=checkbox]\n {\n display: none;\n\n & + label > .item\n {\n position: relative;\n top: 3px;\n\n display: inline-block;\n\n width: 16px;\n height: 16px;\n margin: 0 8px 0 0;\n padding: 5px;\n\n cursor: pointer;\n\n border-radius: 1px;\n background: $form-checkbox-background-color;\n box-shadow: 0 0 0 2px $form-checkbox-box-shadow-color;\n\n flex: none;\n\n &:active\n {\n transform: scale(.9);\n }\n }\n\n &:checked + label > .item\n {\n background: $form-checkbox-background-color url('data:image/svg+xml, ') center center no-repeat;\n }\n }\n}\n",".dialog-ux\n{\n position: fixed;\n z-index: 9999;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n .backdrop-ux\n {\n position: fixed;\n top: 0;\n right: 0;\n bottom: 0;\n left: 0;\n\n background: rgba($dialog-ux-backdrop-background-color,.8);\n }\n\n .modal-ux\n {\n position: absolute;\n z-index: 9999;\n top: 50%;\n left: 50%;\n\n width: 100%;\n min-width: 300px;\n max-width: 650px;\n\n transform: translate(-50%,-50%);\n\n border: 1px solid $dialog-ux-modal-border-color;\n border-radius: 4px;\n background: $dialog-ux-modal-background-color;\n box-shadow: 0 10px 30px 0 rgba($dialog-ux-modal-box-shadow-color,.20);\n }\n\n .modal-ux-content\n {\n overflow-y: auto;\n\n max-height: 540px;\n padding: 20px;\n\n p\n {\n font-size: 12px;\n\n margin: 0 0 5px 0;\n\n color: $dialog-ux-modal-content-font-color;\n\n @include text_body();\n }\n\n h4\n {\n font-size: 18px;\n font-weight: 600;\n\n margin: 15px 0 0 0;\n\n @include text_headline();\n }\n }\n\n .modal-ux-header\n {\n display: flex;\n\n padding: 12px 0;\n\n border-bottom: 1px solid $dialog-ux-modal-header-border-bottom-color;\n\n align-items: center;\n\n .close-modal\n {\n padding: 0 10px;\n\n border: none;\n background: none;\n\n appearance: none;\n }\n\n\n h3\n {\n font-size: 20px;\n font-weight: 600;\n\n margin: 0;\n padding: 0 20px;\n\n flex: 1;\n @include text_headline();\n }\n }\n}\n",".model\n{\n font-size: 12px;\n font-weight: 300;\n\n @include text_code();\n\n .deprecated\n {\n span,\n td\n {\n color: $model-deprecated-font-color !important;\n }\n\n > td:first-of-type {\n text-decoration: line-through;\n }\n }\n &-toggle\n {\n font-size: 10px;\n\n position: relative;\n top: 6px;\n\n display: inline-block;\n\n margin: auto .3em;\n\n cursor: pointer;\n transition: transform .15s ease-in;\n transform: rotate(90deg);\n transform-origin: 50% 50%;\n\n &.collapsed\n {\n transform: rotate(0deg);\n }\n\n &:after\n {\n display: block;\n\n width: 20px;\n height: 20px;\n\n content: '';\n\n background: url('data:image/svg+xml, ') center no-repeat;\n background-size: 100%;\n }\n }\n\n &-jump-to-path\n {\n position: relative;\n\n cursor: pointer;\n\n .view-line-link\n {\n position: absolute;\n top: -.4em;\n\n cursor: pointer;\n }\n }\n\n &-title\n {\n position: relative;\n\n &:hover .model-hint\n {\n visibility: visible;\n }\n }\n\n &-hint\n {\n position: absolute;\n top: -1.8em;\n\n visibility: hidden;\n\n padding: .1em .5em;\n\n white-space: nowrap;\n\n color: $model-hint-font-color;\n border-radius: 4px;\n background: rgba($model-hint-background-color,.7);\n }\n\n p\n {\n margin: 0 0 1em 0;\n }\n\n .property\n {\n color: #999;\n font-style: italic;\n\n &.primitive\n {\n color: #6b6b6b;\n }\n }\n\n .external-docs\n {\n color: #666;\n font-weight: normal;\n }\n}\n\ntable.model\n{\n tr\n {\n &.description\n {\n color: #666;\n font-weight: normal;\n \n td:first-child\n {\n font-weight: bold;\n }\n }\n\n &.property-row\n {\n &.required td:first-child\n {\n font-weight: bold;\n }\n\n td\n {\n vertical-align: top;\n\n &:first-child\n {\n padding-right: 0.2em;\n }\n }\n\n .star\n {\n color: red;\n }\n }\n\n &.extension\n {\n color: #777;\n\n td:last-child\n {\n vertical-align: top;\n }\n }\n\n &.external-docs\n {\n td:first-child\n {\n font-weight: bold;\n }\n }\n\n .renderedMarkdown p:first-child\n {\n margin-top: 0;\n } \n }\n}\n\nsection.models\n{\n margin: 30px 0;\n\n border: 1px solid rgba($section-models-border-color, .3);\n border-radius: 4px;\n\n .pointer\n {\n cursor: pointer;\n }\n\n &.is-open\n {\n padding: 0 0 20px;\n h4\n {\n margin: 0 0 5px 0;\n\n border-bottom: 1px solid rgba($section-models-isopen-h4-border-bottom-color, .3);\n }\n }\n h4\n {\n font-size: 16px;\n\n display: flex;\n align-items: center;\n\n margin: 0;\n padding: 10px 20px 10px 10px;\n\n cursor: pointer;\n transition: all .2s;\n\n @include text_headline($section-models-h4-font-color);\n\n svg\n {\n transition: all .4s;\n }\n\n span\n {\n flex: 1;\n }\n\n &:hover\n {\n background: rgba($section-models-h4-background-color-hover,.02);\n }\n }\n\n h5\n {\n font-size: 16px;\n\n margin: 0 0 10px 0;\n\n @include text_headline($section-models-h5-font-color);\n }\n\n .model-jump-to-path\n {\n position: relative;\n top: 5px;\n }\n\n .model-container\n {\n margin: 0 20px 15px;\n position: relative;\n\n transition: all .5s;\n\n border-radius: 4px;\n background: rgba($section-models-model-container-background-color,.05);\n\n &:hover\n {\n background: rgba($section-models-model-container-background-color,.07);\n }\n\n &:first-of-type\n {\n margin: 20px;\n }\n\n &:last-of-type\n {\n margin: 0 20px;\n }\n\n .models-jump-to-path {\n position: absolute;\n top: 8px;\n right: 5px;\n opacity: 0.65;\n }\n }\n\n .model-box\n {\n background: none;\n }\n}\n\n\n.model-box\n{\n padding: 10px;\n display: inline-block;\n\n border-radius: 4px;\n background: rgba($section-models-model-box-background-color,.1);\n\n .model-jump-to-path\n {\n position: relative;\n top: 4px;\n }\n\n &.deprecated\n {\n opacity: .5;\n }\n}\n\n\n.model-title\n{\n font-size: 16px;\n\n @include text_headline($section-models-model-title-font-color);\n\n img\n {\n margin-left: 1em;\n position: relative;\n bottom: 0px;\n }\n}\n\n.model-deprecated-warning\n{\n font-size: 16px;\n font-weight: 600;\n\n margin-right: 1em;\n\n @include text_headline($_color-delete);\n}\n\n\nspan\n{\n > span.model\n {\n .brace-close\n {\n padding: 0 0 0 10px;\n }\n }\n}\n\n.prop-name\n{\n display: inline-block;\n\n margin-right: 1em;\n}\n\n.prop-type\n{\n color: $prop-type-font-color;\n}\n\n.prop-enum\n{\n display: block;\n}\n.prop-format\n{\n color: $prop-format-font-color;\n}\n",".servers\n{\n > label\n {\n font-size: 12px;\n\n margin: -20px 15px 0 0;\n\n @include text_headline();\n\n select\n {\n min-width: 130px;\n max-width: 100%;\n width: 100%;\n }\n }\n\n h4.message {\n padding-bottom: 2em;\n }\n\n table {\n tr {\n width: 30em;\n }\n td {\n display: inline-block;\n max-width: 15em;\n vertical-align: middle;\n padding-top: 10px;\n padding-bottom: 10px;\n\n &:first-of-type {\n padding-right: 1em;\n }\n\n input {\n width: 100%;\n height: 100%;\n }\n }\n }\n\n .computed-url {\n margin: 2em 0;\n\n code {\n display: inline-block;\n padding: 4px;\n font-size: 16px;\n margin: 0 1em;\n }\n }\n}\n\n.servers-title {\n font-size: 12px;\n font-weight: bold;\n}\n\n.operation-servers {\n h4.message {\n margin-bottom: 2em;\n }\n}\n","table\n{\n width: 100%;\n padding: 0 10px;\n\n border-collapse: collapse;\n\n &.model\n {\n tbody\n {\n tr\n {\n td\n {\n padding: 0;\n\n vertical-align: top;\n\n &:first-of-type\n {\n width: 174px;\n padding: 0 0 0 2em;\n }\n }\n }\n }\n }\n\n &.headers\n {\n td\n {\n font-size: 12px;\n font-weight: 300;\n\n vertical-align: middle;\n\n @include text_code();\n }\n\n .header-example\n {\n color: #999;\n font-style: italic;\n }\n }\n\n tbody\n {\n tr\n {\n td\n {\n padding: 10px 0 0 0;\n\n vertical-align: top;\n\n &:first-of-type\n {\n min-width: 6em;\n padding: 10px 0;\n }\n }\n }\n }\n\n thead\n {\n tr\n {\n th,\n td\n {\n font-size: 12px;\n font-weight: bold;\n\n padding: 12px 0;\n\n text-align: left;\n\n border-bottom: 1px solid rgba($table-thead-td-border-bottom-color, .2);\n\n @include text_body();\n }\n }\n }\n}\n\n.parameters-col_description\n{\n width: 99%; // forces other columns to shrink to their content widths\n margin-bottom: 2em;\n input\n {\n width: 100%;\n max-width: 340px;\n }\n\n select {\n border-width: 1px;\n }\n\n .markdown, .renderedMarkdown {\n p {\n margin: 0;\n }\n }\n}\n\n.parameter__name\n{\n font-size: 16px;\n font-weight: normal;\n\n // hack to give breathing room to the name column\n // TODO: refactor all of this to flexbox\n margin-right: .75em;\n\n @include text_headline();\n\n &.required\n {\n font-weight: bold;\n\n span\n {\n color: red;\n }\n\n &:after\n {\n font-size: 10px;\n\n position: relative;\n top: -6px;\n\n padding: 5px;\n\n content: 'required';\n\n color: rgba($table-parameter-name-required-font-color, .6);\n }\n }\n}\n\n.parameter__in,\n.parameter__extension\n{\n font-size: 12px;\n font-style: italic;\n\n @include text_code($table-parameter-in-font-color);\n}\n\n.parameter__deprecated\n{\n font-size: 12px;\n font-style: italic;\n\n @include text_code($table-parameter-deprecated-font-color);\n}\n\n.parameter__empty_value_toggle {\n display: block;\n font-size: 13px;\n padding-top: 5px;\n padding-bottom: 12px;\n\n input {\n margin-right: 7px;\n width: auto;\n }\n\n &.disabled {\n opacity: 0.7;\n }\n}\n\n\n.table-container\n{\n padding: 20px;\n}\n\n\n.response-col_description {\n width: 99%; // forces other columns to shrink to their content widths\n\n .markdown, .renderedMarkdown {\n p {\n margin: 0;\n }\n }\n}\n\n.response-col_links {\n min-width: 6em;\n}\n\n.response__extension\n{\n font-size: 12px;\n font-style: italic;\n\n @include text_code($table-parameter-in-font-color);\n}\n",".topbar\n{\n padding: 10px 0;\n\n background-color: $topbar-background-color;\n .topbar-wrapper\n {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 10px;\n }\n @media (max-width: 550px) {\n .topbar-wrapper\n {\n flex-direction: column;\n align-items: start;\n }\n }\n\n a\n {\n font-size: 1.5em;\n font-weight: bold;\n\n display: flex;\n align-items: center;\n flex: 1;\n\n max-width: 300px;\n\n text-decoration: none;\n\n @include text_headline($topbar-link-font-color);\n\n span\n {\n margin: 0;\n padding: 0 10px;\n }\n }\n\n .download-url-wrapper\n {\n display: flex;\n flex: 3;\n justify-content: flex-end;\n\n input[type=text]\n {\n width: 100%;\n max-width: 100%;\n margin: 0;\n\n border: 2px solid $topbar-download-url-wrapper-element-border-color;\n border-radius: 4px 0 0 4px;\n outline: none;\n }\n\n .select-label\n {\n display: flex;\n align-items: center;\n\n width: 100%;\n max-width: 600px;\n margin: 0;\n color: #f0f0f0;\n span\n {\n font-size: 16px;\n\n flex: 1;\n\n padding: 0 10px 0 0;\n\n text-align: right;\n }\n\n select\n {\n flex: 2;\n\n width: 100%;\n\n border: 2px solid $topbar-download-url-wrapper-element-border-color;\n outline: none;\n box-shadow: none;\n }\n }\n\n\n .download-url-button\n {\n font-size: 16px;\n font-weight: bold;\n\n padding: 4px 30px;\n\n border: none;\n border-radius: 0 4px 4px 0;\n background: $topbar-download-url-button-background-color;\n\n @include text_headline($topbar-download-url-button-font-color);\n }\n }\n @media (max-width: 550px) {\n .download-url-wrapper\n {\n width: 100%;\n }\n }\n}\n",".info\n{\n margin: 50px 0;\n\n &.failed-config\n { \n max-width: 880px;\n margin-left: auto;\n margin-right: auto;\n text-align: center\n }\n\n hgroup.main\n {\n margin: 0 0 20px 0;\n a\n {\n font-size: 12px;\n }\n }\n pre \n {\n font-size: 14px;\n }\n p, li, table\n {\n font-size: 14px;\n\n @include text_body();\n }\n\n h1, h2, h3, h4, h5\n {\n @include text_body();\n }\n\n a\n {\n font-size: 14px;\n\n transition: all .4s;\n\n @include text_body($info-link-font-color);\n\n &:hover\n {\n color: darken($info-link-font-color-hover, 15%);\n }\n }\n > div\n {\n margin: 0 0 5px 0;\n }\n\n .base-url\n {\n font-size: 12px;\n font-weight: 300 !important;\n\n margin: 0;\n\n @include text_code();\n }\n\n .title\n {\n font-size: 36px;\n\n margin: 0;\n\n @include text_body();\n\n small\n {\n font-size: 10px;\n\n position: relative;\n top: -5px;\n\n display: inline-block;\n\n margin: 0 0 0 5px;\n padding: 2px 4px;\n\n vertical-align: super;\n\n border-radius: 57px;\n background: $info-title-small-background-color;\n \n &.version-stamp\n {\n background-color: #89bf04;\n }\n\n pre\n {\n margin: 0;\n padding: 0;\n\n @include text_headline($info-title-small-pre-font-color);\n }\n }\n }\n}\n",".auth-btn-wrapper\n{\n display: flex;\n\n padding: 10px 0;\n\n justify-content: center;\n\n .btn-done {\n margin-right: 1em;\n }\n}\n\n.auth-wrapper\n{\n display: flex;\n\n flex: 1;\n justify-content: flex-end;\n\n .authorize\n {\n padding-right: 20px;\n margin-left: 10px;\n margin-right: 10px;\n }\n}\n\n.auth-container\n{\n margin: 0 0 10px 0;\n padding: 10px 20px;\n\n border-bottom: 1px solid $auth-container-border-color;\n\n &:last-of-type\n {\n margin: 0;\n padding: 10px 20px;\n\n border: 0;\n }\n\n h4\n {\n margin: 5px 0 15px 0 !important;\n }\n\n .wrapper\n {\n margin: 0;\n padding: 0;\n }\n\n input[type=text],\n input[type=password]\n {\n min-width: 230px;\n }\n\n .errors\n {\n font-size: 12px;\n\n padding: 10px;\n\n border-radius: 4px;\n\n background-color: #ffeeee;\n\n color: red;\n\n margin: 1em;\n\n @include text_code();\n\n b\n {\n text-transform: capitalize;\n margin-right: 1em;\n }\n }\n}\n\n.scopes\n{\n h2\n {\n font-size: 14px;\n\n @include text_headline();\n\n a\n {\n font-size: 12px;\n color: $auth-select-all-none-link-font-color;\n cursor: pointer;\n padding-left: 10px;\n text-decoration: underline;\n }\n }\n}\n\n.scope-def\n{\n padding: 0 0 20px 0;\n}\n",".errors-wrapper\n{\n margin: 20px;\n padding: 10px 20px;\n\n animation: scaleUp .5s;\n\n border: 2px solid $_color-delete;\n border-radius: 4px;\n background: rgba($_color-delete, .1);\n\n .error-wrapper\n {\n margin: 0 0 10px 0;\n }\n\n .errors\n {\n h4\n {\n font-size: 14px;\n\n margin: 0;\n\n @include text_code();\n }\n\n small\n {\n color: $errors-wrapper-errors-small-font-color;\n }\n\n .message\n { \n white-space: pre-line;\n \n &.thrown\n {\n max-width: 100%;\n }\n }\n\n .error-line\n {\n text-decoration: underline;\n cursor: pointer;\n }\n }\n\n hgroup\n {\n display: flex;\n\n align-items: center;\n\n h4\n {\n font-size: 20px;\n\n margin: 0;\n\n flex: 1;\n @include text_headline();\n }\n }\n}\n\n\n@keyframes scaleUp\n{\n 0%\n {\n transform: scale(.8);\n\n opacity: 0;\n }\n 100%\n {\n transform: scale(1);\n\n opacity: 1;\n }\n}\n",".Resizer.vertical.disabled {\n display: none;\n}",".markdown, .renderedMarkdown {\n p, pre {\n margin: 1em auto;\n\n word-break: break-all; /* Fallback trick */\n word-break: break-word;\n }\n pre {\n color: black;\n font-weight: normal;\n white-space: pre-wrap;\n background: none;\n padding: 0px;\n }\n\n code {\n font-size: 14px;\n padding: 5px 7px;\n\n border-radius: 4px;\n background: rgba($info-code-background-color,.05);\n\n @include text_code($info-code-font-color);\n }\n\n pre > code {\n display: block;\n }\n}\n",".json-schema-2020-12 {\n margin: 0 20px 15px 20px;\n border-radius: 4px;\n padding: 12px 0 12px 20px;\n background-color: rgba($section-models-model-container-background-color, .05);\n\n &:first-of-type {\n margin: 20px;\n }\n\n &:last-of-type {\n margin: 0 20px;\n }\n\n &--embedded {\n background-color: inherit;\n padding: 0 inherit 0 inherit;\n }\n\n &-body {\n @include expansion-border;\n margin: 2px 0;\n\n &--collapsed {\n display: none;\n }\n }\n}\n\n\n","@mixin expansion-border {\n margin: 0 0 0 20px;\n border-left: 1px dashed rgba($section-models-model-container-background-color, 0.1);\n}\n\n@import './JSONSchema/json-schema';\n@import './Accordion/accordion';\n@import './ExpandDeepButton/expand-deep-button';\n@import './keywords/all';\n",".json-schema-2020-12-accordion {\n outline: none;\n border: none;\n padding-left: 0;\n\n &__children {\n display: inline-block;\n }\n\n &__icon {\n width: 18px;\n height: 18px;\n display: inline-block;\n vertical-align: bottom;\n\n &--expanded {\n transition: transform .15s ease-in;\n transform: rotate(-90deg);\n transform-origin: 50% 50%;\n }\n\n &--collapsed {\n transition: transform .15s ease-in;\n transform: rotate(0deg);\n transform-origin: 50% 50%;\n }\n\n & svg {\n height: 20px;\n width: 20px;\n }\n }\n}\n\n",".json-schema-2020-12-expand-deep-button {\n @include text_headline($section-models-model-title-font-color);\n font-size: 12px;\n color: rgb(175, 174, 174);\n border: none;\n padding-right: 0;\n}\n",".json-schema-2020-12-keyword {\n margin: 5px 0 5px 0;\n\n &__children {\n @include expansion-border;\n padding: 0;\n\n &--collapsed {\n display: none;\n }\n }\n\n &__name {\n font-size: 12px;\n margin-left: 20px;\n font-weight: bold;\n\n &--primary {\n color: $text-code-default-font-color;\n font-style: normal;\n }\n\n &--secondary {\n color: #6b6b6b;\n font-style: italic;\n }\n }\n\n &__value {\n color: #6b6b6b;\n font-style: italic;\n font-size: 12px;\n font-weight: normal;\n\n &--primary {\n color: $text-code-default-font-color;\n font-style: normal;\n }\n\n &--secondary {\n color: #6b6b6b;\n font-style: italic;\n }\n\n &--const {\n @include text_code();\n color: #6b6b6b;\n font-style: normal;\n display: inline-block;\n margin-left: 10px;\n line-height: 1.5;\n padding: 1px 4px 1px 4px;\n border: 1px dashed #6b6b6b;\n border-radius: 4px;\n }\n\n &--warning {\n @extend .json-schema-2020-12-keyword__value--const;\n color: red;\n border: 1px dashed red;\n }\n }\n}\n.json-schema-2020-12-keyword__name--secondary + .json-schema-2020-12-keyword__value--secondary::before {\n content: '='\n}\n\n.json-schema-2020-12__attribute {\n font-family: monospace;\n color: $text-code-default-font-color;\n font-size: 12px;\n text-transform: lowercase;\n padding-left: 10px;\n\n &--primary {\n color: $prop-type-font-color;\n }\n\n &--muted {\n color: gray;\n }\n\n &--warning {\n color: red;\n }\n}\n\n@import './$vocabulary/$vocabulary';\n@import './Description/description';\n@import './Title/title';\n@import './Properties/properties';\n@import './PatternProperties/pattern-properties';\n@import './Enum/enum';\n@import './Constraint/constraint';\n@import './DependentRequired/dependent-required';\n",".json-schema-2020-12 {\n &-keyword--\\$vocabulary {\n ul {\n @include expansion-border;\n }\n }\n\n &-\\$vocabulary-uri {\n margin-left: 35px;\n\n &--disabled {\n text-decoration: line-through;\n }\n }\n}\n",".json-schema-2020-12-keyword--description {\n color: #6b6b6b;\n font-size: 12px;\n margin-left: 20px;\n\n & p {\n margin: 0;\n }\n}\n",".json-schema-2020-12 {\n &__title {\n @include text_headline($section-models-model-title-font-color);\n display: inline-block;\n font-weight: bold;\n font-size: 12px;\n line-height: normal;\n\n & .json-schema-2020-12-keyword__name {\n margin: 0;\n }\n }\n\n &-property {\n margin: 7px 0;\n\n .json-schema-2020-12__title {\n @include text_code();\n font-size: 12px;\n vertical-align: middle;\n }\n }\n}\n",".json-schema-2020-12 {\n &-keyword--properties {\n & > ul {\n margin: 0;\n padding: 0;\n border: none;\n }\n }\n\n &-property {\n list-style-type: none;\n\n &--required {\n & > .json-schema-2020-12:first-of-type > .json-schema-2020-12-head .json-schema-2020-12__title:after {\n content: '*';\n color: red;\n font-weight: bold;\n }\n }\n }\n}\n",".json-schema-2020-12 {\n &-keyword--patternProperties {\n ul {\n margin: 0;\n padding: 0;\n border: none;\n }\n\n .json-schema-2020-12__title:first-of-type::before {\n color: $prop-type-font-color;\n content: \"/\";\n }\n\n .json-schema-2020-12__title:first-of-type::after {\n color: $prop-type-font-color;\n content: \"/\";\n }\n }\n}\n",".json-schema-2020-12-keyword--enum {\n & > ul {\n display: inline-block;\n padding: 0;\n margin: 0;\n\n li {\n display: inline;\n list-style-type: none;\n }\n }\n}\n",".json-schema-2020-12__constraint {\n @include text_code();\n margin-left: 10px;\n line-height: 1.5;\n padding: 1px 3px;\n color: white;\n background-color: #805AD5;\n border-radius: 4px;\n\n &--string {\n color: white;\n background-color: #D69E2E;\n }\n}\n",".json-schema-2020-12-keyword--dependentRequired {\n & > ul {\n display: inline-block;\n padding: 0;\n margin: 0;\n\n li {\n display: inline;\n list-style-type: none;\n }\n }\n}\n",".model-box {\n // inferred names of Schema Objects\n & .json-schema-2020-12:not(.json-schema-2020-12--embedded) > .json-schema-2020-12-head .json-schema-2020-12__title:first-of-type {\n font-size: 16px;\n }\n\n & > .json-schema-2020-12 {\n margin: 0;\n }\n\n .json-schema-2020-12 {\n padding: 0;\n background-color: transparent;\n }\n\n .json-schema-2020-12-accordion, .json-schema-2020-12-expand-deep-button {\n background-color: transparent;\n }\n}\n",".models .json-schema-2020-12:not(.json-schema-2020-12--embedded) > .json-schema-2020-12-head .json-schema-2020-12__title:first-of-type {\n font-size: 16px;\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/assets/stylesheets/swagger-ui.js b/assets/stylesheets/swagger-ui.js new file mode 100644 index 00000000000..7a06a0a09eb --- /dev/null +++ b/assets/stylesheets/swagger-ui.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUICore=t():e.SwaggerUICore=t()}(this,(function(){return(()=>{var e={6024:(e,t,n)=>{"use strict";n.d(t,{Z:()=>R});var r=n(4250),a=n.n(r),o=n(6349),s=n.n(o),l=n(4606),i=n.n(l),c=n(4555),u=n.n(c),p=n(4291),d=n.n(p),m=n(1885),h=n.n(m),f=n(1093),g=n.n(f),v=n(4883),y=n.n(v),E=n(8493),S=n.n(E),b=n(3942),C=n.n(b),x=n(6689),w=n.n(x);const _=require("react-immutable-pure-component");var A=n.n(_),k=n(8082),N=n.n(k),I=n(580),q=n.n(I),R=function(e){d()(r,e);var t=h()(r);function r(){var e,n;s()(this,r);for(var a=arguments.length,o=new Array(a),l=0;l{"use strict";n.d(t,{Z:()=>k});var r=n(6768),a=n.n(r),o=n(6349),s=n.n(o),l=n(4606),i=n.n(l),c=n(4555),u=n.n(c),p=n(4291),d=n.n(p),m=n(1885),h=n.n(m),f=n(1093),g=n.n(f),v=n(7252),y=n.n(v),E=n(4883),S=n.n(E),b=n(6689),C=n.n(b),x=n(3883),w=n.n(x),_=(n(580),n(1890)),A=n(7504),k=function(e){d()(n,e);var t=h()(n);function n(e,r){var a;s()(this,n),a=t.call(this,e,r),g()(u()(a),"getDefinitionUrl",(function(){var e=a.props.specSelectors;return new(w())(e.url(),A.Z.location).toString()}));var o=(0,e.getConfigs)().validatorUrl;return a.state={url:a.getDefinitionUrl(),validatorUrl:void 0===o?"https://validator.swagger.io/validator":o},a}return i()(n,[{key:"UNSAFE_componentWillReceiveProps",value:function(e){var t=(0,e.getConfigs)().validatorUrl;this.setState({url:this.getDefinitionUrl(),validatorUrl:void 0===t?"https://validator.swagger.io/validator":t})}},{key:"render",value:function(){var e,t,n=(0,this.props.getConfigs)().spec,r=(0,_.Nm)(this.state.validatorUrl);return"object"===a()(n)&&y()(n).length?null:this.state.url&&(0,_.hW)(this.state.validatorUrl)&&(0,_.hW)(this.state.url)?C().createElement("span",{className:"float-right"},C().createElement("a",{target:"_blank",rel:"noopener noreferrer",href:S()(e="".concat(r,"/debug?url=")).call(e,encodeURIComponent(this.state.url))},C().createElement(N,{src:S()(t="".concat(r,"?url=")).call(t,encodeURIComponent(this.state.url)),alt:"Online validator badge"}))):null}}]),n}(C().Component),N=function(e){d()(n,e);var t=h()(n);function n(e){var r;return s()(this,n),(r=t.call(this,e)).state={loaded:!1,error:!1},r}return i()(n,[{key:"componentDidMount",value:function(){var e=this,t=new Image;t.onload=function(){e.setState({loaded:!0})},t.onerror=function(){e.setState({error:!0})},t.src=this.props.src}},{key:"UNSAFE_componentWillReceiveProps",value:function(e){var t=this;if(e.src!==this.props.src){var n=new Image;n.onload=function(){t.setState({loaded:!0})},n.onerror=function(){t.setState({error:!0})},n.src=e.src}}},{key:"render",value:function(){return this.state.error?C().createElement("img",{alt:"Error"}):this.state.loaded?C().createElement("img",{src:this.props.src,alt:this.props.alt}):null}}]),n}(C().Component)},2552:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d,s:()=>m});var r=n(6689),a=n.n(r),o=(n(580),n(963));const s=require("remarkable/linkify"),l=require("dompurify");var i=n.n(l),c=n(9003),u=n.n(c);function p(e){var t=e.source,n=e.className,r=void 0===n?"":n,l=e.getConfigs;if("string"!=typeof t)return null;var i=new o.Remarkable({html:!0,typographer:!0,breaks:!0,linkTarget:"_blank"}).use(s.linkify);i.core.ruler.disable(["replacements","smartquotes"]);var c=l().useUnsafeMarkdown,p=i.render(t),d=m(p,{useUnsafeMarkdown:c});return t&&p&&d?a().createElement("div",{className:u()(r,"markdown"),dangerouslySetInnerHTML:{__html:d}}):null}i().addHook&&i().addHook("beforeSanitizeElements",(function(e){return e.href&&e.setAttribute("rel","noopener noreferrer"),e})),p.defaultProps={getConfigs:function(){return{useUnsafeMarkdown:!1}}};const d=p;function m(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.useUnsafeMarkdown,r=void 0!==n&&n,a=r,o=r?[]:["style","class"];return r&&!m.hasWarnedAboutDeprecation&&(console.warn("useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0."),m.hasWarnedAboutDeprecation=!0),i().sanitize(e,{ADD_ATTR:["target"],FORBID_TAGS:["style","form"],ALLOW_DATA_ATTR:a,FORBID_ATTR:o})}m.hasWarnedAboutDeprecation=!1},5308:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>d});var r,a=n(4235),o=n.n(a),s=n(874),l=n.n(s),i=n(1890),c=n(9595),u=n(5102),p={};const d=p;o()(r=l()(u).call(u)).call(r,(function(e){if("./index.js"!==e){var t=u(e);p[(0,i.Zl)(e)]=t.default?t.default:t}})),p.SafeRender=c.default},5812:(e,t,n)=>{"use strict";n.r(t),n.d(t,{SHOW_AUTH_POPUP:()=>m,AUTHORIZE:()=>h,LOGOUT:()=>f,PRE_AUTHORIZE_OAUTH2:()=>g,AUTHORIZE_OAUTH2:()=>v,VALIDATE:()=>y,CONFIGURE_AUTH:()=>E,RESTORE_AUTHORIZATION:()=>S,showDefinitions:()=>b,authorize:()=>C,authorizeWithPersistOption:()=>x,logout:()=>w,logoutWithPersistOption:()=>_,preAuthorizeImplicit:()=>A,authorizeOauth2:()=>k,authorizeOauth2WithPersistOption:()=>N,authorizePassword:()=>I,authorizeApplication:()=>q,authorizeAccessCodeWithFormParams:()=>R,authorizeAccessCodeWithBasicAuthentication:()=>P,authorizeRequest:()=>T,configureAuth:()=>O,restoreAuthorization:()=>M,persistAuthorizationIfNeeded:()=>j,authPopup:()=>V});var r=n(6768),a=n.n(r),o=n(8344),s=n.n(o),l=n(4994),i=n.n(l),c=n(3883),u=n.n(c),p=n(7504),d=n(1890),m="show_popup",h="authorize",f="logout",g="pre_authorize_oauth2",v="authorize_oauth2",y="validate",E="configure_auth",S="restore_authorization";function b(e){return{type:m,payload:e}}function C(e){return{type:h,payload:e}}var x=function(e){return function(t){var n=t.authActions;n.authorize(e),n.persistAuthorizationIfNeeded()}};function w(e){return{type:f,payload:e}}var _=function(e){return function(t){var n=t.authActions;n.logout(e),n.persistAuthorizationIfNeeded()}},A=function(e){return function(t){var n=t.authActions,r=t.errActions,a=e.auth,o=e.token,l=e.isValid,i=a.schema,c=a.name,u=i.get("flow");delete p.Z.swaggerUIRedirectOauth2,"accessCode"===u||l||r.newAuthErr({authId:c,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),o.error?r.newAuthErr({authId:c,source:"auth",level:"error",message:s()(o)}):n.authorizeOauth2WithPersistOption({auth:a,token:o})}};function k(e){return{type:v,payload:e}}var N=function(e){return function(t){var n=t.authActions;n.authorizeOauth2(e),n.persistAuthorizationIfNeeded()}},I=function(e){return function(t){var n=t.authActions,r=e.schema,a=e.name,o=e.username,s=e.password,l=e.passwordType,c=e.clientId,u=e.clientSecret,p={grant_type:"password",scope:e.scopes.join(" "),username:o,password:s},m={};switch(l){case"request-body":!function(e,t,n){t&&i()(e,{client_id:t});n&&i()(e,{client_secret:n})}(p,c,u);break;case"basic":m.Authorization="Basic "+(0,d.r3)(c+":"+u);break;default:console.warn("Warning: invalid passwordType ".concat(l," was passed, not including client id and secret"))}return n.authorizeRequest({body:(0,d.GZ)(p),url:r.get("tokenUrl"),name:a,headers:m,query:{},auth:e})}};var q=function(e){return function(t){var n=t.authActions,r=e.schema,a=e.scopes,o=e.name,s=e.clientId,l=e.clientSecret,i={Authorization:"Basic "+(0,d.r3)(s+":"+l)},c={grant_type:"client_credentials",scope:a.join(" ")};return n.authorizeRequest({body:(0,d.GZ)(c),name:o,url:r.get("tokenUrl"),auth:e,headers:i})}},R=function(e){var t=e.auth,n=e.redirectUrl;return function(e){var r=e.authActions,a=t.schema,o=t.name,s=t.clientId,l=t.clientSecret,i=t.codeVerifier,c={grant_type:"authorization_code",code:t.code,client_id:s,client_secret:l,redirect_uri:n,code_verifier:i};return r.authorizeRequest({body:(0,d.GZ)(c),name:o,url:a.get("tokenUrl"),auth:t})}},P=function(e){var t=e.auth,n=e.redirectUrl;return function(e){var r=e.authActions,a=t.schema,o=t.name,s=t.clientId,l=t.clientSecret,i=t.codeVerifier,c={Authorization:"Basic "+(0,d.r3)(s+":"+l)},u={grant_type:"authorization_code",code:t.code,client_id:s,redirect_uri:n,code_verifier:i};return r.authorizeRequest({body:(0,d.GZ)(u),name:o,url:a.get("tokenUrl"),auth:t,headers:c})}},T=function(e){return function(t){var n,r=t.fn,o=t.getConfigs,l=t.authActions,c=t.errActions,p=t.oas3Selectors,d=t.specSelectors,m=t.authSelectors,h=e.body,f=e.query,g=void 0===f?{}:f,v=e.headers,y=void 0===v?{}:v,E=e.name,S=e.url,b=e.auth,C=(m.getConfigs()||{}).additionalQueryStringParams;if(d.isOAS3()){var x=p.serverEffectiveValue(p.selectedServer());n=u()(S,x,!0)}else n=u()(S,d.url(),!0);"object"===a()(C)&&(n.query=i()({},n.query,C));var w=n.toString(),_=i()({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},y);r.fetch({url:w,method:"post",headers:_,query:g,body:h,requestInterceptor:o().requestInterceptor,responseInterceptor:o().responseInterceptor}).then((function(e){var t=JSON.parse(e.data),n=t&&(t.error||""),r=t&&(t.parseError||"");e.ok?n||r?c.newAuthErr({authId:E,level:"error",source:"auth",message:s()(t)}):l.authorizeOauth2WithPersistOption({auth:b,token:t}):c.newAuthErr({authId:E,level:"error",source:"auth",message:e.statusText})})).catch((function(e){var t=new Error(e).message;if(e.response&&e.response.data){var n=e.response.data;try{var r="string"==typeof n?JSON.parse(n):n;r.error&&(t+=", error: ".concat(r.error)),r.error_description&&(t+=", description: ".concat(r.error_description))}catch(e){}}c.newAuthErr({authId:E,level:"error",source:"auth",message:t})}))}};function O(e){return{type:E,payload:e}}function M(e){return{type:S,payload:e}}var j=function(){return function(e){var t=e.authSelectors;if((0,e.getConfigs)().persistAuthorization){var n=t.authorized();localStorage.setItem("authorized",s()(n.toJS()))}}},V=function(e,t){return function(){p.Z.swaggerUIRedirectOauth2=t,p.Z.open(e)}}},3705:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>m,preauthorizeBasic:()=>h,preauthorizeApiKey:()=>f});var r=n(1093),a=n.n(r),o=n(593),s=n.n(o),l=n(4883),i=n.n(l),c=n(3962),u=n(5812),p=n(35),d=n(8302);function m(){return{afterLoad:function(e){this.rootInjects=this.rootInjects||{},this.rootInjects.initOAuth=e.authActions.configureAuth,this.rootInjects.preauthorizeApiKey=s()(f).call(f,null,e),this.rootInjects.preauthorizeBasic=s()(h).call(h,null,e)},statePlugins:{auth:{reducers:c.default,actions:u,selectors:p},spec:{wrapActions:d}}}}function h(e,t,n,r){var o,s=e.authActions.authorize,l=e.specSelectors,c=l.specJson,u=(0,l.isOAS3)()?["components","securitySchemes"]:["securityDefinitions"],p=c().getIn(i()(o=[]).call(o,u,[t]));return p?s(a()({},t,{value:{username:n,password:r},schema:p.toJS()})):null}function f(e,t,n){var r,o=e.authActions.authorize,s=e.specSelectors,l=s.specJson,c=(0,s.isOAS3)()?["components","securitySchemes"]:["securityDefinitions"],u=l().getIn(i()(r=[]).call(r,c,[t]));return u?o(a()({},t,{value:n,schema:u.toJS()})):null}},3962:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>f});var r,a=n(1093),o=n.n(a),s=n(8030),l=n.n(s),i=n(4235),c=n.n(i),u=n(4994),p=n.n(u),d=n(5572),m=n(1890),h=n(5812);const f=(r={},o()(r,h.SHOW_AUTH_POPUP,(function(e,t){var n=t.payload;return e.set("showDefinitions",n)})),o()(r,h.AUTHORIZE,(function(e,t){var n,r=t.payload,a=(0,d.fromJS)(r),o=e.get("authorized")||(0,d.Map)();return c()(n=a.entrySeq()).call(n,(function(t){var n=l()(t,2),r=n[0],a=n[1];if(!(0,m.Wl)(a.getIn))return e.set("authorized",o);var s=a.getIn(["schema","type"]);if("apiKey"===s||"http"===s)o=o.set(r,a);else if("basic"===s){var i=a.getIn(["value","username"]),c=a.getIn(["value","password"]);o=(o=o.setIn([r,"value"],{username:i,header:"Basic "+(0,m.r3)(i+":"+c)})).setIn([r,"schema"],a.get("schema"))}})),e.set("authorized",o)})),o()(r,h.AUTHORIZE_OAUTH2,(function(e,t){var n,r=t.payload,a=r.auth,o=r.token;a.token=p()({},o),n=(0,d.fromJS)(a);var s=e.get("authorized")||(0,d.Map)();return s=s.set(n.get("name"),n),e.set("authorized",s)})),o()(r,h.LOGOUT,(function(e,t){var n=t.payload,r=e.get("authorized").withMutations((function(e){c()(n).call(n,(function(t){e.delete(t)}))}));return e.set("authorized",r)})),o()(r,h.CONFIGURE_AUTH,(function(e,t){var n=t.payload;return e.set("configs",n)})),o()(r,h.RESTORE_AUTHORIZATION,(function(e,t){var n=t.payload;return e.set("authorized",(0,d.fromJS)(n.authorized))})),r)},35:(e,t,n)=>{"use strict";n.r(t),n.d(t,{shownDefinitions:()=>S,definitionsToAuthorize:()=>b,getDefinitionsByNames:()=>C,definitionsForRequirements:()=>x,authorized:()=>w,isAuthorized:()=>_,getConfigs:()=>A});var r=n(8030),a=n.n(r),o=n(4235),s=n.n(o),l=n(9998),i=n.n(l),c=n(5626),u=n.n(c),p=n(8493),d=n.n(p),m=n(3942),h=n.n(m),f=n(7252),g=n.n(f),v=n(6814),y=n(5572),E=function(e){return e},S=(0,v.createSelector)(E,(function(e){return e.get("showDefinitions")})),b=(0,v.createSelector)(E,(function(){return function(e){var t,n=e.specSelectors.securityDefinitions()||(0,y.Map)({}),r=(0,y.List)();return s()(t=n.entrySeq()).call(t,(function(e){var t=a()(e,2),n=t[0],o=t[1],s=(0,y.Map)();s=s.set(n,o),r=r.push(s)})),r}})),C=function(e,t){return function(e){var n,r=e.specSelectors;console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.");var o=r.securityDefinitions(),l=(0,y.List)();return s()(n=t.valueSeq()).call(n,(function(e){var t,n=(0,y.Map)();s()(t=e.entrySeq()).call(t,(function(e){var t,r,l=a()(e,2),i=l[0],c=l[1],u=o.get(i);"oauth2"===u.get("type")&&c.size&&(t=u.get("scopes"),s()(r=t.keySeq()).call(r,(function(e){c.contains(e)||(t=t.delete(e))})),u=u.set("allowedScopes",t));n=n.set(i,u)})),l=l.push(n)})),l}},x=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,y.List)();return function(e){var n=e.authSelectors.definitionsToAuthorize()||(0,y.List)();return i()(n).call(n,(function(e){return u()(t).call(t,(function(t){return t.get(e.keySeq().first())}))}))}},w=(0,v.createSelector)(E,(function(e){return e.get("authorized")||(0,y.Map)()})),_=function(e,t){return function(e){var n,r=e.authSelectors.authorized();return y.List.isList(t)?!!i()(n=t.toJS()).call(n,(function(e){var t,n;return-1===d()(t=h()(n=g()(e)).call(n,(function(e){return!!r.get(e)}))).call(t,!1)})).length:null}},A=(0,v.createSelector)(E,(function(e){return e.get("configs")}))},8302:(e,t,n)=>{"use strict";n.r(t),n.d(t,{execute:()=>o});var r=n(67),a=n.n(r),o=function(e,t){var n=t.authSelectors,r=t.specSelectors;return function(t){var o=t.path,s=t.method,l=t.operation,i=t.extras,c={authorized:n.authorized()&&n.authorized().toJS(),definitions:r.securityDefinitions()&&r.securityDefinitions().toJS(),specSecurity:r.security()&&r.security().toJS()};return e(a()({path:o,method:s,operation:l,securities:c},i))}}},714:(e,t,n)=>{"use strict";n.r(t),n.d(t,{UPDATE_CONFIGS:()=>o,TOGGLE_CONFIGS:()=>s,update:()=>l,toggle:()=>i,loaded:()=>c});var r=n(1093),a=n.n(r),o="configs_update",s="configs_toggle";function l(e,t){return{type:o,payload:a()({},e,t)}}function i(e){return{type:s,payload:e}}var c=function(){return function(e){var t=e.getConfigs,n=e.authActions;if(t().persistAuthorization){var r=localStorage.getItem("authorized");r&&n.restoreAuthorization({authorized:JSON.parse(r)})}}}},2256:(e,t,n)=>{"use strict";n.r(t),n.d(t,{parseYamlConfig:()=>o});var r=n(9793),a=n.n(r),o=function(e,t){try{return a().load(e)}catch(e){return t&&t.errActions.newThrownErr(new Error(e)),{}}}},1661:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(5163),a=n(2256),o=n(714),s=n(2698),l=n(9018),i=n(7743),c={getLocalConfig:function(){return(0,a.parseYamlConfig)(r)}};function u(){return{statePlugins:{spec:{actions:s,selectors:c},configs:{reducers:i.default,actions:o,selectors:l}}}}},7743:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r,a=n(1093),o=n.n(a),s=n(5572),l=n(714);const i=(r={},o()(r,l.UPDATE_CONFIGS,(function(e,t){return e.merge((0,s.fromJS)(t.payload))})),o()(r,l.TOGGLE_CONFIGS,(function(e,t){var n=t.payload,r=e.get(n);return e.set(n,!r)})),r)},9018:(e,t,n)=>{"use strict";n.r(t),n.d(t,{get:()=>o});var r=n(7104),a=n.n(r),o=function(e,t){return e.getIn(a()(t)?t:[t])}},2698:(e,t,n)=>{"use strict";n.r(t),n.d(t,{downloadConfig:()=>a,getConfigByUrl:()=>o});var r=n(2256),a=function(e){return function(t){return(0,t.fn.fetch)(e)}},o=function(e,t){return function(n){var a=n.specActions;if(e)return a.downloadConfig(e).then(o,o);function o(n){n instanceof Error||n.status>=400?(a.updateLoadingStatus("failedConfig"),a.updateLoadingStatus("failedConfig"),a.updateUrl(""),console.error(n.statusText+" "+e.url),t(null)):t((0,r.parseYamlConfig)(n.text))}}}},1970:(e,t,n)=>{"use strict";n.r(t),n.d(t,{setHash:()=>r});var r=function(e){return e?history.pushState(null,null,"#".concat(e)):window.location.hash=""}},4980:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(2179),a=n(877),o=n(4584);function s(){return[r.default,{statePlugins:{configs:{wrapActions:{loaded:function(e,t){return function(){e.apply(void 0,arguments);var n=decodeURIComponent(window.location.hash);t.layoutActions.parseDeepLinkHash(n)}}}}},wrapComponents:{operation:a.default,OperationTag:o.default}}]}},2179:(e,t,n)=>{"use strict";n.r(t),n.d(t,{clearScrollTo:()=>R,default:()=>P,parseDeepLinkHash:()=>N,readyToScroll:()=>I,scrollTo:()=>k,scrollToElement:()=>q,show:()=>A});var r=n(1093),a=n.n(r),o=n(8030),s=n.n(o),l=n(7104),i=n.n(l),c=n(4883),u=n.n(c),p=n(600),d=n.n(p),m=n(3942),h=n.n(m),f=n(8493),g=n.n(f),v=n(1970);const y=require("zenscroll");var E,S=n.n(y),b=n(1890),C=n(5572),x=n.n(C),w="layout_scroll_to",_="layout_clear_scroll",A=function(e,t){var n=t.getConfigs,r=t.layoutSelectors;return function(){for(var t=arguments.length,a=new Array(t),o=0;o-1&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),n.show(h()(y).call(y,(function(e){return e.replace(/_/g," ")})),!0)),n.show(y,!0)}(g()(m).call(m,"_")>-1||g()(v).call(v,"_")>-1)&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),n.show(h()(i).call(i,(function(e){return e.replace(/_/g," ")})),!0)),n.show(i,!0),n.scrollTo(i)}}},I=function(e,t){return function(n){var r=n.layoutSelectors.getScrollToKey();x().is(r,(0,C.fromJS)(e))&&(n.layoutActions.scrollToElement(t),n.layoutActions.clearScrollTo())}},q=function(e,t){return function(n){try{t=t||n.fn.getScrollParent(e),S().createScroller(t).to(e)}catch(e){console.error(e)}}},R=function(){return{type:_}};const P={fn:{getScrollParent:function(e,t){var n=document.documentElement,r=getComputedStyle(e),a="absolute"===r.position,o=t?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===r.position)return n;for(var s=e;s=s.parentElement;)if(r=getComputedStyle(s),(!a||"static"!==r.position)&&o.test(r.overflow+r.overflowY+r.overflowX))return s;return n}},statePlugins:{layout:{actions:{scrollToElement:q,scrollTo:k,clearScrollTo:R,readyToScroll:I,parseDeepLinkHash:N},selectors:{getScrollToKey:function(e){return e.get("scrollToKey")},isShownKeyFromUrlHashArray:function(e,t){var n=s()(t,2),r=n[0],a=n[1];return a?["operations",r,a]:r?["operations-tag",r]:[]},urlHashArrayFromIsShownKey:function(e,t){var n=s()(t,3),r=n[0],a=n[1],o=n[2];return"operations"==r?[a,o]:"operations-tag"==r?[a]:[]}},reducers:(E={},a()(E,w,(function(e,t){return e.set("scrollToKey",x().fromJS(t.payload))})),a()(E,_,(function(e){return e.delete("scrollToKey")})),E),wrapActions:{show:A}}}}},4584:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>E});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4555),i=n.n(l),c=n(4291),u=n.n(c),p=n(1885),d=n.n(p),m=n(1093),h=n.n(m),f=n(4883),g=n.n(f),v=n(6689),y=n.n(v);n(580);const E=function(e,t){return function(n){u()(o,n);var r=d()(o);function o(){var e,n;a()(this,o);for(var s=arguments.length,l=new Array(s),c=0;c{"use strict";n.r(t),n.d(t,{default:()=>E});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4555),i=n.n(l),c=n(4291),u=n.n(c),p=n(1885),d=n.n(p),m=n(1093),h=n.n(m),f=n(4883),g=n.n(f),v=n(6689),y=n.n(v);n(8082);const E=function(e,t){return function(n){u()(o,n);var r=d()(o);function o(){var e,n;a()(this,o);for(var s=arguments.length,l=new Array(s),c=0;c{"use strict";n.r(t),n.d(t,{default:()=>g});var r=n(4994),a=n.n(r),o=n(9478),s=n.n(o),l=n(4883),i=n.n(l),c=n(8493),u=n.n(c),p=n(8344),d=n.n(p),m=n(6814),h=n(5572),f=n(7504);function g(e){var t=e.fn;return{statePlugins:{spec:{actions:{download:function(e){return function(n){var r=n.errActions,o=n.specSelectors,l=n.specActions,c=n.getConfigs,u=t.fetch,p=c();function d(t){if(t instanceof Error||t.status>=400)return l.updateLoadingStatus("failed"),r.newThrownErr(a()(new Error((t.message||t.statusText)+" "+e),{source:"fetch"})),void(!t.status&&t instanceof Error&&function(){try{var t;if("URL"in f.Z?t=new(s())(e):(t=document.createElement("a")).href=e,"https:"!==t.protocol&&"https:"===f.Z.location.protocol){var n=a()(new Error("Possible mixed-content issue? The page was loaded over https:// but a ".concat(t.protocol,"// URL was specified. Check that you are not attempting to load mixed content.")),{source:"fetch"});return void r.newThrownErr(n)}if(t.origin!==f.Z.location.origin){var o,l=a()(new Error(i()(o="Possible cross-origin (CORS) issue? The URL origin (".concat(t.origin,") does not match the page (")).call(o,f.Z.location.origin,"). Check the server returns the correct 'Access-Control-Allow-*' headers.")),{source:"fetch"});r.newThrownErr(l)}}catch(e){return}}());l.updateLoadingStatus("success"),l.updateSpec(t.text),o.url()!==e&&l.updateUrl(e)}e=e||o.url(),l.updateLoadingStatus("loading"),r.clear({source:"fetch"}),u({url:e,loadSpec:!0,requestInterceptor:p.requestInterceptor||function(e){return e},responseInterceptor:p.responseInterceptor||function(e){return e},credentials:"same-origin",headers:{Accept:"application/json,*/*"}}).then(d,d)}},updateLoadingStatus:function(e){var t,n=[null,"loading","failed","success","failedConfig"];-1===u()(n).call(n,e)&&console.error(i()(t="Error: ".concat(e," is not one of ")).call(t,d()(n)));return{type:"spec_update_loading_status",payload:e}}},reducers:{spec_update_loading_status:function(e,t){return"string"==typeof t.payload?e.set("loadingStatus",t.payload):e}},selectors:{loadingStatus:(0,m.createSelector)((function(e){return e||(0,h.Map)()}),(function(e){return e.get("loadingStatus")||null}))}}}}}},4966:(e,t,n)=>{"use strict";n.r(t),n.d(t,{NEW_THROWN_ERR:()=>a,NEW_THROWN_ERR_BATCH:()=>o,NEW_SPEC_ERR:()=>s,NEW_SPEC_ERR_BATCH:()=>l,NEW_AUTH_ERR:()=>i,CLEAR:()=>c,CLEAR_BY:()=>u,newThrownErr:()=>p,newThrownErrBatch:()=>d,newSpecErr:()=>m,newSpecErrBatch:()=>h,newAuthErr:()=>f,clear:()=>g,clearBy:()=>v});var r=n(41),a="err_new_thrown_err",o="err_new_thrown_err_batch",s="err_new_spec_err",l="err_new_spec_err_batch",i="err_new_auth_err",c="err_clear",u="err_clear_by";function p(e){return{type:a,payload:(0,r.serializeError)(e)}}function d(e){return{type:o,payload:e}}function m(e){return{type:s,payload:e}}function h(e){return{type:l,payload:e}}function f(e){return{type:i,payload:e}}function g(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return{type:c,payload:e}}function v(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:function(){return!0};return{type:u,payload:e}}},2860:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(9998),a=n.n(r),o=n(3942),s=n.n(o);const l=require("lodash/reduce");var i=n.n(l),c=[n(2392),n(1835)];function u(e){var t,n={jsSpec:{}},r=i()(c,(function(e,t){try{var r=t.transform(e,n);return a()(r).call(r,(function(e){return!!e}))}catch(t){return console.error("Transformer error:",t),e}}),e);return s()(t=a()(r).call(r,(function(e){return!!e}))).call(t,(function(e){return!e.get("line")&&e.get("path"),e}))}},2392:(e,t,n)=>{"use strict";n.r(t),n.d(t,{transform:()=>p});var r=n(3942),a=n.n(r),o=n(8493),s=n.n(o),l=n(600),i=n.n(l),c=n(66),u=n.n(c);function p(e){return a()(e).call(e,(function(e){var t,n="is not of a type(s)",r=s()(t=e.get("message")).call(t,n);if(r>-1){var a,o,l=i()(a=e.get("message")).call(a,r+n.length).split(",");return e.set("message",i()(o=e.get("message")).call(o,0,r)+function(e){return u()(e).call(e,(function(e,t,n,r){return n===r.length-1&&r.length>1?e+"or "+t:r[n+1]&&r.length>2?e+t+", ":r[n+1]?e+t+" ":e+t}),"should be a")}(l))}return e}))}},1835:(e,t,n)=>{"use strict";n.r(t),n.d(t,{transform:()=>r});n(3942),n(8493),n(1712),n(5572);function r(e,t){t.jsSpec;return e}},7793:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(3527),a=n(4966),o=n(7667);function s(e){return{statePlugins:{err:{reducers:(0,r.default)(e),actions:a,selectors:o}}}}},3527:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>E});var r=n(1093),a=n.n(r),o=n(4994),s=n.n(o),l=n(3942),i=n.n(l),c=n(4883),u=n.n(c),p=n(9998),d=n.n(p),m=n(7834),h=n.n(m),f=n(4966),g=n(5572),v=n(2860),y={line:0,level:"error",message:"Unknown error"};function E(){var e;return e={},a()(e,f.NEW_THROWN_ERR,(function(e,t){var n=t.payload,r=s()(y,n,{type:"thrown"});return e.update("errors",(function(e){return(e||(0,g.List)()).push((0,g.fromJS)(r))})).update("errors",(function(e){return(0,v.default)(e)}))})),a()(e,f.NEW_THROWN_ERR_BATCH,(function(e,t){var n=t.payload;return n=i()(n).call(n,(function(e){return(0,g.fromJS)(s()(y,e,{type:"thrown"}))})),e.update("errors",(function(e){var t;return u()(t=e||(0,g.List)()).call(t,(0,g.fromJS)(n))})).update("errors",(function(e){return(0,v.default)(e)}))})),a()(e,f.NEW_SPEC_ERR,(function(e,t){var n=t.payload,r=(0,g.fromJS)(n);return r=r.set("type","spec"),e.update("errors",(function(e){return(e||(0,g.List)()).push((0,g.fromJS)(r)).sortBy((function(e){return e.get("line")}))})).update("errors",(function(e){return(0,v.default)(e)}))})),a()(e,f.NEW_SPEC_ERR_BATCH,(function(e,t){var n=t.payload;return n=i()(n).call(n,(function(e){return(0,g.fromJS)(s()(y,e,{type:"spec"}))})),e.update("errors",(function(e){var t;return u()(t=e||(0,g.List)()).call(t,(0,g.fromJS)(n))})).update("errors",(function(e){return(0,v.default)(e)}))})),a()(e,f.NEW_AUTH_ERR,(function(e,t){var n=t.payload,r=(0,g.fromJS)(s()({},n));return r=r.set("type","auth"),e.update("errors",(function(e){return(e||(0,g.List)()).push((0,g.fromJS)(r))})).update("errors",(function(e){return(0,v.default)(e)}))})),a()(e,f.CLEAR,(function(e,t){var n,r=t.payload;if(!r||!e.get("errors"))return e;var a=d()(n=e.get("errors")).call(n,(function(e){var t;return h()(t=e.keySeq()).call(t,(function(t){var n=e.get(t),a=r[t];return!a||n!==a}))}));return e.merge({errors:a})})),a()(e,f.CLEAR_BY,(function(e,t){var n,r=t.payload;if(!r||"function"!=typeof r)return e;var a=d()(n=e.get("errors")).call(n,(function(e){return r(e)}));return e.merge({errors:a})})),e}},7667:(e,t,n)=>{"use strict";n.r(t),n.d(t,{allErrors:()=>o,lastError:()=>s});var r=n(5572),a=n(6814),o=(0,a.createSelector)((function(e){return e}),(function(e){return e.get("errors",(0,r.List)())})),s=(0,a.createSelector)(o,(function(e){return e.last()}))},9978:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4309);function a(){return{fn:{opsFilter:r.default}}}},4309:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(9998),a=n.n(r),o=n(8493),s=n.n(o);function l(e,t){return a()(e).call(e,(function(e,n){return-1!==s()(n).call(n,t)}))}},5474:(e,t,n)=>{"use strict";n.r(t),n.d(t,{UPDATE_LAYOUT:()=>a,UPDATE_FILTER:()=>o,UPDATE_MODE:()=>s,SHOW:()=>l,updateLayout:()=>i,updateFilter:()=>c,show:()=>u,changeMode:()=>p});var r=n(1890),a="layout_update_layout",o="layout_update_filter",s="layout_update_mode",l="layout_show";function i(e){return{type:a,payload:e}}function c(e){return{type:o,payload:e}}function u(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return e=(0,r.AF)(e),{type:l,payload:{thing:e,shown:t}}}function p(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=(0,r.AF)(e),{type:s,payload:{thing:e,mode:t}}}},6821:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(5672),a=n(5474),o=n(4400),s=n(8989);function l(){return{statePlugins:{layout:{reducers:r.default,actions:a,selectors:o},spec:{wrapSelectors:s}}}}},5672:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r,a=n(1093),o=n.n(a),s=n(4883),l=n.n(s),i=n(5572),c=n(5474);const u=(r={},o()(r,c.UPDATE_LAYOUT,(function(e,t){return e.set("layout",t.payload)})),o()(r,c.UPDATE_FILTER,(function(e,t){return e.set("filter",t.payload)})),o()(r,c.SHOW,(function(e,t){var n=t.payload.shown,r=(0,i.fromJS)(t.payload.thing);return e.update("shown",(0,i.fromJS)({}),(function(e){return e.set(r,n)}))})),o()(r,c.UPDATE_MODE,(function(e,t){var n,r=t.payload.thing,a=t.payload.mode;return e.setIn(l()(n=["modes"]).call(n,r),(a||"")+"")})),r)},4400:(e,t,n)=>{"use strict";n.r(t),n.d(t,{current:()=>u,currentFilter:()=>p,isShown:()=>d,whatMode:()=>m,showSummary:()=>h});var r=n(6731),a=n.n(r),o=n(4883),s=n.n(o),l=n(6814),i=n(1890),c=n(5572),u=function(e){return e.get("layout")},p=function(e){return e.get("filter")},d=function(e,t,n){return t=(0,i.AF)(t),e.get("shown",(0,c.fromJS)({})).get((0,c.fromJS)(t),n)},m=function(e,t){var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return t=(0,i.AF)(t),e.getIn(s()(n=["modes"]).call(n,a()(t)),r)},h=(0,l.createSelector)((function(e){return e}),(function(e){return!d(e,"editor")}))},8989:(e,t,n)=>{"use strict";n.r(t),n.d(t,{taggedOperations:()=>l});var r=n(4883),a=n.n(r),o=n(600),s=n.n(o),l=function(e,t){return function(n){for(var r,o=arguments.length,l=new Array(o>1?o-1:0),i=1;i=0&&(c=s()(c).call(c,0,f)),c}}},9150:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(593),a=n.n(r);function o(e){var t=e.configs,n={debug:0,info:1,log:2,warn:3,error:4},r=function(e){return n[e]||-1},o=t.logLevel,s=r(o);function l(e){for(var t,n=arguments.length,a=new Array(n>1?n-1:0),o=1;o=s&&(t=console)[e].apply(t,a)}return l.warn=a()(l).call(l,null,"warn"),l.error=a()(l).call(l,null,"error"),l.info=a()(l).call(l,null,"info"),l.debug=a()(l).call(l,null,"debug"),{rootInjects:{log:l}}}},7002:(e,t,n)=>{"use strict";n.r(t),n.d(t,{UPDATE_SELECTED_SERVER:()=>r,UPDATE_REQUEST_BODY_VALUE:()=>a,UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG:()=>o,UPDATE_REQUEST_BODY_INCLUSION:()=>s,UPDATE_ACTIVE_EXAMPLES_MEMBER:()=>l,UPDATE_REQUEST_CONTENT_TYPE:()=>i,UPDATE_RESPONSE_CONTENT_TYPE:()=>c,UPDATE_SERVER_VARIABLE_VALUE:()=>u,SET_REQUEST_BODY_VALIDATE_ERROR:()=>p,CLEAR_REQUEST_BODY_VALIDATE_ERROR:()=>d,CLEAR_REQUEST_BODY_VALUE:()=>m,setSelectedServer:()=>h,setRequestBodyValue:()=>f,setRetainRequestBodyValueFlag:()=>g,setRequestBodyInclusion:()=>v,setActiveExamplesMember:()=>y,setRequestContentType:()=>E,setResponseContentType:()=>S,setServerVariableValue:()=>b,setRequestBodyValidateError:()=>C,clearRequestBodyValidateError:()=>x,initRequestBodyValidateError:()=>w,clearRequestBodyValue:()=>_});var r="oas3_set_servers",a="oas3_set_request_body_value",o="oas3_set_request_body_retain_flag",s="oas3_set_request_body_inclusion",l="oas3_set_active_examples_member",i="oas3_set_request_content_type",c="oas3_set_response_content_type",u="oas3_set_server_variable_value",p="oas3_set_request_body_validate_error",d="oas3_clear_request_body_validate_error",m="oas3_clear_request_body_value";function h(e,t){return{type:r,payload:{selectedServerUrl:e,namespace:t}}}function f(e){var t=e.value,n=e.pathMethod;return{type:a,payload:{value:t,pathMethod:n}}}var g=function(e){var t=e.value,n=e.pathMethod;return{type:o,payload:{value:t,pathMethod:n}}};function v(e){var t=e.value,n=e.pathMethod,r=e.name;return{type:s,payload:{value:t,pathMethod:n,name:r}}}function y(e){var t=e.name,n=e.pathMethod,r=e.contextType,a=e.contextName;return{type:l,payload:{name:t,pathMethod:n,contextType:r,contextName:a}}}function E(e){var t=e.value,n=e.pathMethod;return{type:i,payload:{value:t,pathMethod:n}}}function S(e){var t=e.value,n=e.path,r=e.method;return{type:c,payload:{value:t,path:n,method:r}}}function b(e){var t=e.server,n=e.namespace,r=e.key,a=e.val;return{type:u,payload:{server:t,namespace:n,key:r,val:a}}}var C=function(e){var t=e.path,n=e.method,r=e.validationErrors;return{type:p,payload:{path:t,method:n,validationErrors:r}}},x=function(e){var t=e.path,n=e.method;return{type:d,payload:{path:t,method:n}}},w=function(e){var t=e.pathMethod;return{type:d,payload:{path:t[0],method:t[1]}}},_=function(e){var t=e.pathMethod;return{type:m,payload:{pathMethod:t}}}},3723:(e,t,n)=>{"use strict";n.r(t),n.d(t,{definitionsToAuthorize:()=>E});var r=n(1093),a=n.n(r),o=n(8030),s=n.n(o),l=n(4883),i=n.n(l),c=n(4235),u=n.n(c),p=n(9998),d=n.n(p),m=n(66),h=n.n(m),f=n(6814),g=n(5572),v=n(7779);var y,E=(y=(0,f.createSelector)((function(e){return e}),(function(e){return e.specSelectors.securityDefinitions()}),(function(e,t){var n,r=(0,g.List)();return t?(u()(n=t.entrySeq()).call(n,(function(e){var t,n=s()(e,2),o=n[0],l=n[1],i=l.get("type");if("oauth2"===i&&u()(t=l.get("flows").entrySeq()).call(t,(function(e){var t=s()(e,2),n=t[0],i=t[1],c=(0,g.fromJS)({flow:n,authorizationUrl:i.get("authorizationUrl"),tokenUrl:i.get("tokenUrl"),scopes:i.get("scopes"),type:l.get("type"),description:l.get("description")});r=r.push(new g.Map(a()({},o,d()(c).call(c,(function(e){return void 0!==e})))))})),"http"!==i&&"apiKey"!==i||(r=r.push(new g.Map(a()({},o,l)))),"openIdConnect"===i&&l.get("openIdConnectData")){var c=l.get("openIdConnectData"),p=c.get("grant_types_supported")||["authorization_code","implicit"];u()(p).call(p,(function(e){var t,n=c.get("scopes_supported")&&h()(t=c.get("scopes_supported")).call(t,(function(e,t){return e.set(t,"")}),new g.Map),s=(0,g.fromJS)({flow:e,authorizationUrl:c.get("authorization_endpoint"),tokenUrl:c.get("token_endpoint"),scopes:n,type:"oauth2",openIdConnectUrl:l.get("openIdConnectUrl")});r=r.push(new g.Map(a()({},o,d()(s).call(s,(function(e){return void 0!==e})))))}))}})),r):r})),function(e,t){return function(){for(var n=t.getSystem().specSelectors.specJson(),r=arguments.length,a=new Array(r),o=0;o{"use strict";n.r(t),n.d(t,{default:()=>d});var r=n(4250),a=n.n(r),o=n(8030),s=n.n(o),l=n(3942),i=n.n(l),c=n(6689),u=n.n(c),p=(n(580),n(8082),n(5572));const d=function(e){var t,n=e.callbacks,r=e.getComponent,o=e.specPath,l=r("OperationContainer",!0);if(!n)return u().createElement("span",null,"No callbacks");var c=i()(t=n.entrySeq()).call(t,(function(t){var n,r=s()(t,2),c=r[0],d=r[1];return u().createElement("div",{key:c},u().createElement("h2",null,c),i()(n=d.entrySeq()).call(n,(function(t){var n,r=s()(t,2),d=r[0],m=r[1];return"$$ref"===d?null:u().createElement("div",{key:d},i()(n=m.entrySeq()).call(n,(function(t){var n=s()(t,2),r=n[0],i=n[1];if("$$ref"===r)return null;var m=(0,p.fromJS)({operation:i});return u().createElement(l,a()({},e,{op:m,key:r,tag:"",method:r,path:d,specPath:o.push(c,d,r),allowTryItOut:!1}))})))})))}));return u().createElement("div",null,c)}},6775:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>x});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4555),i=n.n(l),c=n(4291),u=n.n(c),p=n(1885),d=n.n(p),m=n(1093),h=n.n(m),f=n(4994),g=n.n(f),v=n(9998),y=n.n(v),E=n(3942),S=n.n(E),b=n(6689),C=n.n(b),x=(n(580),function(e){u()(n,e);var t=d()(n);function n(e,r){var o;a()(this,n),o=t.call(this,e,r),h()(i()(o),"onChange",(function(e){var t=o.props.onChange,n=e.target,r=n.value,a=n.name,s=g()({},o.state.value);a?s[a]=r:s=r,o.setState({value:s},(function(){return t(o.state)}))}));var s=o.props,l=s.name,c=s.schema,u=o.getValue();return o.state={name:l,schema:c,value:u},o}return s()(n,[{key:"getValue",value:function(){var e=this.props,t=e.name,n=e.authorized;return n&&n.getIn([t,"value"])}},{key:"render",value:function(){var e,t,n=this.props,r=n.schema,a=n.getComponent,o=n.errSelectors,s=n.name,l=a("Input"),i=a("Row"),c=a("Col"),u=a("authError"),p=a("Markdown",!0),d=a("JumpToPath",!0),m=(r.get("scheme")||"").toLowerCase(),h=this.getValue(),f=y()(e=o.allErrors()).call(e,(function(e){return e.get("authId")===s}));if("basic"===m){var g,v=h?h.get("username"):null;return C().createElement("div",null,C().createElement("h4",null,C().createElement("code",null,s||r.get("name")),"  (http, Basic)",C().createElement(d,{path:["securityDefinitions",s]})),v&&C().createElement("h6",null,"Authorized"),C().createElement(i,null,C().createElement(p,{source:r.get("description")})),C().createElement(i,null,C().createElement("label",null,"Username:"),v?C().createElement("code",null," ",v," "):C().createElement(c,null,C().createElement(l,{type:"text",required:"required",name:"username","aria-label":"auth-basic-username",onChange:this.onChange,autoFocus:!0}))),C().createElement(i,null,C().createElement("label",null,"Password:"),v?C().createElement("code",null," ****** "):C().createElement(c,null,C().createElement(l,{autoComplete:"new-password",name:"password",type:"password","aria-label":"auth-basic-password",onChange:this.onChange}))),S()(g=f.valueSeq()).call(g,(function(e,t){return C().createElement(u,{error:e,key:t})})))}return"bearer"===m?C().createElement("div",null,C().createElement("h4",null,C().createElement("code",null,s||r.get("name")),"  (http, Bearer)",C().createElement(d,{path:["securityDefinitions",s]})),h&&C().createElement("h6",null,"Authorized"),C().createElement(i,null,C().createElement(p,{source:r.get("description")})),C().createElement(i,null,C().createElement("label",null,"Value:"),h?C().createElement("code",null," ****** "):C().createElement(c,null,C().createElement(l,{type:"text","aria-label":"auth-bearer-value",onChange:this.onChange,autoFocus:!0}))),S()(t=f.valueSeq()).call(t,(function(e,t){return C().createElement(u,{error:e,key:t})}))):C().createElement("div",null,C().createElement("em",null,C().createElement("b",null,s)," HTTP authentication: unsupported scheme ","'".concat(m,"'")))}}]),n}(C().Component))},6467:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(3427),a=n(2458),o=n(5757),s=n(6617),l=n(9928),i=n(5327),c=n(6775),u=n(6796);const p={Callbacks:r.default,HttpAuth:c.default,RequestBody:a.default,Servers:s.default,ServersContainer:l.default,RequestBodyEditor:i.default,OperationServers:u.default,operationLink:o.default}},5757:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>y});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4291),i=n.n(l),c=n(1885),u=n.n(c),p=n(8344),d=n.n(p),m=n(3942),h=n.n(m),f=n(6689),g=n.n(f),v=(n(580),n(8082),function(e){i()(n,e);var t=u()(n);function n(){return a()(this,n),t.apply(this,arguments)}return s()(n,[{key:"render",value:function(){var e=this.props,t=e.link,n=e.name,r=(0,e.getComponent)("Markdown",!0),a=t.get("operationId")||t.get("operationRef"),o=t.get("parameters")&&t.get("parameters").toJS(),s=t.get("description");return g().createElement("div",{className:"operation-link"},g().createElement("div",{className:"description"},g().createElement("b",null,g().createElement("code",null,n)),s?g().createElement(r,{source:s}):null),g().createElement("pre",null,"Operation `",a,"`",g().createElement("br",null),g().createElement("br",null),"Parameters ",function(e,t){var n;if("string"!=typeof t)return"";return h()(n=t.split("\n")).call(n,(function(t,n){return n>0?Array(e+1).join(" ")+t:t})).join("\n")}(0,d()(o,null,2))||"{}",g().createElement("br",null)))}}]),n}(f.Component));const y=v},6796:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>b});var r=n(67),a=n.n(r),o=n(6349),s=n.n(o),l=n(4606),i=n.n(l),c=n(4555),u=n.n(c),p=n(4291),d=n.n(p),m=n(1885),h=n.n(m),f=n(1093),g=n.n(f),v=n(4883),y=n.n(v),E=n(6689),S=n.n(E),b=(n(580),n(8082),function(e){d()(n,e);var t=h()(n);function n(){var e,r;s()(this,n);for(var o=arguments.length,l=new Array(o),i=0;i{"use strict";n.r(t),n.d(t,{default:()=>b});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4555),i=n.n(l),c=n(4291),u=n.n(c),p=n(1885),d=n.n(p),m=n(1093),h=n.n(m),f=n(6689),g=n.n(f),v=(n(580),n(9003)),y=n.n(v),E=n(1890),S=Function.prototype,b=function(e){u()(n,e);var t=d()(n);function n(e,r){var o;return a()(this,n),o=t.call(this,e,r),h()(i()(o),"applyDefaultValue",(function(e){var t=e||o.props,n=t.onChange,r=t.defaultValue;return o.setState({value:r}),n(r)})),h()(i()(o),"onChange",(function(e){o.props.onChange((0,E.Pz)(e))})),h()(i()(o),"onDomChange",(function(e){var t=e.target.value;o.setState({value:t},(function(){return o.onChange(t)}))})),o.state={value:(0,E.Pz)(e.value)||e.defaultValue},e.onChange(e.value),o}return s()(n,[{key:"UNSAFE_componentWillReceiveProps",value:function(e){this.props.value!==e.value&&e.value!==this.state.value&&this.setState({value:(0,E.Pz)(e.value)}),!e.value&&e.defaultValue&&this.state.value&&this.applyDefaultValue(e)}},{key:"render",value:function(){var e=this.props,t=e.getComponent,n=e.errors,r=this.state.value,a=n.size>0,o=t("TextArea");return g().createElement("div",{className:"body-param"},g().createElement(o,{className:y()("body-param__text",{invalid:a}),title:n.size?n.join(", "):"",value:r,onChange:this.onDomChange}))}}]),n}(f.PureComponent);h()(b,"defaultProps",{onChange:S,userHasEditedBody:!1})},2458:(e,t,n)=>{"use strict";n.r(t),n.d(t,{getDefaultRequestBodyValue:()=>S,default:()=>b});var r=n(8030),a=n.n(r),o=n(3942),s=n.n(o),l=n(8493),i=n.n(l),c=n(2605),u=n.n(c),p=n(4883),d=n.n(p),m=n(7104),h=n.n(m),f=n(6689),g=n.n(f),v=(n(580),n(8082),n(5572)),y=n(1890),E=n(2518),S=function(e,t,n){var r=e.getIn(["content",t]),a=r.get("schema").toJS(),o=void 0!==r.get("examples"),s=r.get("example"),l=o?r.getIn(["examples",n,"value"]):s,i=(0,y.xi)(a,t,{includeWriteOnly:!0},l);return(0,y.Pz)(i)};const b=function(e){var t=e.userHasEditedBody,n=e.requestBody,r=e.requestBodyValue,o=e.requestBodyInclusionSetting,l=e.requestBodyErrors,c=e.getComponent,p=e.getConfigs,m=e.specSelectors,f=e.fn,b=e.contentType,C=e.isExecute,x=e.specPath,w=e.onChange,_=e.onChangeIncludeEmpty,A=e.activeExamplesKey,k=e.updateActiveExamplesKey,N=e.setRetainRequestBodyValueFlag,I=function(e){var t={key:e,shouldDispatchInit:!1,defaultValue:!0};return"no value"===o.get(e,"no value")&&(t.shouldDispatchInit=!0),t},q=c("Markdown",!0),R=c("modelExample"),P=c("RequestBodyEditor"),T=c("highlightCode"),O=c("ExamplesSelectValueRetainer"),M=c("Example"),j=c("ParameterIncludeEmpty"),V=p().showCommonExtensions,D=n&&n.get("description")||null,L=n&&n.get("content")||new v.OrderedMap;b=b||L.keySeq().first()||"";var U=L.get(b,(0,v.OrderedMap)()),z=U.get("schema",(0,v.OrderedMap)()),B=U.get("examples",null),J=null==B?void 0:s()(B).call(B,(function(e,t){var r,a=null===(r=e)||void 0===r?void 0:r.get("value",null);return a&&(e=e.set("value",S(n,b,t),a)),e}));if(l=v.List.isList(l)?l:(0,v.List)(),!U.size)return null;var F="object"===U.getIn(["schema","type"]),W="binary"===U.getIn(["schema","format"]),H="base64"===U.getIn(["schema","format"]);if("application/octet-stream"===b||0===i()(b).call(b,"image/")||0===i()(b).call(b,"audio/")||0===i()(b).call(b,"video/")||W||H){var K=c("Input");return C?g().createElement(K,{type:"file",onChange:function(e){w(e.target.files[0])}}):g().createElement("i",null,"Example values are not available for ",g().createElement("code",null,b)," media types.")}if(F&&("application/x-www-form-urlencoded"===b||0===i()(b).call(b,"multipart/"))&&z.get("properties",(0,v.OrderedMap)()).size>0){var Z,G=c("JsonSchemaForm"),Y=c("ParameterExt"),X=z.get("properties",(0,v.OrderedMap)());return r=v.Map.isMap(r)?r:(0,v.OrderedMap)(),g().createElement("div",{className:"table-container"},D&&g().createElement(q,{source:D}),g().createElement("table",null,g().createElement("tbody",null,v.Map.isMap(X)&&s()(Z=X.entrySeq()).call(Z,(function(e){var t,n,i=a()(e,2),p=i[0],m=i[1];if(!m.get("readOnly")){var E=V?(0,y.po)(m):null,S=u()(t=z.get("required",(0,v.List)())).call(t,p),b=m.get("type"),x=m.get("format"),A=m.get("description"),k=r.getIn([p,"value"]),N=r.getIn([p,"errors"])||l,R=o.get(p)||!1,P=m.has("default")||m.has("example")||m.hasIn(["items","example"])||m.hasIn(["items","default"]),T=m.has("enum")&&(1===m.get("enum").size||S),O=P||T,M="";"array"!==b||O||(M=[]),("object"===b||O)&&(M=(0,y.xi)(m,!1,{includeWriteOnly:!0})),"string"!=typeof M&&"object"===b&&(M=(0,y.Pz)(M)),"string"==typeof M&&"array"===b&&(M=JSON.parse(M));var D="string"===b&&("binary"===x||"base64"===x);return g().createElement("tr",{key:p,className:"parameters","data-property-name":p},g().createElement("td",{className:"parameters-col_name"},g().createElement("div",{className:S?"parameter__name required":"parameter__name"},p,S?g().createElement("span",null," *"):null),g().createElement("div",{className:"parameter__type"},b,x&&g().createElement("span",{className:"prop-format"},"($",x,")"),V&&E.size?s()(n=E.entrySeq()).call(n,(function(e){var t,n=a()(e,2),r=n[0],o=n[1];return g().createElement(Y,{key:d()(t="".concat(r,"-")).call(t,o),xKey:r,xVal:o})})):null),g().createElement("div",{className:"parameter__deprecated"},m.get("deprecated")?"deprecated":null)),g().createElement("td",{className:"parameters-col_description"},g().createElement(q,{source:A}),C?g().createElement("div",null,g().createElement(G,{fn:f,dispatchInitialValue:!D,schema:m,description:p,getComponent:c,value:void 0===k?M:k,required:S,errors:N,onChange:function(e){w(e,[p])}}),S?null:g().createElement(j,{onChange:function(e){return _(p,e)},isIncluded:R,isIncludedOptions:I(p),isDisabled:h()(k)?0!==k.length:!(0,y.O2)(k)})):null))}})))))}var Q=S(n,b,A),$=null;return(0,E.O)(Q)&&($="json"),g().createElement("div",null,D&&g().createElement(q,{source:D}),J?g().createElement(O,{userHasEditedBody:t,examples:J,currentKey:A,currentUserInputValue:r,onSelect:function(e){k(e)},updateValue:w,defaultToFirstExample:!0,getComponent:c,setRetainRequestBodyValueFlag:N}):null,C?g().createElement("div",null,g().createElement(P,{value:r,errors:l,defaultValue:Q,onChange:w,getComponent:c})):g().createElement(R,{getComponent:c,getConfigs:p,specSelectors:m,expandDepth:1,isExecute:C,schema:U.get("schema"),specPath:x.push("content",b),example:g().createElement(T,{className:"body-param__example",getConfigs:p,language:$,value:(0,y.Pz)(r)||Q}),includeWriteOnly:!0}),J?g().createElement(M,{example:J.get(A),getComponent:c,getConfigs:p}):null)}},9928:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>m});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4291),i=n.n(l),c=n(1885),u=n.n(c),p=n(6689),d=n.n(p),m=(n(580),function(e){i()(n,e);var t=u()(n);function n(){return a()(this,n),t.apply(this,arguments)}return s()(n,[{key:"render",value:function(){var e=this.props,t=e.specSelectors,n=e.oas3Selectors,r=e.oas3Actions,a=e.getComponent,o=t.servers(),s=a("Servers");return o&&o.size?d().createElement("div",null,d().createElement("span",{className:"servers-title"},"Servers"),d().createElement(s,{servers:o,currentServer:n.selectedServer(),setSelectedServer:r.setSelectedServer,setServerVariableValue:r.setServerVariableValue,getServerVariable:n.serverVariableValue,getEffectiveServerValue:n.serverEffectiveValue})):null}}]),n}(d().Component))},6617:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>A});var r=n(8030),a=n.n(r),o=n(6349),s=n.n(o),l=n(4606),i=n.n(l),c=n(4555),u=n.n(c),p=n(4291),d=n.n(p),m=n(1885),h=n.n(m),f=n(1093),g=n.n(f),v=n(4883),y=n.n(v),E=n(3580),S=n.n(E),b=n(3942),C=n.n(b),x=n(6689),w=n.n(x),_=n(5572),A=(n(580),n(8082),function(e){d()(n,e);var t=h()(n);function n(){var e,r;s()(this,n);for(var a=arguments.length,o=new Array(a),l=0;l{"use strict";n.r(t),n.d(t,{isOAS3:()=>c,isSwagger2:()=>u,OAS3ComponentWrapFactory:()=>p});var r=n(4250),a=n.n(r),o=n(3262),s=n.n(o),l=n(6689),i=n.n(l);function c(e){var t=e.get("openapi");return"string"==typeof t&&(s()(t).call(t,"3.0.")&&t.length>4)}function u(e){var t=e.get("swagger");return"string"==typeof t&&s()(t).call(t,"2.0")}function p(e){return function(t,n){return function(r){return n&&n.specSelectors&&n.specSelectors.specJson?c(n.specSelectors.specJson())?i().createElement(e,a()({},r,n,{Ori:t})):i().createElement(t,r):(console.warn("OAS3 wrapper: couldn't get spec"),null)}}}},7451:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(2044),a=n(3723),o=n(1741),s=n(6467),l=n(7761),i=n(7002),c=n(5065),u=n(5013);function p(){return{components:s.default,wrapComponents:l.default,statePlugins:{spec:{wrapSelectors:r,selectors:o},auth:{wrapSelectors:a},oas3:{actions:i,reducers:u.default,selectors:c}}}}},5013:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>S});var r=n(1093),a=n.n(r);const o=require("@babel/runtime-corejs3/helpers/toArray");var s,l=n.n(o),i=n(8030),c=n.n(i),u=n(874),p=n.n(u),d=n(600),m=n.n(d),h=n(4235),f=n.n(h),g=n(66),v=n.n(g),y=n(5572),E=n(7002);const S=(s={},a()(s,E.UPDATE_SELECTED_SERVER,(function(e,t){var n=t.payload,r=n.selectedServerUrl,a=n.namespace,o=a?[a,"selectedServer"]:["selectedServer"];return e.setIn(o,r)})),a()(s,E.UPDATE_REQUEST_BODY_VALUE,(function(e,t){var n=t.payload,r=n.value,a=n.pathMethod,o=c()(a,2),s=o[0],i=o[1];if(!y.Map.isMap(r))return e.setIn(["requestData",s,i,"bodyValue"],r);var u,d=e.getIn(["requestData",s,i,"bodyValue"])||(0,y.Map)();y.Map.isMap(d)||(d=(0,y.Map)());var h=p()(r).call(r),g=l()(h),v=m()(g).call(g,0);return f()(v).call(v,(function(e){var t=r.getIn([e]);d.has(e)&&y.Map.isMap(t)||(u=d.setIn([e,"value"],t))})),e.setIn(["requestData",s,i,"bodyValue"],u)})),a()(s,E.UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG,(function(e,t){var n=t.payload,r=n.value,a=n.pathMethod,o=c()(a,2),s=o[0],l=o[1];return e.setIn(["requestData",s,l,"retainBodyValue"],r)})),a()(s,E.UPDATE_REQUEST_BODY_INCLUSION,(function(e,t){var n=t.payload,r=n.value,a=n.pathMethod,o=n.name,s=c()(a,2),l=s[0],i=s[1];return e.setIn(["requestData",l,i,"bodyInclusion",o],r)})),a()(s,E.UPDATE_ACTIVE_EXAMPLES_MEMBER,(function(e,t){var n=t.payload,r=n.name,a=n.pathMethod,o=n.contextType,s=n.contextName,l=c()(a,2),i=l[0],u=l[1];return e.setIn(["examples",i,u,o,s,"activeExample"],r)})),a()(s,E.UPDATE_REQUEST_CONTENT_TYPE,(function(e,t){var n=t.payload,r=n.value,a=n.pathMethod,o=c()(a,2),s=o[0],l=o[1];return e.setIn(["requestData",s,l,"requestContentType"],r)})),a()(s,E.UPDATE_RESPONSE_CONTENT_TYPE,(function(e,t){var n=t.payload,r=n.value,a=n.path,o=n.method;return e.setIn(["requestData",a,o,"responseContentType"],r)})),a()(s,E.UPDATE_SERVER_VARIABLE_VALUE,(function(e,t){var n=t.payload,r=n.server,a=n.namespace,o=n.key,s=n.val,l=a?[a,"serverVariableValues",r,o]:["serverVariableValues",r,o];return e.setIn(l,s)})),a()(s,E.SET_REQUEST_BODY_VALIDATE_ERROR,(function(e,t){var n=t.payload,r=n.path,a=n.method,o=n.validationErrors,s=[];if(s.push("Required field is not provided"),o.missingBodyValue)return e.setIn(["requestData",r,a,"errors"],(0,y.fromJS)(s));if(o.missingRequiredKeys&&o.missingRequiredKeys.length>0){var l=o.missingRequiredKeys;return e.updateIn(["requestData",r,a,"bodyValue"],(0,y.fromJS)({}),(function(e){return v()(l).call(l,(function(e,t){return e.setIn([t,"errors"],(0,y.fromJS)(s))}),e)}))}return console.warn("unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR"),e})),a()(s,E.CLEAR_REQUEST_BODY_VALIDATE_ERROR,(function(e,t){var n=t.payload,r=n.path,a=n.method,o=e.getIn(["requestData",r,a,"bodyValue"]);if(!y.Map.isMap(o))return e.setIn(["requestData",r,a,"errors"],(0,y.fromJS)([]));var s=p()(o).call(o),i=l()(s),c=m()(i).call(i,0);return c?e.updateIn(["requestData",r,a,"bodyValue"],(0,y.fromJS)({}),(function(e){return v()(c).call(c,(function(e,t){return e.setIn([t,"errors"],(0,y.fromJS)([]))}),e)})):e})),a()(s,E.CLEAR_REQUEST_BODY_VALUE,(function(e,t){var n=t.payload.pathMethod,r=c()(n,2),a=r[0],o=r[1],s=e.getIn(["requestData",a,o,"bodyValue"]);return s?y.Map.isMap(s)?e.setIn(["requestData",a,o,"bodyValue"],(0,y.Map)()):e.setIn(["requestData",a,o,"bodyValue"],""):e})),s)},5065:(e,t,n)=>{"use strict";n.r(t),n.d(t,{selectedServer:()=>b,requestBodyValue:()=>C,shouldRetainRequestBodyValue:()=>x,hasUserEditedBody:()=>w,requestBodyInclusionSetting:()=>_,requestBodyErrors:()=>A,activeExamplesMember:()=>k,requestContentType:()=>N,responseContentType:()=>I,serverVariableValue:()=>q,serverVariables:()=>R,serverEffectiveValue:()=>P,validateBeforeExecute:()=>T,validateShallowRequired:()=>O});var r=n(6731),a=n.n(r),o=n(4883),s=n.n(o),l=n(3942),i=n.n(l),c=n(4235),u=n.n(c),p=n(7252),d=n.n(p),m=n(8493),h=n.n(m),f=n(5572),g=n(7779),v=n(2458),y=n(1890);function E(e){return function(){for(var t=arguments.length,n=new Array(t),r=0;r{"use strict";n.r(t),n.d(t,{servers:()=>u,isSwagger2:()=>p});var r=n(6814),a=n(5572),o=n(7779);var s,l=function(e){return e||(0,a.Map)()},i=(0,r.createSelector)(l,(function(e){return e.get("json",(0,a.Map)())})),c=(0,r.createSelector)(l,(function(e){return e.get("resolved",(0,a.Map)())})),u=(s=(0,r.createSelector)((function(e){var t=c(e);return t.count()<1&&(t=i(e)),t}),(function(e){return e.getIn(["servers"])||(0,a.Map)()})),function(){return function(e){var t=e.getSystem().specSelectors.specJson();if((0,o.isOAS3)(t)){for(var n=arguments.length,r=new Array(n>1?n-1:0),a=1;a{"use strict";n.r(t),n.d(t,{definitions:()=>m,hasHost:()=>h,securityDefinitions:()=>f,host:()=>g,basePath:()=>v,consumes:()=>y,produces:()=>E,schemes:()=>S,servers:()=>b,isOAS3:()=>C,isSwagger2:()=>x});var r=n(6814),a=n(3881),o=n(5572),s=n(7779);function l(e){return function(t,n){return function(){var r=n.getSystem().specSelectors.specJson();return(0,s.isOAS3)(r)?e.apply(void 0,arguments):t.apply(void 0,arguments)}}}var i=function(e){return e||(0,o.Map)()},c=l((0,r.createSelector)((function(){return null}))),u=(0,r.createSelector)(i,(function(e){return e.get("json",(0,o.Map)())})),p=(0,r.createSelector)(i,(function(e){return e.get("resolved",(0,o.Map)())})),d=function(e){var t=p(e);return t.count()<1&&(t=u(e)),t},m=l((0,r.createSelector)(d,(function(e){var t=e.getIn(["components","schemas"]);return o.Map.isMap(t)?t:(0,o.Map)()}))),h=l((function(e){return d(e).hasIn(["servers",0])})),f=l((0,r.createSelector)(a.specJsonWithResolvedSubtrees,(function(e){return e.getIn(["components","securitySchemes"])||null}))),g=c,v=c,y=c,E=c,S=c,b=l((0,r.createSelector)(d,(function(e){return e.getIn(["servers"])||(0,o.Map)()}))),C=function(e,t){return function(){var e=t.getSystem().specSelectors.specJson();return(0,s.isOAS3)(o.Map.isMap(e)?e:(0,o.Map)())}},x=function(e,t){return function(){var e=t.getSystem().specSelectors.specJson();return(0,s.isSwagger2)(o.Map.isMap(e)?e:(0,o.Map)())}}},356:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(5579),a=n.n(r),o=n(6689),s=n.n(o),l=n(7779),i=["Ori"];const c=(0,l.OAS3ComponentWrapFactory)((function(e){var t=e.Ori,n=a()(e,i),r=n.schema,o=n.getComponent,l=n.errSelectors,c=n.authorized,u=n.onAuthChange,p=n.name,d=o("HttpAuth");return"http"===r.get("type")?s().createElement(d,{key:p,schema:r,name:p,errSelectors:l,authorized:c,getComponent:o,onChange:u}):s().createElement(t,n)}))},7761:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(2460),a=n(356),o=n(9487),s=n(58),l=n(3499),i=n(287);const c={Markdown:r.default,AuthItem:a.default,JsonSchema_string:i.default,VersionStamp:o.default,model:l.default,onlineValidatorBadge:s.default}},287:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(5579),a=n.n(r),o=n(6689),s=n.n(o),l=n(7779),i=["Ori"];const c=(0,l.OAS3ComponentWrapFactory)((function(e){var t=e.Ori,n=a()(e,i),r=n.schema,o=n.getComponent,l=n.errors,c=n.onChange,u=r&&r.get?r.get("format"):null,p=r&&r.get?r.get("type"):null,d=o("Input");return p&&"string"===p&&u&&("binary"===u||"base64"===u)?s().createElement(d,{type:"file",className:l.length?"invalid":"",title:l.length?l:"",onChange:function(e){c(e.target.files[0])},disabled:t.isDisabled}):s().createElement(t,n)}))},2460:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Markdown:()=>m,default:()=>h});var r=n(7390),a=n.n(r),o=n(6689),s=n.n(o),l=(n(580),n(9003)),i=n.n(l),c=n(963),u=n(7779),p=n(2552),d=new c.Remarkable("commonmark");d.block.ruler.enable(["table"]),d.set({linkTarget:"_blank"});var m=function(e){var t=e.source,n=e.className,r=void 0===n?"":n,o=e.getConfigs;if("string"!=typeof t)return null;if(t){var l,c=o().useUnsafeMarkdown,u=d.render(t),m=(0,p.s)(u,{useUnsafeMarkdown:c});return"string"==typeof m&&(l=a()(m).call(m)),s().createElement("div",{dangerouslySetInnerHTML:{__html:l},className:i()(r,"renderedMarkdown")})}return null};m.defaultProps={getConfigs:function(){return{useUnsafeMarkdown:!1}}};const h=(0,u.OAS3ComponentWrapFactory)(m)},3499:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>y});var r=n(4250),a=n.n(r),o=n(6349),s=n.n(o),l=n(4606),i=n.n(l),c=n(4291),u=n.n(c),p=n(1885),d=n.n(p),m=n(6689),h=n.n(m),f=(n(580),n(7779)),g=n(6024),v=function(e){u()(n,e);var t=d()(n);function n(){return s()(this,n),t.apply(this,arguments)}return i()(n,[{key:"render",value:function(){var e=this.props,t=e.getConfigs,n=["model-box"],r=null;return!0===e.schema.get("deprecated")&&(n.push("deprecated"),r=h().createElement("span",{className:"model-deprecated-warning"},"Deprecated:")),h().createElement("div",{className:n.join(" ")},r,h().createElement(g.Z,a()({},this.props,{getConfigs:t,depth:1,expandDepth:this.props.expandDepth||0})))}}]),n}(m.Component);const y=(0,f.OAS3ComponentWrapFactory)(v)},58:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(7779),a=n(5623);const o=(0,r.OAS3ComponentWrapFactory)(a.Z)},9487:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(6689),a=n.n(r);const o=(0,n(7779).OAS3ComponentWrapFactory)((function(e){var t=e.Ori;return a().createElement("span",null,a().createElement(t,e),a().createElement("small",{className:"version-stamp"},a().createElement("pre",{className:"version"},"OAS3")))}))},8560:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(9300),a=n.n(r),o=!1;function s(){return{statePlugins:{spec:{wrapActions:{updateSpec:function(e){return function(){return o=!0,e.apply(void 0,arguments)}},updateJsonSpec:function(e,t){return function(){var n=t.getConfigs().onComplete;return o&&"function"==typeof n&&(a()(n,0),o=!1),e.apply(void 0,arguments)}}}}}}}},8223:(e,t,n)=>{"use strict";n.r(t),n.d(t,{requestSnippetGenerator_curl_bash:()=>O,requestSnippetGenerator_curl_cmd:()=>M,requestSnippetGenerator_curl_powershell:()=>T});var r=n(6731),a=n.n(r),o=n(8030),s=n.n(o),l=n(1771),i=n.n(l),c=n(8493),u=n.n(c),p=n(7390),d=n.n(p),m=n(4883),h=n.n(m),f=n(8344),g=n.n(f),v=n(3942),y=n.n(v);const E=require("@babel/runtime-corejs3/core-js-stable/instance/repeat");var S=n.n(E),b=n(7862),C=n.n(b),x=n(2605),w=n.n(x),_=n(7504),A=n(5572),k=function(e){var t,n="_**[]";return u()(e).call(e,n)<0?e:d()(t=e.split(n)[0]).call(t)},N=function(e){return"-d "===e||/^[_\/-]/g.test(e)?e:"'"+e.replace(/'/g,"'\\''")+"'"},I=function(e){return"-d "===(e=e.replace(/\^/g,"^^").replace(/\\"/g,'\\\\"').replace(/"/g,'""').replace(/\n/g,"^\n"))?e.replace(/-d /g,"-d ^\n"):/^[_\/-]/g.test(e)?e:'"'+e+'"'},q=function(e){return"-d "===e?e:/\n/.test(e)?'@"\n'+e.replace(/"/g,'\\"').replace(/`/g,"``").replace(/\$/,"`$")+'\n"@':/^[_\/-]/g.test(e)?e:"'"+e.replace(/"/g,'""').replace(/'/g,"''")+"'"};function R(e){var t,n=[],r=i()(e.get("body").entrySeq());try{for(r.s();!(t=r.n()).done;){var a,o,l,c=s()(t.value,2),u=c[0],p=c[1],d=k(u);if(p instanceof _.Z.File)n.push(h()(a=h()(o=' "'.concat(d,'": {\n "name": "')).call(o,p.name,'"')).call(a,p.type?',\n "type": "'.concat(p.type,'"'):"","\n }"));else n.push(h()(l=' "'.concat(d,'": ')).call(l,g()(p,null,2).replace(/(\r\n|\r|\n)/g,"\n ")))}}catch(e){r.e(e)}finally{r.f()}return"{\n".concat(n.join(",\n"),"\n}")}var P=function(e,t,n){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=!1,l="",c=function(){for(var e=arguments.length,n=new Array(e),r=0;r0&&void 0!==arguments[0]?arguments[0]:1;return l+=S()(e=" ").call(e,t)},m=e.get("headers");if(l+="curl"+r,e.has("curlOptions")&&c.apply(void 0,a()(e.get("curlOptions"))),c("-X",e.get("method")),p(),d(),u("".concat(e.get("url"))),m&&m.size){var f,v,E=i()(C()(f=e.get("headers")).call(f));try{for(E.s();!(v=E.n()).done;){var b,x=v.value;p(),d();var N=s()(x,2),I=N[0],q=N[1];u("-H",h()(b="".concat(I,": ")).call(b,q)),o=o||/^content-type$/i.test(I)&&/^multipart\/form-data$/i.test(q)}}catch(e){E.e(e)}finally{E.f()}}var P,T=e.get("body");if(T)if(o&&w()(P=["POST","PUT","PATCH"]).call(P,e.get("method"))){var O,M=i()(T.entrySeq());try{for(M.s();!(O=M.n()).done;){var j,V,D,L=s()(O.value,2),U=L[0],z=L[1],B=k(U);if(p(),d(),u("-F"),z instanceof _.Z.File)c(h()(j=h()(V="".concat(B,"=@")).call(V,z.name)).call(j,z.type?";type=".concat(z.type):""));else c(h()(D="".concat(B,"=")).call(D,z))}}catch(e){M.e(e)}finally{M.f()}}else if(T instanceof _.Z.File)p(),d(),u("--data-binary '@".concat(T.name,"'"));else{p(),d(),u("-d ");var J=T;A.Map.isMap(J)?u(R(e)):("string"!=typeof J&&(J=g()(J)),u(J))}else T||"POST"!==e.get("method")||(p(),d(),u("-d ''"));return l},T=function(e){return P(e,q,"`\n",".exe")},O=function(e){return P(e,N,"\\\n")},M=function(e){return P(e,I,"^\n")}},6575:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(8223),a=n(4669),o=n(4206);const s=function(){return{components:{RequestSnippets:o.default},fn:r,statePlugins:{requestSnippets:{selectors:a}}}}},4206:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>x});var r=n(8030),a=n.n(r),o=n(9998),s=n.n(o),l=n(1733),i=n.n(l),c=n(4235),u=n.n(c),p=n(3942),d=n.n(p),m=n(6689),h=n.n(m),f=(n(580),n(1712)),g=n.n(f),v=n(5716),y=n.n(v),E=n(2807),S=n(6068),b={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(250, 250, 250)",paddingBottom:"0",paddingTop:"0",border:"1px solid rgb(51, 51, 51)",borderRadius:"4px 4px 0 0",boxShadow:"none",borderBottom:"none"},C={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(51, 51, 51)",boxShadow:"none",border:"1px solid rgb(51, 51, 51)",paddingBottom:"0",paddingTop:"0",borderRadius:"4px 4px 0 0",marginTop:"-5px",marginRight:"-5px",marginLeft:"-5px",zIndex:"9999",borderBottom:"none"};const x=function(e){var t,n,r=e.request,o=e.requestSnippetsSelectors,l=e.getConfigs,c=y()(l)?l():null,p=!1!==g()(c,"syntaxHighlight")&&g()(c,"syntaxHighlight.activated",!0),f=(0,m.useRef)(null),v=(0,m.useState)(null===(t=o.getSnippetGenerators())||void 0===t?void 0:t.keySeq().first()),x=a()(v,2),w=x[0],_=x[1],A=(0,m.useState)(null==o?void 0:o.getDefaultExpanded()),k=a()(A,2),N=k[0],I=k[1];(0,m.useEffect)((function(){}),[]),(0,m.useEffect)((function(){var e,t=s()(e=i()(f.current.childNodes)).call(e,(function(e){var t;return!!e.nodeType&&(null===(t=e.classList)||void 0===t?void 0:t.contains("curl-command"))}));return u()(t).call(t,(function(e){return e.addEventListener("mousewheel",M,{passive:!1})})),function(){u()(t).call(t,(function(e){return e.removeEventListener("mousewheel",M)}))}}),[r]);var q=o.getSnippetGenerators(),R=q.get(w),P=R.get("fn")(r),T=function(){I(!N)},O=function(e){return e===w?C:b},M=function(e){var t=e.target,n=e.deltaY,r=t.scrollHeight,a=t.offsetHeight,o=t.scrollTop;r>a&&(0===o&&n<0||a+o>=r&&n>0)&&e.preventDefault()},j=p?h().createElement(S.d3,{language:R.get("syntax"),className:"curl microlight",style:(0,S.C2)(g()(c,"syntaxHighlight.theme"))},P):h().createElement("textarea",{readOnly:!0,className:"curl",value:P});return h().createElement("div",{className:"request-snippets",ref:f},h().createElement("div",{style:{width:"100%",display:"flex",justifyContent:"flex-start",alignItems:"center",marginBottom:"15px"}},h().createElement("h4",{onClick:function(){return T()},style:{cursor:"pointer"}},"Snippets"),h().createElement("button",{onClick:function(){return T()},style:{border:"none",background:"none"},title:N?"Collapse operation":"Expand operation"},h().createElement("svg",{className:"arrow",width:"10",height:"10"},h().createElement("use",{href:N?"#large-arrow-down":"#large-arrow",xlinkHref:N?"#large-arrow-down":"#large-arrow"})))),N&&h().createElement("div",{className:"curl-command"},h().createElement("div",{style:{paddingLeft:"15px",paddingRight:"10px",width:"100%",display:"flex"}},d()(n=q.entrySeq()).call(n,(function(e){var t=a()(e,2),n=t[0],r=t[1];return h().createElement("div",{style:O(n),className:"btn",key:n,onClick:function(){return function(e){w!==e&&_(e)}(n)}},h().createElement("h4",{style:n===w?{color:"white"}:{}},r.get("title")))}))),h().createElement("div",{className:"copy-to-clipboard"},h().createElement(E.CopyToClipboard,{text:P},h().createElement("button",null))),h().createElement("div",null,j)))}},4669:(e,t,n)=>{"use strict";n.r(t),n.d(t,{getGenerators:()=>d,getSnippetGenerators:()=>m,getActiveLanguage:()=>h,getDefaultExpanded:()=>f});var r=n(9998),a=n.n(r),o=n(2605),s=n.n(o),l=n(3942),i=n.n(l),c=n(6814),u=n(5572),p=function(e){return e||(0,u.Map)()},d=(0,c.createSelector)(p,(function(e){var t=e.get("languages"),n=e.get("generators",(0,u.Map)());return!t||t.isEmpty()?n:a()(n).call(n,(function(e,n){return s()(t).call(t,n)}))})),m=function(e){return function(t){var n,r,o=t.fn;return a()(n=i()(r=d(e)).call(r,(function(e,t){var n=function(e){return o["requestSnippetGenerator_".concat(e)]}(t);return"function"!=typeof n?null:e.set("fn",n)}))).call(n,(function(e){return e}))}},h=(0,c.createSelector)(p,(function(e){return e.get("activeLanguage")})),f=(0,c.createSelector)(p,(function(e){return e.get("defaultExpanded")}))},6195:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ErrorBoundary:()=>v,default:()=>y});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o),l=n(4291),i=n.n(l),c=n(1885),u=n.n(c),p=n(4883),d=n.n(p),m=(n(580),n(6689)),h=n.n(m),f=n(6189),g=n(9403),v=function(e){i()(n,e);var t=u()(n);function n(){var e,r;a()(this,n);for(var o=arguments.length,s=new Array(o),l=0;l{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(6689),a=n.n(r);n(580);const o=function(e){var t=e.name;return a().createElement("div",{className:"fallback"},"😱 ",a().createElement("i",null,"Could not render ","t"===t?"this component":t,", see the console."))}},6189:(e,t,n)=>{"use strict";n.r(t),n.d(t,{componentDidCatch:()=>f,withErrorBoundary:()=>g});var r=n(4250),a=n.n(r),o=n(6349),s=n.n(o),l=n(4606),i=n.n(l),c=n(4291),u=n.n(c),p=n(1885),d=n.n(p),m=n(6689),h=n.n(m),f=console.error,g=function(e){return function(t){var n,r=e(),o=r.getComponent,l=r.fn,c=o("ErrorBoundary"),p=l.getDisplayName(t),f=function(e){u()(r,e);var n=d()(r);function r(){return s()(this,r),n.apply(this,arguments)}return i()(r,[{key:"render",value:function(){return h().createElement(c,{targetName:p,getComponent:o,fn:l},h().createElement(t,a()({},this.props,this.context)))}}]),r}(m.Component);return f.displayName="WithErrorBoundary(".concat(p,")"),(n=t).prototype&&n.prototype.isReactComponent&&(f.prototype.mapStateToProps=t.prototype.mapStateToProps),f}}},9595:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>h});var r=n(6731),a=n.n(r),o=n(4883),s=n.n(o);const l=require("@babel/runtime-corejs3/core-js-stable/instance/fill");var i=n.n(l);const c=require("lodash/zipObject");var u=n.n(c),p=n(6195),d=n(9403),m=n(6189);const h=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.componentList,n=void 0===t?[]:t,r=e.fullOverride,o=void 0!==r&&r;return function(e){var t,r,l=e.getSystem,c=o?n:s()(t=[]).call(t,["App","BaseLayout","VersionPragmaFilter","InfoContainer","ServersContainer","SchemesContainer","AuthorizeBtnContainer","FilterContainer","Operations","OperationContainer","parameters","responses","OperationServers","Models","ModelWrapper"],a()(n)),h=u()(c,i()(r=Array(c.length)).call(r,(function(e,t){return t.fn.withErrorBoundary(e)})));return{fn:{componentDidCatch:m.componentDidCatch,withErrorBoundary:(0,m.withErrorBoundary)(l)},components:{ErrorBoundary:p.default,Fallback:d.default},wrapComponents:h}}}},4128:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createXMLExample:()=>J,inferSchema:()=>B,memoizedCreateXMLExample:()=>H,memoizedSampleFromSchema:()=>K,sampleFromSchema:()=>F,sampleFromSchemaGeneric:()=>z});var r=n(6768),a=n.n(r),o=n(4883),s=n.n(o),l=n(8493),i=n.n(l),c=n(4235),u=n.n(c),p=n(7104),d=n.n(p),m=n(2605),h=n.n(m),f=n(5626),g=n.n(f),v=n(600),y=n.n(v),E=n(3580),S=n.n(E),b=n(3942),C=n.n(b),x=n(8344),w=n.n(x);const _=require("xml");var A=n.n(_);const k=require("randexp");var N=n.n(k);const I=require("lodash/isEmpty");var q=n.n(I),R=n(1890),P=n(7156),T={string:function(e){return e.pattern?function(e){try{return new(N())(e).gen()}catch(e){return"string"}}(e.pattern):"string"},string_email:function(){return"user@example.com"},"string_date-time":function(){return(new Date).toISOString()},string_date:function(){return(new Date).toISOString().substring(0,10)},string_uuid:function(){return"3fa85f64-5717-4562-b3fc-2c963f66afa6"},string_hostname:function(){return"example.com"},string_ipv4:function(){return"198.51.100.42"},string_ipv6:function(){return"2001:0db8:5b96:0000:0000:426f:8e17:642a"},number:function(){return 0},number_float:function(){return 0},integer:function(){return 0},boolean:function(e){return"boolean"!=typeof e.default||e.default}},O=function(e){var t,n=e=(0,R.mz)(e),r=n.type,a=n.format,o=T[s()(t="".concat(r,"_")).call(t,a)]||T[r];return(0,R.Wl)(o)?o(e):"Unknown Type: "+e.type},M=function(e){return(0,R.XV)(e,"$$ref",(function(e){return"string"==typeof e&&i()(e).call(e,"#")>-1}))},j=["maxProperties","minProperties"],V=["minItems","maxItems"],D=["minimum","maximum","exclusiveMinimum","exclusiveMaximum"],L=["minLength","maxLength"],U=function e(t,n){var r,a,o,l=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},c=function(e){void 0===n[e]&&void 0!==t[e]&&(n[e]=t[e])};(u()(r=s()(a=["example","default","enum","xml","type"]).call(a,j,V,D,L)).call(r,(function(e){return c(e)})),void 0!==t.required&&d()(t.required))&&(void 0!==n.required&&n.required.length||(n.required=[]),u()(o=t.required).call(o,(function(e){var t;h()(t=n.required).call(t,e)||n.required.push(e)})));if(t.properties){n.properties||(n.properties={});var p=(0,R.mz)(t.properties);for(var m in p){var f;if(Object.prototype.hasOwnProperty.call(p,m))if(!p[m]||!p[m].deprecated)if(!p[m]||!p[m].readOnly||l.includeReadOnly)if(!p[m]||!p[m].writeOnly||l.includeWriteOnly)if(!n.properties[m])n.properties[m]=p[m],!t.required&&d()(t.required)&&-1!==i()(f=t.required).call(f,m)&&(n.required?n.required.push(m):n.required=[m])}}return t.items&&(n.items||(n.items={}),n.items=e(t.items,n.items,l)),n},z=function e(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,o=arguments.length>3&&void 0!==arguments[3]&&arguments[3];t&&(0,R.Wl)(t.toJS)&&(t=t.toJS());var l=void 0!==r||t&&void 0!==t.example||t&&void 0!==t.default,c=!l&&t&&t.oneOf&&t.oneOf.length>0,p=!l&&t&&t.anyOf&&t.anyOf.length>0;if(!l&&(c||p)){var m=(0,R.mz)(c?t.oneOf[0]:t.anyOf[0]);if(U(m,t,n),!t.xml&&m.xml&&(t.xml=m.xml),void 0!==t.example&&void 0!==m.example)l=!0;else if(m.properties){t.properties||(t.properties={});var f=(0,R.mz)(m.properties);for(var v in f){var E;if(Object.prototype.hasOwnProperty.call(f,v))if(!f[v]||!f[v].deprecated)if(!f[v]||!f[v].readOnly||n.includeReadOnly)if(!f[v]||!f[v].writeOnly||n.includeWriteOnly)if(!t.properties[v])t.properties[v]=f[v],!m.required&&d()(m.required)&&-1!==i()(E=m.required).call(E,v)&&(t.required?t.required.push(v):t.required=[v])}}}var b,x={},w=t||{},_=w.xml,A=w.type,k=w.example,N=w.properties,I=w.additionalProperties,P=w.items,T=n.includeReadOnly,L=n.includeWriteOnly,z=_=_||{},B=z.name,J=z.prefix,F=z.namespace,W={};if(o&&(b=(J?J+":":"")+(B=B||"notagname"),F)){var H=J?"xmlns:"+J:"xmlns";x[H]=F}o&&(W[b]=[]);var K=function(e){return g()(e).call(e,(function(e){return Object.prototype.hasOwnProperty.call(t,e)}))};t&&!A&&(N||I||K(j)?A="object":P||K(V)?A="array":K(D)?(A="number",t.type="number"):l||t.enum||(A="string",t.type="string"));var Z,G,Y=function(e){var n,r,a,o,s;null!==(null===(n=t)||void 0===n?void 0:n.maxItems)&&void 0!==(null===(r=t)||void 0===r?void 0:r.maxItems)&&(e=y()(e).call(e,0,null===(s=t)||void 0===s?void 0:s.maxItems));if(null!==(null===(a=t)||void 0===a?void 0:a.minItems)&&void 0!==(null===(o=t)||void 0===o?void 0:o.minItems))for(var l=0;e.length<(null===(i=t)||void 0===i?void 0:i.minItems);){var i;e.push(e[l++%e.length])}return e},X=(0,R.mz)(N),Q=0,$=function(){return t&&null!==t.maxProperties&&void 0!==t.maxProperties&&Q>=t.maxProperties},ee=function(){if(!t||!t.required)return 0;var e,n,r=0;o?u()(e=t.required).call(e,(function(e){return r+=void 0===W[e]?0:1})):u()(n=t.required).call(n,(function(e){var t;return r+=void 0===(null===(t=W[b])||void 0===t?void 0:S()(t).call(t,(function(t){return void 0!==t[e]})))?0:1}));return t.required.length-r},te=function(e){var n;return!(t&&t.required&&t.required.length)||!h()(n=t.required).call(n,e)},ne=function(e){return!t||null===t.maxProperties||void 0===t.maxProperties||!$()&&(!te(e)||t.maxProperties-Q-ee()>0)};if(Z=o?function(r){var a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;if(t&&X[r]){if(X[r].xml=X[r].xml||{},X[r].xml.attribute){var l=d()(X[r].enum)?X[r].enum[0]:void 0,i=X[r].example,c=X[r].default;return void(x[X[r].xml.name||r]=void 0!==i?i:void 0!==c?c:void 0!==l?l:O(X[r]))}X[r].xml.name=X[r].xml.name||r}else X[r]||!1===I||(X[r]={xml:{name:r}});var u,p=e(t&&X[r]||void 0,n,a,o);ne(r)&&(Q++,d()(p)?W[b]=s()(u=W[b]).call(u,p):W[b].push(p))}:function(t,r){ne(t)&&(W[t]=e(X[t],n,r,o),Q++)},l){var re;if(re=M(void 0!==r?r:void 0!==k?k:t.default),!o){if("number"==typeof re&&"string"===A)return"".concat(re);if("string"!=typeof re||"string"===A)return re;try{return JSON.parse(re)}catch(e){return re}}if(t||(A=d()(re)?"array":a()(re)),"array"===A){if(!d()(re)){if("string"==typeof re)return re;re=[re]}var ae=t?t.items:void 0;ae&&(ae.xml=ae.xml||_||{},ae.xml.name=ae.xml.name||_.name);var oe=C()(re).call(re,(function(t){return e(ae,n,t,o)}));return oe=Y(oe),_.wrapped?(W[b]=oe,q()(x)||W[b].push({_attr:x})):W=oe,W}if("object"===A){if("string"==typeof re)return re;for(var se in re)Object.prototype.hasOwnProperty.call(re,se)&&(t&&X[se]&&X[se].readOnly&&!T||t&&X[se]&&X[se].writeOnly&&!L||(t&&X[se]&&X[se].xml&&X[se].xml.attribute?x[X[se].xml.name||se]=re[se]:Z(se,re[se])));return q()(x)||W[b].push({_attr:x}),W}return W[b]=q()(x)?re:[{_attr:x},re],W}if("object"===A){for(var le in X)Object.prototype.hasOwnProperty.call(X,le)&&(X[le]&&X[le].deprecated||X[le]&&X[le].readOnly&&!T||X[le]&&X[le].writeOnly&&!L||Z(le));if(o&&x&&W[b].push({_attr:x}),$())return W;if(!0===I)o?W[b].push({additionalProp:"Anything can be here"}):W.additionalProp1={},Q++;else if(I){var ie=(0,R.mz)(I),ce=e(ie,n,void 0,o);if(o&&ie.xml&&ie.xml.name&&"notagname"!==ie.xml.name)W[b].push(ce);else for(var ue=null!==t.minProperties&&void 0!==t.minProperties&&Q{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(4128);function a(){return{fn:r}}},7960:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CLEAR_REQUEST:()=>de,CLEAR_RESPONSE:()=>pe,CLEAR_VALIDATE_PARAMS:()=>me,LOG_REQUEST:()=>ue,SET_MUTATED_REQUEST:()=>ce,SET_REQUEST:()=>ie,SET_RESPONSE:()=>le,SET_SCHEME:()=>ve,UPDATE_EMPTY_PARAM_INCLUSION:()=>oe,UPDATE_JSON:()=>re,UPDATE_OPERATION_META_VALUE:()=>he,UPDATE_PARAM:()=>ae,UPDATE_RESOLVED:()=>fe,UPDATE_RESOLVED_SUBTREE:()=>ge,UPDATE_SPEC:()=>te,UPDATE_URL:()=>ne,VALIDATE_PARAMS:()=>se,changeConsumesValue:()=>Me,changeParam:()=>Ne,changeParamByIdentity:()=>Ie,changeProducesValue:()=>je,clearRequest:()=>Fe,clearResponse:()=>Je,clearValidateParams:()=>Oe,execute:()=>Be,executeRequest:()=>ze,invalidateResolvedSubtreeCache:()=>Re,logRequest:()=>Ue,parseToJson:()=>Ce,requestResolvedSubtree:()=>ke,resolveSpec:()=>we,setMutatedRequest:()=>Le,setRequest:()=>De,setResponse:()=>Ve,setScheme:()=>We,updateEmptyParamInclusion:()=>Te,updateJsonSpec:()=>be,updateResolved:()=>Ee,updateResolvedSubtree:()=>qe,updateSpec:()=>ye,updateUrl:()=>Se,validateParams:()=>Pe});var r=n(67),a=n.n(r),o=n(5579),s=n.n(o);const l=require("@babel/runtime-corejs3/helpers/asyncToGenerator");var i=n.n(l),c=n(6768),u=n.n(c);const p=require("@babel/runtime-corejs3/regenerator");var d=n.n(p),m=n(7104),h=n.n(m),f=n(3942),g=n.n(f);const v=require("@babel/runtime-corejs3/core-js-stable/object/define-property");var y=n.n(v),E=n(66),S=n.n(E),b=n(7834),C=n.n(b);const x=require("@babel/runtime-corejs3/core-js-stable/promise");var w=n.n(x),_=n(9998),A=n.n(_),k=n(9968),N=n.n(k),I=n(8493),q=n.n(I),R=n(4235),P=n.n(R),T=n(4883),O=n.n(T),M=n(7252),j=n.n(M),V=n(4994),D=n.n(V);const L=require("@babel/runtime-corejs3/core-js-stable/date/now");var U=n.n(L),z=n(9793),B=n.n(z),J=n(5572),F=n(3883),W=n.n(F),H=n(41);const K=require("lodash/isString");var Z=n.n(K);const G=require("lodash/debounce");var Y=n.n(G);const X=require("lodash/set");var Q=n.n(X),$=n(1890),ee=["path","method"],te="spec_update_spec",ne="spec_update_url",re="spec_update_json",ae="spec_update_param",oe="spec_update_empty_param_inclusion",se="spec_validate_param",le="spec_set_response",ie="spec_set_request",ce="spec_set_mutated_request",ue="spec_log_request",pe="spec_clear_response",de="spec_clear_request",me="spec_clear_validate_param",he="spec_update_operation_meta_value",fe="spec_update_resolved",ge="spec_update_resolved_subtree",ve="set_scheme";function ye(e){var t,n=(t=e,Z()(t)?t:"").replace(/\t/g," ");if("string"==typeof e)return{type:te,payload:n}}function Ee(e){return{type:fe,payload:e}}function Se(e){return{type:ne,payload:e}}function be(e){return{type:re,payload:e}}var Ce=function(e){return function(t){var n=t.specActions,r=t.specSelectors,a=t.errActions,o=r.specStr,s=null;try{e=e||o(),a.clear({source:"parser"}),s=B().load(e,{schema:z.JSON_SCHEMA})}catch(e){return console.error(e),a.newSpecErr({source:"parser",level:"error",message:e.reason,line:e.mark&&e.mark.line?e.mark.line+1:void 0})}return s&&"object"===u()(s)?n.updateJsonSpec(s):{}}},xe=!1,we=function(e,t){return function(n){var r=n.specActions,a=n.specSelectors,o=n.errActions,s=n.fn,l=s.fetch,i=s.resolve,c=s.AST,u=void 0===c?{}:c,p=n.getConfigs;xe||(console.warn("specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!"),xe=!0);var d=p(),m=d.modelPropertyMacro,f=d.parameterMacro,v=d.requestInterceptor,E=d.responseInterceptor;void 0===e&&(e=a.specJson()),void 0===t&&(t=a.url());var S=u.getLineNumberForPath?u.getLineNumberForPath:function(){},b=a.specStr();return i({fetch:l,spec:e,baseDoc:t,modelPropertyMacro:m,parameterMacro:f,requestInterceptor:v,responseInterceptor:E}).then((function(e){var t=e.spec,n=e.errors;if(o.clear({type:"thrown"}),h()(n)&&n.length>0){var a=g()(n).call(n,(function(e){return console.error(e),e.line=e.fullPath?S(b,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",y()(e,"message",{enumerable:!0,value:e.message}),e}));o.newThrownErrBatch(a)}return r.updateResolved(t)}))}},_e=[],Ae=Y()(i()(d().mark((function e(){var t,n,r,a,o,s,l,c,u,p,m,f,v,E,b,x,_,k;return d().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(t=_e.system){e.next=4;break}return console.error("debResolveSubtrees: don't have a system to operate on, aborting."),e.abrupt("return");case 4:if(n=t.errActions,r=t.errSelectors,a=t.fn,o=a.resolveSubtree,s=a.fetch,l=a.AST,c=void 0===l?{}:l,u=t.specSelectors,p=t.specActions,o){e.next=8;break}return console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing."),e.abrupt("return");case 8:return m=c.getLineNumberForPath?c.getLineNumberForPath:function(){},f=u.specStr(),v=t.getConfigs(),E=v.modelPropertyMacro,b=v.parameterMacro,x=v.requestInterceptor,_=v.responseInterceptor,e.prev=11,e.next=14,S()(_e).call(_e,function(){var e=i()(d().mark((function e(t,a){var l,c,p,v,S,k,I,q,R;return d().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.next=2,t;case 2:return l=e.sent,c=l.resultMap,p=l.specWithCurrentSubtrees,e.next=7,o(p,a,{baseDoc:u.url(),modelPropertyMacro:E,parameterMacro:b,requestInterceptor:x,responseInterceptor:_});case 7:if(v=e.sent,S=v.errors,k=v.spec,r.allErrors().size&&n.clearBy((function(e){var t;return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!C()(t=e.get("fullPath")).call(t,(function(e,t){return e===a[t]||void 0===a[t]}))})),h()(S)&&S.length>0&&(I=g()(S).call(S,(function(e){return e.line=e.fullPath?m(f,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",y()(e,"message",{enumerable:!0,value:e.message}),e})),n.newThrownErrBatch(I)),!k||!u.isOAS3()||"components"!==a[0]||"securitySchemes"!==a[1]){e.next=15;break}return e.next=15,w().all(g()(q=A()(R=N()(k)).call(R,(function(e){return"openIdConnect"===e.type}))).call(q,function(){var e=i()(d().mark((function e(t){var n,r;return d().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n={url:t.openIdConnectUrl,requestInterceptor:x,responseInterceptor:_},e.prev=1,e.next=4,s(n);case 4:(r=e.sent)instanceof Error||r.status>=400?console.error(r.statusText+" "+n.url):t.openIdConnectData=JSON.parse(r.text),e.next=11;break;case 8:e.prev=8,e.t0=e.catch(1),console.error(e.t0);case 11:case"end":return e.stop()}}),e,null,[[1,8]])})));return function(t){return e.apply(this,arguments)}}()));case 15:return Q()(c,a,k),Q()(p,a,k),e.abrupt("return",{resultMap:c,specWithCurrentSubtrees:p});case 18:case"end":return e.stop()}}),e)})));return function(t,n){return e.apply(this,arguments)}}(),w().resolve({resultMap:(u.specResolvedSubtree([])||(0,J.Map)()).toJS(),specWithCurrentSubtrees:u.specJson().toJS()}));case 14:k=e.sent,delete _e.system,_e=[],e.next=22;break;case 19:e.prev=19,e.t0=e.catch(11),console.error(e.t0);case 22:p.updateResolvedSubtree([],k.resultMap);case 23:case"end":return e.stop()}}),e,null,[[11,19]])}))),35),ke=function(e){return function(t){var n;q()(n=g()(_e).call(_e,(function(e){return e.join("@@")}))).call(n,e.join("@@"))>-1||(_e.push(e),_e.system=t,Ae())}};function Ne(e,t,n,r,a){return{type:ae,payload:{path:e,value:r,paramName:t,paramIn:n,isXml:a}}}function Ie(e,t,n,r){return{type:ae,payload:{path:e,param:t,value:n,isXml:r}}}var qe=function(e,t){return{type:ge,payload:{path:e,value:t}}},Re=function(){return{type:ge,payload:{path:[],value:(0,J.Map)()}}},Pe=function(e,t){return{type:se,payload:{pathMethod:e,isOAS3:t}}},Te=function(e,t,n,r){return{type:oe,payload:{pathMethod:e,paramName:t,paramIn:n,includeEmptyValue:r}}};function Oe(e){return{type:me,payload:{pathMethod:e}}}function Me(e,t){return{type:he,payload:{path:e,value:t,key:"consumes_value"}}}function je(e,t){return{type:he,payload:{path:e,value:t,key:"produces_value"}}}var Ve=function(e,t,n){return{payload:{path:e,method:t,res:n},type:le}},De=function(e,t,n){return{payload:{path:e,method:t,req:n},type:ie}},Le=function(e,t,n){return{payload:{path:e,method:t,req:n},type:ce}},Ue=function(e){return{payload:e,type:ue}},ze=function(e){return function(t){var n,r,a=t.fn,o=t.specActions,s=t.specSelectors,l=t.getConfigs,c=t.oas3Selectors,u=e.pathName,p=e.method,m=e.operation,f=l(),v=f.requestInterceptor,y=f.responseInterceptor,E=m.toJS();m&&m.get("parameters")&&P()(n=A()(r=m.get("parameters")).call(r,(function(e){return e&&!0===e.get("allowEmptyValue")}))).call(n,(function(t){if(s.parameterInclusionSettingFor([u,p],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};var n=(0,$.cz)(t,e.parameters);(!n||n&&0===n.size)&&(e.parameters[t.get("name")]="")}}));if(e.contextUrl=W()(s.url()).toString(),E&&E.operationId?e.operationId=E.operationId:E&&u&&p&&(e.operationId=a.opId(E,u,p)),s.isOAS3()){var S,b=O()(S="".concat(u,":")).call(S,p);e.server=c.selectedServer(b)||c.selectedServer();var C=c.serverVariables({server:e.server,namespace:b}).toJS(),x=c.serverVariables({server:e.server}).toJS();e.serverVariables=j()(C).length?C:x,e.requestContentType=c.requestContentType(u,p),e.responseContentType=c.responseContentType(u,p)||"*/*";var w,_=c.requestBodyValue(u,p),k=c.requestBodyInclusionSetting(u,p);if(_&&_.toJS)e.requestBody=A()(w=g()(_).call(_,(function(e){return J.Map.isMap(e)?e.get("value"):e}))).call(w,(function(e,t){return(h()(e)?0!==e.length:!(0,$.O2)(e))||k.get(t)})).toJS();else e.requestBody=_}var N=D()({},e);N=a.buildRequest(N),o.setRequest(e.pathName,e.method,N);var I=function(){var t=i()(d().mark((function t(n){var r,a;return d().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:return t.next=2,v.apply(undefined,[n]);case 2:return r=t.sent,a=D()({},r),o.setMutatedRequest(e.pathName,e.method,a),t.abrupt("return",r);case 6:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}();e.requestInterceptor=I,e.responseInterceptor=y;var q=U()();return a.execute(e).then((function(t){t.duration=U()()-q,o.setResponse(e.pathName,e.method,t)})).catch((function(t){"Failed to fetch"===t.message&&(t.name="",t.message='**Failed to fetch.** \n**Possible Reasons:** \n - CORS \n - Network Failure \n - URL scheme must be "http" or "https" for CORS request.'),o.setResponse(e.pathName,e.method,{error:!0,err:(0,H.serializeError)(t)})}))}},Be=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.path,n=e.method,r=s()(e,ee);return function(e){var o=e.fn.fetch,s=e.specSelectors,l=e.specActions,i=s.specJsonWithResolvedSubtrees().toJS(),c=s.operationScheme(t,n),u=s.contentTypeValues([t,n]).toJS(),p=u.requestContentType,d=u.responseContentType,m=/xml/i.test(p),h=s.parameterValues([t,n],m).toJS();return l.executeRequest(a()(a()({},r),{},{fetch:o,spec:i,pathName:t,method:n,parameters:h,requestContentType:p,scheme:c,responseContentType:d}))}};function Je(e,t){return{type:pe,payload:{path:e,method:t}}}function Fe(e,t){return{type:de,payload:{path:e,method:t}}}function We(e,t,n){return{type:ve,payload:{scheme:e,path:t,method:n}}}},7038:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>l});var r=n(32),a=n(7960),o=n(3881),s=n(7508);function l(){return{statePlugins:{spec:{wrapActions:s,reducers:r.default,actions:a,selectors:o}}}}},32:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>b});var r,a=n(1093),o=n.n(a),s=n(6731),l=n.n(s),i=n(4883),c=n.n(i),u=n(66),p=n.n(u),d=n(3942),m=n.n(d),h=n(4994),f=n.n(h),g=n(5572),v=n(1890),y=n(7504),E=n(3881),S=n(7960);const b=(r={},o()(r,S.UPDATE_SPEC,(function(e,t){return"string"==typeof t.payload?e.set("spec",t.payload):e})),o()(r,S.UPDATE_URL,(function(e,t){return e.set("url",t.payload+"")})),o()(r,S.UPDATE_JSON,(function(e,t){return e.set("json",(0,v.oG)(t.payload))})),o()(r,S.UPDATE_RESOLVED,(function(e,t){return e.setIn(["resolved"],(0,v.oG)(t.payload))})),o()(r,S.UPDATE_RESOLVED_SUBTREE,(function(e,t){var n,r=t.payload,a=r.value,o=r.path;return e.setIn(c()(n=["resolvedSubtrees"]).call(n,l()(o)),(0,v.oG)(a))})),o()(r,S.UPDATE_PARAM,(function(e,t){var n,r,a=t.payload,o=a.path,s=a.paramName,i=a.paramIn,u=a.param,p=a.value,d=a.isXml,m=u?(0,v.V9)(u):c()(n="".concat(i,".")).call(n,s),h=d?"value_xml":"value";return e.setIn(c()(r=["meta","paths"]).call(r,l()(o),["parameters",m,h]),p)})),o()(r,S.UPDATE_EMPTY_PARAM_INCLUSION,(function(e,t){var n,r,a=t.payload,o=a.pathMethod,s=a.paramName,i=a.paramIn,u=a.includeEmptyValue;if(!s||!i)return console.warn("Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey."),e;var p=c()(n="".concat(i,".")).call(n,s);return e.setIn(c()(r=["meta","paths"]).call(r,l()(o),["parameter_inclusions",p]),u)})),o()(r,S.VALIDATE_PARAMS,(function(e,t){var n,r,a=t.payload,o=a.pathMethod,s=a.isOAS3,i=(0,E.specJsonWithResolvedSubtrees)(e).getIn(c()(n=["paths"]).call(n,l()(o))),u=(0,E.parameterValues)(e,o).toJS();return e.updateIn(c()(r=["meta","paths"]).call(r,l()(o),["parameters"]),(0,g.fromJS)({}),(function(t){var n;return p()(n=i.get("parameters",(0,g.List)())).call(n,(function(t,n){var r=(0,v.cz)(n,u),a=(0,E.parameterInclusionSettingFor)(e,o,n.get("name"),n.get("in")),l=(0,v.Ik)(n,r,{bypassRequiredCheck:a,isOAS3:s});return t.setIn([(0,v.V9)(n),"errors"],(0,g.fromJS)(l))}),t)}))})),o()(r,S.CLEAR_VALIDATE_PARAMS,(function(e,t){var n,r=t.payload.pathMethod;return e.updateIn(c()(n=["meta","paths"]).call(n,l()(r),["parameters"]),(0,g.fromJS)([]),(function(e){return m()(e).call(e,(function(e){return e.set("errors",(0,g.fromJS)([]))}))}))})),o()(r,S.SET_RESPONSE,(function(e,t){var n,r=t.payload,a=r.res,o=r.path,s=r.method;(n=a.error?f()({error:!0,name:a.err.name,message:a.err.message,statusCode:a.err.statusCode},a.err.response):a).headers=n.headers||{};var l=e.setIn(["responses",o,s],(0,v.oG)(n));return y.Z.Blob&&a.data instanceof y.Z.Blob&&(l=l.setIn(["responses",o,s,"text"],a.data)),l})),o()(r,S.SET_REQUEST,(function(e,t){var n=t.payload,r=n.req,a=n.path,o=n.method;return e.setIn(["requests",a,o],(0,v.oG)(r))})),o()(r,S.SET_MUTATED_REQUEST,(function(e,t){var n=t.payload,r=n.req,a=n.path,o=n.method;return e.setIn(["mutatedRequests",a,o],(0,v.oG)(r))})),o()(r,S.UPDATE_OPERATION_META_VALUE,(function(e,t){var n,r,a,o,s,i,u=t.payload,p=u.path,d=u.value,m=u.key,h=c()(n=["paths"]).call(n,l()(p)),f=c()(r=["meta","paths"]).call(r,l()(p));return e.getIn(c()(a=["json"]).call(a,l()(h)))||e.getIn(c()(o=["resolved"]).call(o,l()(h)))||e.getIn(c()(s=["resolvedSubtrees"]).call(s,l()(h)))?e.setIn(c()(i=[]).call(i,l()(f),[m]),(0,g.fromJS)(d)):e})),o()(r,S.CLEAR_RESPONSE,(function(e,t){var n=t.payload,r=n.path,a=n.method;return e.deleteIn(["responses",r,a])})),o()(r,S.CLEAR_REQUEST,(function(e,t){var n=t.payload,r=n.path,a=n.method;return e.deleteIn(["requests",r,a])})),o()(r,S.SET_SCHEME,(function(e,t){var n=t.payload,r=n.scheme,a=n.path,o=n.method;return a&&o?e.setIn(["scheme",a,o],r):a||o?void 0:e.setIn(["scheme","_defaultScheme"],r)})),r)},3881:(e,t,n)=>{"use strict";n.r(t),n.d(t,{lastError:()=>O,url:()=>M,specStr:()=>j,specSource:()=>V,specJson:()=>D,specResolved:()=>L,specResolvedSubtree:()=>U,specJsonWithResolvedSubtrees:()=>B,spec:()=>J,isOAS3:()=>F,info:()=>W,externalDocs:()=>H,version:()=>K,semver:()=>Z,paths:()=>G,operations:()=>Y,consumes:()=>X,produces:()=>Q,security:()=>$,securityDefinitions:()=>ee,findDefinition:()=>te,definitions:()=>ne,basePath:()=>re,host:()=>ae,schemes:()=>oe,operationsWithRootInherited:()=>se,tags:()=>le,tagDetails:()=>ie,operationsWithTags:()=>ce,taggedOperations:()=>ue,responses:()=>pe,requests:()=>de,mutatedRequests:()=>me,responseFor:()=>he,requestFor:()=>fe,mutatedRequestFor:()=>ge,allowTryItOutFor:()=>ve,parameterWithMetaByIdentity:()=>ye,parameterInclusionSettingFor:()=>Ee,parameterWithMeta:()=>Se,operationWithMeta:()=>be,getParameter:()=>Ce,hasHost:()=>xe,parameterValues:()=>we,parametersIncludeIn:()=>_e,parametersIncludeType:()=>Ae,contentTypeValues:()=>ke,currentProducesFor:()=>Ne,producesOptionsFor:()=>Ie,consumesOptionsFor:()=>qe,operationScheme:()=>Re,canExecuteScheme:()=>Pe,validateBeforeExecute:()=>Te,getOAS3RequiredRequestBodyContentType:()=>Oe,isMediaTypeSchemaPropertiesEqual:()=>Me});var r=n(8030),a=n.n(r),o=n(6731),s=n.n(o),l=n(4883),i=n.n(l),c=n(600),u=n.n(c),p=n(4235),d=n.n(p),m=n(8493),h=n.n(m),f=n(3942),g=n.n(f),v=n(9998),y=n.n(v),E=n(3580),S=n.n(E),b=n(66),C=n.n(b),x=n(9247),w=n.n(x),_=n(5626),A=n.n(_),k=n(7104),N=n.n(k),I=n(6814),q=n(1890),R=n(5572),P=["get","put","post","delete","options","head","patch","trace"],T=function(e){return e||(0,R.Map)()},O=(0,I.createSelector)(T,(function(e){return e.get("lastError")})),M=(0,I.createSelector)(T,(function(e){return e.get("url")})),j=(0,I.createSelector)(T,(function(e){return e.get("spec")||""})),V=(0,I.createSelector)(T,(function(e){return e.get("specSource")||"not-editor"})),D=(0,I.createSelector)(T,(function(e){return e.get("json",(0,R.Map)())})),L=(0,I.createSelector)(T,(function(e){return e.get("resolved",(0,R.Map)())})),U=function(e,t){var n;return e.getIn(i()(n=["resolvedSubtrees"]).call(n,s()(t)),void 0)},z=function e(t,n){return R.Map.isMap(t)&&R.Map.isMap(n)?n.get("$$ref")?n:(0,R.OrderedMap)().mergeWith(e,t,n):n},B=(0,I.createSelector)(T,(function(e){return(0,R.OrderedMap)().mergeWith(z,e.get("json"),e.get("resolvedSubtrees"))})),J=function(e){return D(e)},F=(0,I.createSelector)(J,(function(){return!1})),W=(0,I.createSelector)(J,(function(e){return je(e&&e.get("info"))})),H=(0,I.createSelector)(J,(function(e){return je(e&&e.get("externalDocs"))})),K=(0,I.createSelector)(W,(function(e){return e&&e.get("version")})),Z=(0,I.createSelector)(K,(function(e){var t;return u()(t=/v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(e)).call(t,1)})),G=(0,I.createSelector)(B,(function(e){return e.get("paths")})),Y=(0,I.createSelector)(G,(function(e){if(!e||e.size<1)return(0,R.List)();var t=(0,R.List)();return e&&d()(e)?(d()(e).call(e,(function(e,n){if(!e||!d()(e))return{};d()(e).call(e,(function(e,r){var a;h()(P).call(P,r)<0||(t=t.push((0,R.fromJS)({path:n,method:r,operation:e,id:i()(a="".concat(r,"-")).call(a,n)})))}))})),t):(0,R.List)()})),X=(0,I.createSelector)(J,(function(e){return(0,R.Set)(e.get("consumes"))})),Q=(0,I.createSelector)(J,(function(e){return(0,R.Set)(e.get("produces"))})),$=(0,I.createSelector)(J,(function(e){return e.get("security",(0,R.List)())})),ee=(0,I.createSelector)(J,(function(e){return e.get("securityDefinitions")})),te=function(e,t){var n=e.getIn(["resolvedSubtrees","definitions",t],null),r=e.getIn(["json","definitions",t],null);return n||r||null},ne=(0,I.createSelector)(J,(function(e){var t=e.get("definitions");return R.Map.isMap(t)?t:(0,R.Map)()})),re=(0,I.createSelector)(J,(function(e){return e.get("basePath")})),ae=(0,I.createSelector)(J,(function(e){return e.get("host")})),oe=(0,I.createSelector)(J,(function(e){return e.get("schemes",(0,R.Map)())})),se=(0,I.createSelector)(Y,X,Q,(function(e,t,n){return g()(e).call(e,(function(e){return e.update("operation",(function(e){if(e){if(!R.Map.isMap(e))return;return e.withMutations((function(e){return e.get("consumes")||e.update("consumes",(function(e){return(0,R.Set)(e).merge(t)})),e.get("produces")||e.update("produces",(function(e){return(0,R.Set)(e).merge(n)})),e}))}return(0,R.Map)()}))}))})),le=(0,I.createSelector)(J,(function(e){var t=e.get("tags",(0,R.List)());return R.List.isList(t)?y()(t).call(t,(function(e){return R.Map.isMap(e)})):(0,R.List)()})),ie=function(e,t){var n,r=le(e)||(0,R.List)();return S()(n=y()(r).call(r,R.Map.isMap)).call(n,(function(e){return e.get("name")===t}),(0,R.Map)())},ce=(0,I.createSelector)(se,le,(function(e,t){return C()(e).call(e,(function(e,t){var n=(0,R.Set)(t.getIn(["operation","tags"]));return n.count()<1?e.update("default",(0,R.List)(),(function(e){return e.push(t)})):C()(n).call(n,(function(e,n){return e.update(n,(0,R.List)(),(function(e){return e.push(t)}))}),e)}),C()(t).call(t,(function(e,t){return e.set(t.get("name"),(0,R.List)())}),(0,R.OrderedMap)()))})),ue=function(e){return function(t){var n,r=(0,t.getConfigs)(),a=r.tagsSorter,o=r.operationsSorter;return g()(n=ce(e).sortBy((function(e,t){return t}),(function(e,t){var n="function"==typeof a?a:q.wh.tagsSorter[a];return n?n(e,t):null}))).call(n,(function(t,n){var r="function"==typeof o?o:q.wh.operationsSorter[o],a=r?w()(t).call(t,r):t;return(0,R.Map)({tagDetails:ie(e,n),operations:a})}))}},pe=(0,I.createSelector)(T,(function(e){return e.get("responses",(0,R.Map)())})),de=(0,I.createSelector)(T,(function(e){return e.get("requests",(0,R.Map)())})),me=(0,I.createSelector)(T,(function(e){return e.get("mutatedRequests",(0,R.Map)())})),he=function(e,t,n){return pe(e).getIn([t,n],null)},fe=function(e,t,n){return de(e).getIn([t,n],null)},ge=function(e,t,n){return me(e).getIn([t,n],null)},ve=function(){return!0},ye=function(e,t,n){var r,a,o=B(e).getIn(i()(r=["paths"]).call(r,s()(t),["parameters"]),(0,R.OrderedMap)()),l=e.getIn(i()(a=["meta","paths"]).call(a,s()(t),["parameters"]),(0,R.OrderedMap)()),c=g()(o).call(o,(function(e){var t,r,a,o=l.get(i()(t="".concat(n.get("in"),".")).call(t,n.get("name"))),s=l.get(i()(r=i()(a="".concat(n.get("in"),".")).call(a,n.get("name"),".hash-")).call(r,n.hashCode()));return(0,R.OrderedMap)().merge(e,o,s)}));return S()(c).call(c,(function(e){return e.get("in")===n.get("in")&&e.get("name")===n.get("name")}),(0,R.OrderedMap)())},Ee=function(e,t,n,r){var a,o,l=i()(a="".concat(r,".")).call(a,n);return e.getIn(i()(o=["meta","paths"]).call(o,s()(t),["parameter_inclusions",l]),!1)},Se=function(e,t,n,r){var a,o=B(e).getIn(i()(a=["paths"]).call(a,s()(t),["parameters"]),(0,R.OrderedMap)()),l=S()(o).call(o,(function(e){return e.get("in")===r&&e.get("name")===n}),(0,R.OrderedMap)());return ye(e,t,l)},be=function(e,t,n){var r,a=B(e).getIn(["paths",t,n],(0,R.OrderedMap)()),o=e.getIn(["meta","paths",t,n],(0,R.OrderedMap)()),s=g()(r=a.get("parameters",(0,R.List)())).call(r,(function(r){return ye(e,[t,n],r)}));return(0,R.OrderedMap)().merge(a,o).set("parameters",s)};function Ce(e,t,n,r){var a;t=t||[];var o=e.getIn(i()(a=["meta","paths"]).call(a,s()(t),["parameters"]),(0,R.fromJS)([]));return S()(o).call(o,(function(e){return R.Map.isMap(e)&&e.get("name")===n&&e.get("in")===r}))||(0,R.Map)()}var xe=(0,I.createSelector)(J,(function(e){var t=e.get("host");return"string"==typeof t&&t.length>0&&"/"!==t[0]}));function we(e,t,n){var r;t=t||[];var a=be.apply(void 0,i()(r=[e]).call(r,s()(t))).get("parameters",(0,R.List)());return C()(a).call(a,(function(e,t){var r=n&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set((0,q.V9)(t,{allowHashes:!1}),r)}),(0,R.fromJS)({}))}function _e(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(R.List.isList(e))return A()(e).call(e,(function(e){return R.Map.isMap(e)&&e.get("in")===t}))}function Ae(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(R.List.isList(e))return A()(e).call(e,(function(e){return R.Map.isMap(e)&&e.get("type")===t}))}function ke(e,t){var n,r;t=t||[];var a=B(e).getIn(i()(n=["paths"]).call(n,s()(t)),(0,R.fromJS)({})),o=e.getIn(i()(r=["meta","paths"]).call(r,s()(t)),(0,R.fromJS)({})),l=Ne(e,t),c=a.get("parameters")||new R.List,u=o.get("consumes_value")?o.get("consumes_value"):Ae(c,"file")?"multipart/form-data":Ae(c,"formData")?"application/x-www-form-urlencoded":void 0;return(0,R.fromJS)({requestContentType:u,responseContentType:l})}function Ne(e,t){var n,r;t=t||[];var a=B(e).getIn(i()(n=["paths"]).call(n,s()(t)),null);if(null!==a){var o=e.getIn(i()(r=["meta","paths"]).call(r,s()(t),["produces_value"]),null),l=a.getIn(["produces",0],null);return o||l||"application/json"}}function Ie(e,t){var n;t=t||[];var r=B(e),o=r.getIn(i()(n=["paths"]).call(n,s()(t)),null);if(null!==o){var l=t,c=a()(l,1)[0],u=o.get("produces",null),p=r.getIn(["paths",c,"produces"],null),d=r.getIn(["produces"],null);return u||p||d}}function qe(e,t){var n;t=t||[];var r=B(e),o=r.getIn(i()(n=["paths"]).call(n,s()(t)),null);if(null!==o){var l=t,c=a()(l,1)[0],u=o.get("consumes",null),p=r.getIn(["paths",c,"consumes"],null),d=r.getIn(["consumes"],null);return u||p||d}}var Re=function(e,t,n){var r=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),a=N()(r)?r[1]:null;return e.getIn(["scheme",t,n])||e.getIn(["scheme","_defaultScheme"])||a||""},Pe=function(e,t,n){var r;return h()(r=["http","https"]).call(r,Re(e,t,n))>-1},Te=function(e,t){var n;t=t||[];var r=e.getIn(i()(n=["meta","paths"]).call(n,s()(t),["parameters"]),(0,R.fromJS)([])),a=!0;return d()(r).call(r,(function(e){var t=e.get("errors");t&&t.count()&&(a=!1)})),a},Oe=function(e,t){var n,r,a={requestBody:!1,requestContentType:{}},o=e.getIn(i()(n=["resolvedSubtrees","paths"]).call(n,s()(t),["requestBody"]),(0,R.fromJS)([]));return o.size<1||(o.getIn(["required"])&&(a.requestBody=o.getIn(["required"])),d()(r=o.getIn(["content"]).entrySeq()).call(r,(function(e){var t=e[0];if(e[1].getIn(["schema","required"])){var n=e[1].getIn(["schema","required"]).toJS();a.requestContentType[t]=n}}))),a},Me=function(e,t,n,r){var a;if((n||r)&&n===r)return!0;var o=e.getIn(i()(a=["resolvedSubtrees","paths"]).call(a,s()(t),["requestBody","content"]),(0,R.fromJS)([]));if(o.size<2||!n||!r)return!1;var l=o.getIn([n,"schema","properties"],(0,R.fromJS)([])),c=o.getIn([r,"schema","properties"],(0,R.fromJS)([]));return!!l.equals(c)};function je(e){return R.Map.isMap(e)?e:new R.Map}},7508:(e,t,n)=>{"use strict";n.r(t),n.d(t,{updateSpec:()=>c,updateJsonSpec:()=>u,executeRequest:()=>p,validateParams:()=>d});var r=n(7252),a=n.n(r),o=n(4235),s=n.n(o),l=n(1712),i=n.n(l),c=function(e,t){var n=t.specActions;return function(){e.apply(void 0,arguments),n.parseToJson.apply(n,arguments)}},u=function(e,t){var n=t.specActions;return function(){for(var t=arguments.length,r=new Array(t),o=0;o{"use strict";n.r(t),n.d(t,{loaded:()=>r});var r=function(e,t){return function(){e.apply(void 0,arguments);var n=t.getConfigs().withCredentials;void 0!==n&&(t.fn.fetch.withCredentials="string"==typeof n?"true"===n:!!n)}}},8901:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>h});var r=n(4883),a=n.n(r);const o=require("swagger-client/es/resolver");var s=n.n(o);const l=require("swagger-client/es/execute"),i=require("swagger-client/es/http");var c=n.n(i);const u=require("swagger-client/es/subtree-resolver");var p=n.n(u),d=n(6765),m=n(4852);function h(e){var t=e.configs,n=e.getConfigs;return{fn:{fetch:(0,i.makeHttp)(c(),t.preFetch,t.postFetch),buildRequest:l.buildRequest,execute:l.execute,resolve:s(),resolveSubtree:function(e,t,r){var o;if(void 0===r){var s=n();r={modelPropertyMacro:s.modelPropertyMacro,parameterMacro:s.parameterMacro,requestInterceptor:s.requestInterceptor,responseInterceptor:s.responseInterceptor}}for(var l=arguments.length,i=new Array(l>3?l-3:0),c=3;c{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(1890);function a(){return{fn:{shallowEqualKeys:r.be}}}},8347:(e,t,n)=>{"use strict";n.r(t),n.d(t,{getDisplayName:()=>r});var r=function(e){return e.displayName||e.name||"Component"}},3420:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(8344),a=n.n(r),o=n(1890),s=n(290),l=n(8347),i=n(7156);const c=function(e){var t,n=e.getComponents,r=e.getStore,c=e.getSystem,u=(t=(0,s.getComponent)(c,r,n),(0,o.HP)(t,(function(){for(var e=arguments.length,t=new Array(e),n=0;n{"use strict";n.r(t),n.d(t,{getComponent:()=>T,render:()=>P,withMappedContainer:()=>R});var r=n(6768),a=n.n(r),o=n(67),s=n.n(o),l=n(4250),i=n.n(l),c=n(6349),u=n.n(c),p=n(4606),d=n.n(p),m=n(4291),h=n.n(m),f=n(1885),g=n.n(f),v=n(7252),y=n.n(v),E=n(6689),S=n.n(E);const b=require("react-dom");var C=n.n(b),x=n(6695);const w=require("react-redux"),_=require("lodash/omit");var A=n.n(_);const k=require("lodash/identity");var N=n.n(k),I=function(e,t,n){return(0,x.compose)(n?function(e,t){return function(n){var r=e().fn,a=function(e){h()(a,e);var r=g()(a);function a(){return u()(this,a),r.apply(this,arguments)}return d()(a,[{key:"render",value:function(){return S().createElement(w.Provider,{store:t},S().createElement(n,i()({},this.props,this.context)))}}]),a}(E.Component);return a.displayName="WithRoot(".concat(r.getDisplayName(n),")"),a}}(e,n):N(),(0,w.connect)((function(n,r){var a,o=s()(s()({},r),e()),l=(null===(a=t.prototype)||void 0===a?void 0:a.mapStateToProps)||function(e){return{state:e}};return l(n,o)})),function(e){return function(t){var n=e().fn,r=function(n){h()(a,n);var r=g()(a);function a(){return u()(this,a),r.apply(this,arguments)}return d()(a,[{key:"render",value:function(){return S().createElement(t,i()({},e(),this.props,this.context))}}]),a}(E.Component);return r.displayName="WithSystem(".concat(n.getDisplayName(t),")"),r}}(e))(t)},q=function(e,t,n,r){for(var a in t){var o=t[a];"function"==typeof o&&o(n[a],r[a],e())}},R=function(e,t,n){return function(t,r){var a=e().fn,o=n(t,"root"),s=function(t){h()(a,t);var n=g()(a);function a(t,o){var s;return u()(this,a),s=n.call(this,t,o),q(e,r,t,{}),s}return d()(a,[{key:"UNSAFE_componentWillReceiveProps",value:function(t){q(e,r,t,this.props)}},{key:"render",value:function(){var e=A()(this.props,r?y()(r):[]);return S().createElement(o,e)}}]),a}(E.Component);return s.displayName="WithMappedContainer(".concat(a.getDisplayName(o),")"),s}},P=function(e,t,n,r){return function(a){var o=n(e,t,r)("App","root");C().render(S().createElement(o,null),a)}},T=function(e,t,n){return function(r,o){var s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"!=typeof r)throw new TypeError("Need a string, to fetch a component. Was given a "+a()(r));var l=n(r);return l?o?"root"===o?I(e,l,t()):I(e,l):l:(s.failSilently||e().log.warn("Could not find component:",r),null)}}},6068:(e,t,n)=>{"use strict";n.d(t,{d3:()=>i(),C2:()=>V});var r=n(7252),a=n.n(r),o=n(2605),s=n.n(o);const l=require("react-syntax-highlighter/dist/esm/light");var i=n.n(l);const c=require("react-syntax-highlighter/dist/esm/languages/hljs/javascript");var u=n.n(c);const p=require("react-syntax-highlighter/dist/esm/languages/hljs/json");var d=n.n(p);const m=require("react-syntax-highlighter/dist/esm/languages/hljs/xml");var h=n.n(m);const f=require("react-syntax-highlighter/dist/esm/languages/hljs/bash");var g=n.n(f);const v=require("react-syntax-highlighter/dist/esm/languages/hljs/yaml");var y=n.n(v);const E=require("react-syntax-highlighter/dist/esm/languages/hljs/http");var S=n.n(E);const b=require("react-syntax-highlighter/dist/esm/languages/hljs/powershell");var C=n.n(b);const x=require("react-syntax-highlighter/dist/esm/styles/hljs/agate");var w=n.n(x);const _=require("react-syntax-highlighter/dist/esm/styles/hljs/arta");var A=n.n(_);const k=require("react-syntax-highlighter/dist/esm/styles/hljs/monokai");var N=n.n(k);const I=require("react-syntax-highlighter/dist/esm/styles/hljs/nord");var q=n.n(I);const R=require("react-syntax-highlighter/dist/esm/styles/hljs/obsidian");var P=n.n(R);const T=require("react-syntax-highlighter/dist/esm/styles/hljs/tomorrow-night");var O=n.n(T);i().registerLanguage("json",d()),i().registerLanguage("js",u()),i().registerLanguage("xml",h()),i().registerLanguage("yaml",y()),i().registerLanguage("http",S()),i().registerLanguage("bash",g()),i().registerLanguage("powershell",C()),i().registerLanguage("javascript",u());var M={agate:w(),arta:A(),monokai:N(),nord:q(),obsidian:P(),"tomorrow-night":O()},j=a()(M),V=function(e){return s()(j).call(j,e)?M[e]:(console.warn("Request style '".concat(e,"' is not available, returning default instead")),w())}},1890:(e,t,n)=>{"use strict";n.d(t,{r3:()=>Fe,GZ:()=>He,Xb:()=>lt,oJ:()=>Xe,XV:()=>tt,iQ:()=>Re,J6:()=>Qe,DR:()=>Te,oG:()=>be,Uj:()=>st,QG:()=>Ye,po:()=>et,nX:()=>$e,gp:()=>Pe,xi:()=>Be,kJ:()=>Ae,O2:()=>ct,LQ:()=>xe,Wl:()=>_e,Kn:()=>we,HP:()=>ke,AF:()=>Ce,D$:()=>rt,Ay:()=>Ne,Q2:()=>Ie,mz:()=>Se,V9:()=>at,cz:()=>ot,UG:()=>Je,Zl:()=>Oe,hW:()=>Ge,Nm:()=>Ze,be:()=>Ke,wh:()=>We,Pz:()=>nt,_5:()=>qe,Ik:()=>je});var r=n(6731),a=n.n(r),o=(n(8030),n(6768)),s=n.n(o),l=n(1771),i=n.n(l),c=n(7104),u=n.n(c),p=n(3942),d=n.n(p),m=n(7862),h=n.n(m),f=n(4883),g=n.n(f),v=n(4235),y=n.n(v),E=n(9998),S=n.n(E),b=n(7252),C=n.n(b),x=(n(593),n(66)),w=n.n(x),_=n(4994),A=n.n(_),k=n(9247),N=n.n(k),I=n(600),q=n.n(I),R=n(5626),P=n.n(R),T=(n(2605),n(8344)),O=n.n(T),M=n(8493),j=n.n(M),V=n(3580),D=n.n(V),L=n(3262),U=n.n(L),z=n(7390),B=n.n(z),J=n(5572),F=n.n(J);const W=require("@braintree/sanitize-url"),H=require("lodash/camelCase");var K=n.n(H);const Z=require("lodash/upperFirst");var G=n.n(Z),Y=n(541),X=n.n(Y);const Q=require("lodash/find");var $=n.n(Q);const ee=require("lodash/some");var te=n.n(ee);const ne=require("lodash/eq");var re=n.n(ne),ae=n(5716),oe=n.n(ae),se=n(4128),le=n(7504);const ie=require("css.escape");var ce=n.n(ie),ue=n(9069),pe=n(185),de=n.n(pe);const me=require("sha.js");var he=n.n(me),fe=n(9793),ge=n.n(fe),ve=n(871).Buffer,ye="default",Ee=function(e){return F().Iterable.isIterable(e)};function Se(e){return we(e)?Ee(e)?e.toJS():e:{}}function be(e){var t,n;if(Ee(e))return e;if(e instanceof le.Z.File)return e;if(!we(e))return e;if(u()(e))return d()(n=F().Seq(e)).call(n,be).toList();if(oe()(h()(e))){var r,a=function(e){if(!oe()(h()(e)))return e;var t,n={},r="_**[]",a={},o=i()(h()(e).call(e));try{for(o.s();!(t=o.n()).done;){var s=t.value;if(n[s[0]]||a[s[0]]&&a[s[0]].containsMultiple){var l,c,u,p;if(!a[s[0]])a[s[0]]={containsMultiple:!0,length:1},n[g()(u=g()(p="".concat(s[0])).call(p,r)).call(u,a[s[0]].length)]=n[s[0]],delete n[s[0]];a[s[0]].length+=1,n[g()(l=g()(c="".concat(s[0])).call(c,r)).call(l,a[s[0]].length)]=s[1]}else n[s[0]]=s[1]}}catch(e){o.e(e)}finally{o.f()}return n}(e);return d()(r=F().OrderedMap(a)).call(r,be)}return d()(t=F().OrderedMap(e)).call(t,be)}function Ce(e){return u()(e)?e:[e]}function xe(e){return"function"==typeof e}function we(e){return!!e&&"object"===s()(e)}function _e(e){return"function"==typeof e}function Ae(e){return u()(e)}var ke=X();function Ne(e,t){var n;return w()(n=C()(e)).call(n,(function(n,r){return n[r]=t(e[r],r),n}),{})}function Ie(e,t){var n;return w()(n=C()(e)).call(n,(function(n,r){var a=t(e[r],r);return a&&"object"===s()(a)&&A()(n,a),n}),{})}function qe(e){return function(t){t.dispatch,t.getState;return function(t){return function(n){return"function"==typeof n?n(e()):t(n)}}}}function Re(e){var t,n=e.keySeq();return n.contains(ye)?ye:N()(t=S()(n).call(n,(function(e){return"2"===(e+"")[0]}))).call(t).first()}function Pe(e,t){if(!F().Iterable.isIterable(e))return F().List();var n=e.getIn(u()(t)?t:[t]);return F().List.isList(n)?n:F().List()}function Te(e){var t,n=[/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i];if(P()(n).call(n,(function(n){return null!==(t=n.exec(e))})),null!==t&&t.length>1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function Oe(e){return t=e.replace(/\.[^./]*$/,""),G()(K()(t));var t}function Me(e,t,n,r,o){if(!t)return[];var l=[],i=t.get("nullable"),c=t.get("required"),p=t.get("maximum"),m=t.get("minimum"),h=t.get("type"),f=t.get("format"),v=t.get("maxLength"),E=t.get("minLength"),b=t.get("uniqueItems"),C=t.get("maxItems"),x=t.get("minItems"),w=t.get("pattern"),_=n||!0===c,A=null!=e;if(i&&null===e||!h||!(_||A&&"array"===h||!(!_&&!A)))return[];var k="string"===h&&e,N="array"===h&&u()(e)&&e.length,I="array"===h&&F().List.isList(e)&&e.count(),q=[k,N,I,"array"===h&&"string"==typeof e&&e,"file"===h&&e instanceof le.Z.File,"boolean"===h&&(e||!1===e),"number"===h&&(e||0===e),"integer"===h&&(e||0===e),"object"===h&&"object"===s()(e)&&null!==e,"object"===h&&"string"==typeof e&&e],R=P()(q).call(q,(function(e){return!!e}));if(_&&!R&&!r)return l.push("Required field is not provided"),l;if("object"===h&&(null===o||"application/json"===o)){var T,O=e;if("string"==typeof e)try{O=JSON.parse(e)}catch(e){return l.push("Parameter string value must be valid JSON"),l}if(t&&t.has("required")&&_e(c.isList)&&c.isList()&&y()(c).call(c,(function(e){void 0===O[e]&&l.push({propKey:e,error:"Required property not found"})})),t&&t.has("properties"))y()(T=t.get("properties")).call(T,(function(e,t){var n=Me(O[t],e,!1,r,o);l.push.apply(l,a()(d()(n).call(n,(function(e){return{propKey:t,error:e}}))))}))}if(w){var M=function(e,t){if(!new RegExp(t).test(e))return"Value must follow pattern "+t}(e,w);M&&l.push(M)}if(x&&"array"===h){var j=function(e,t){var n;if(!e&&t>=1||e&&e.lengtht)return g()(n="Array must not contain more then ".concat(t," item")).call(n,1===t?"":"s")}(e,C);V&&l.push({needRemove:!0,error:V})}if(b&&"array"===h){var D=function(e,t){if(e&&("true"===t||!0===t)){var n=(0,J.fromJS)(e),r=n.toSet();if(e.length>r.size){var a=(0,J.Set)();if(y()(n).call(n,(function(e,t){S()(n).call(n,(function(t){return _e(t.equals)?t.equals(e):t===e})).size>1&&(a=a.add(t))})),0!==a.size)return d()(a).call(a,(function(e){return{index:e,error:"No duplicates allowed."}})).toArray()}}}(e,b);D&&l.push.apply(l,a()(D))}if(v||0===v){var L=function(e,t){var n;if(e.length>t)return g()(n="Value must be no longer than ".concat(t," character")).call(n,1!==t?"s":"")}(e,v);L&&l.push(L)}if(E){var U=function(e,t){var n;if(e.lengtht)return"Value must be less than ".concat(t)}(e,p);z&&l.push(z)}if(m||0===m){var B=function(e,t){if(e2&&void 0!==arguments[2]?arguments[2]:{},r=n.isOAS3,a=void 0!==r&&r,o=n.bypassRequiredCheck,s=void 0!==o&&o,l=e.get("required"),i=(0,ue.Z)(e,{isOAS3:a}),c=i.schema,u=i.parameterContentMediaType;return Me(t,c,l,s,u)},Ve=function(e,t,n){if(e&&(!e.xml||!e.xml.name)){if(e.xml=e.xml||{},!e.$$ref)return e.type||e.items||e.properties||e.additionalProperties?'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e':null;var r=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=r[1]}return(0,se.memoizedCreateXMLExample)(e,t,n)},De=[{when:/json/,shouldStringifyTypes:["string"]}],Le=["object"],Ue=function(e,t,n,r){var o=(0,se.memoizedSampleFromSchema)(e,t,r),l=s()(o),i=w()(De).call(De,(function(e,t){var r;return t.when.test(n)?g()(r=[]).call(r,a()(e),a()(t.shouldStringifyTypes)):e}),Le);return te()(i,(function(e){return e===l}))?O()(o,null,2):o},ze=function(e,t,n,r){var a,o=Ue(e,t,n,r);try{"\n"===(a=ge().dump(ge().load(o),{lineWidth:-1},{schema:fe.JSON_SCHEMA}))[a.length-1]&&(a=q()(a).call(a,0,a.length-1))}catch(e){return console.error(e),"error: could not generate yaml example"}return a.replace(/\t/g," ")},Be=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;return e&&_e(e.toJS)&&(e=e.toJS()),r&&_e(r.toJS)&&(r=r.toJS()),/xml/.test(t)?Ve(e,n,r):/(yaml|yml)/.test(t)?ze(e,n,t,r):Ue(e,n,t,r)},Je=function(){var e={},t=le.Z.location.search;if(!t)return{};if(""!=t){var n=t.substr(1).split("&");for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(r=n[r].split("="),e[decodeURIComponent(r[0])]=r[1]&&decodeURIComponent(r[1])||"")}return e},Fe=function(e){return(e instanceof ve?e:ve.from(e.toString(),"utf-8")).toString("base64")},We={operationsSorter:{alpha:function(e,t){return e.get("path").localeCompare(t.get("path"))},method:function(e,t){return e.get("method").localeCompare(t.get("method"))}},tagsSorter:{alpha:function(e,t){return e.localeCompare(t)}}},He=function(e){var t=[];for(var n in e){var r=e[n];void 0!==r&&""!==r&&t.push([n,"=",encodeURIComponent(r).replace(/%20/g,"+")].join(""))}return t.join("&")},Ke=function(e,t,n){return!!$()(n,(function(n){return re()(e[n],t[n])}))};function Ze(e){return"string"!=typeof e||""===e?"":(0,W.sanitizeUrl)(e)}function Ge(e){return!(!e||j()(e).call(e,"localhost")>=0||j()(e).call(e,"127.0.0.1")>=0||"none"===e)}function Ye(e){if(!F().OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;var t=D()(e).call(e,(function(e,t){return U()(t).call(t,"2")&&C()(e.get("content")||{}).length>0})),n=e.get("default")||F().OrderedMap(),r=(n.get("content")||F().OrderedMap()).keySeq().toJS().length?n:null;return t||r}var Xe=function(e){return"string"==typeof e||e instanceof String?B()(e).call(e).replace(/\s/g,"%20"):""},Qe=function(e){return ce()(Xe(e).replace(/%20/g,"_"))},$e=function(e){return S()(e).call(e,(function(e,t){return/^x-/.test(t)}))},et=function(e){return S()(e).call(e,(function(e,t){return/^pattern|maxLength|minLength|maximum|minimum/.test(t)}))};function tt(e,t){var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){return!0};if("object"!==s()(e)||u()(e)||null===e||!t)return e;var a=A()({},e);return y()(n=C()(a)).call(n,(function(e){e===t&&r(a[e],e)?delete a[e]:a[e]=tt(a[e],t,r)})),a}function nt(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"===s()(e)&&null!==e)try{return O()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function rt(e){return"number"==typeof e?e.toString():e}function at(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.returnAll,r=void 0!==n&&n,a=t.allowHashes,o=void 0===a||a;if(!F().Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");var s,l,i,c=e.get("name"),u=e.get("in"),p=[];e&&e.hashCode&&u&&c&&o&&p.push(g()(s=g()(l="".concat(u,".")).call(l,c,".hash-")).call(s,e.hashCode()));u&&c&&p.push(g()(i="".concat(u,".")).call(i,c));return p.push(c),r?p:p[0]||""}function ot(e,t){var n,r=at(e,{returnAll:!0});return S()(n=d()(r).call(r,(function(e){return t[e]}))).call(n,(function(e){return void 0!==e}))[0]}function st(){return it(de()(32).toString("base64"))}function lt(e){return it(he()("sha256").update(e).digest("base64"))}function it(e){return e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}var ct=function(e){return!e||!(!Ee(e)||!e.isEmpty())}},2518:(e,t,n)=>{"use strict";function r(e){return function(e){try{return!!JSON.parse(e)}catch(e){return null}}(e)?"json":null}n.d(t,{O:()=>r})},7504:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=function(){var e={location:{},history:{},open:function(){},close:function(){},File:function(){}};if("undefined"==typeof window)return e;try{e=window;for(var t=0,n=["File","Blob","FormData"];t{"use strict";n.d(t,{Z:()=>u});var r=n(9998),a=n.n(r),o=n(2605),s=n.n(o),l=n(5572),i=n.n(l),c=i().Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function u(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.isOAS3;if(!i().Map.isMap(e))return{schema:i().Map(),parameterContentMediaType:null};if(!n)return"body"===e.get("in")?{schema:e.get("schema",i().Map()),parameterContentMediaType:null}:{schema:a()(e).call(e,(function(e,t){return s()(c).call(c,t)})),parameterContentMediaType:null};if(e.get("content")){var r=e.get("content",i().Map({})).keySeq(),o=r.first();return{schema:e.getIn(["content",o,"schema"],i().Map()),parameterContentMediaType:o}}return{schema:e.get("schema",i().Map()),parameterContentMediaType:null}}},7156:(e,t,n)=>{"use strict";n.d(t,{Z:()=>j});var r=n(6349),a=n.n(r),o=n(4606),s=n.n(o);const l=require("@babel/runtime-corejs3/helpers/get");var i=n.n(l);const c=require("@babel/runtime-corejs3/helpers/getPrototypeOf");var u=n.n(c),p=n(4291),d=n.n(p),m=n(1885),h=n.n(m);const f=require("@babel/runtime-corejs3/helpers/wrapNativeSuper");var g=n.n(f),v=n(7104),y=n.n(v),E=n(7834),S=n.n(E),b=n(1733),C=n.n(b),x=n(874),w=n.n(x),_=n(3580),A=n.n(_);const k=require("@babel/runtime-corejs3/core-js-stable/instance/find-index");var N=n.n(k),I=n(2611),q=n.n(I),R=n(541),P=n.n(R),T=function(e){return function(t){return y()(e)&&y()(t)&&e.length===t.length&&S()(e).call(e,(function(e,n){return e===t[n]}))}},O=function(){for(var e=arguments.length,t=new Array(e),n=0;n1&&void 0!==arguments[1]?arguments[1]:O,n=P().Cache;P().Cache=M;var r=P()(e,t);return P().Cache=n,r}},5102:(e,t,n)=>{var r={"./all.js":5308,"./auth/actions.js":5812,"./auth/index.js":3705,"./auth/reducers.js":3962,"./auth/selectors.js":35,"./auth/spec-wrap-actions.js":8302,"./configs/actions.js":714,"./configs/helpers.js":2256,"./configs/index.js":1661,"./configs/reducers.js":7743,"./configs/selectors.js":9018,"./configs/spec-actions.js":2698,"./deep-linking/helpers.js":1970,"./deep-linking/index.js":4980,"./deep-linking/layout.js":2179,"./deep-linking/operation-tag-wrapper.jsx":4584,"./deep-linking/operation-wrapper.jsx":877,"./download-url.js":8011,"./err/actions.js":4966,"./err/error-transformers/hook.js":2860,"./err/error-transformers/transformers/not-of-type.js":2392,"./err/error-transformers/transformers/parameter-oneof.js":1835,"./err/index.js":7793,"./err/reducers.js":3527,"./err/selectors.js":7667,"./filter/index.js":9978,"./filter/opsFilter.js":4309,"./layout/actions.js":5474,"./layout/index.js":6821,"./layout/reducers.js":5672,"./layout/selectors.js":4400,"./layout/spec-extensions/wrap-selector.js":8989,"./logs/index.js":9150,"./oas3/actions.js":7002,"./oas3/auth-extensions/wrap-selectors.js":3723,"./oas3/components/callbacks.jsx":3427,"./oas3/components/http-auth.jsx":6775,"./oas3/components/index.js":6467,"./oas3/components/operation-link.jsx":5757,"./oas3/components/operation-servers.jsx":6796,"./oas3/components/request-body-editor.jsx":5327,"./oas3/components/request-body.jsx":2458,"./oas3/components/servers-container.jsx":9928,"./oas3/components/servers.jsx":6617,"./oas3/helpers.jsx":7779,"./oas3/index.js":7451,"./oas3/reducers.js":5013,"./oas3/selectors.js":5065,"./oas3/spec-extensions/selectors.js":1741,"./oas3/spec-extensions/wrap-selectors.js":2044,"./oas3/wrap-components/auth-item.jsx":356,"./oas3/wrap-components/index.js":7761,"./oas3/wrap-components/json-schema-string.jsx":287,"./oas3/wrap-components/markdown.jsx":2460,"./oas3/wrap-components/model.jsx":3499,"./oas3/wrap-components/online-validator-badge.js":58,"./oas3/wrap-components/version-stamp.jsx":9487,"./on-complete/index.js":8560,"./request-snippets/fn.js":8223,"./request-snippets/index.js":6575,"./request-snippets/request-snippets.jsx":4206,"./request-snippets/selectors.js":4669,"./safe-render/components/error-boundary.jsx":6195,"./safe-render/components/fallback.jsx":9403,"./safe-render/fn.jsx":6189,"./safe-render/index.js":9595,"./samples/fn.js":4128,"./samples/index.js":8883,"./spec/actions.js":7960,"./spec/index.js":7038,"./spec/reducers.js":32,"./spec/selectors.js":3881,"./spec/wrap-actions.js":7508,"./swagger-js/configs-wrap-actions.js":4852,"./swagger-js/index.js":8901,"./util/index.js":8525,"./view/fn.js":8347,"./view/index.js":3420,"./view/root-injects.jsx":290,"core/plugins/all.js":5308,"core/plugins/auth/actions.js":5812,"core/plugins/auth/index.js":3705,"core/plugins/auth/reducers.js":3962,"core/plugins/auth/selectors.js":35,"core/plugins/auth/spec-wrap-actions.js":8302,"core/plugins/configs/actions.js":714,"core/plugins/configs/helpers.js":2256,"core/plugins/configs/index.js":1661,"core/plugins/configs/reducers.js":7743,"core/plugins/configs/selectors.js":9018,"core/plugins/configs/spec-actions.js":2698,"core/plugins/deep-linking/helpers.js":1970,"core/plugins/deep-linking/index.js":4980,"core/plugins/deep-linking/layout.js":2179,"core/plugins/deep-linking/operation-tag-wrapper.jsx":4584,"core/plugins/deep-linking/operation-wrapper.jsx":877,"core/plugins/download-url.js":8011,"core/plugins/err/actions.js":4966,"core/plugins/err/error-transformers/hook.js":2860,"core/plugins/err/error-transformers/transformers/not-of-type.js":2392,"core/plugins/err/error-transformers/transformers/parameter-oneof.js":1835,"core/plugins/err/index.js":7793,"core/plugins/err/reducers.js":3527,"core/plugins/err/selectors.js":7667,"core/plugins/filter/index.js":9978,"core/plugins/filter/opsFilter.js":4309,"core/plugins/layout/actions.js":5474,"core/plugins/layout/index.js":6821,"core/plugins/layout/reducers.js":5672,"core/plugins/layout/selectors.js":4400,"core/plugins/layout/spec-extensions/wrap-selector.js":8989,"core/plugins/logs/index.js":9150,"core/plugins/oas3/actions.js":7002,"core/plugins/oas3/auth-extensions/wrap-selectors.js":3723,"core/plugins/oas3/components/callbacks.jsx":3427,"core/plugins/oas3/components/http-auth.jsx":6775,"core/plugins/oas3/components/index.js":6467,"core/plugins/oas3/components/operation-link.jsx":5757,"core/plugins/oas3/components/operation-servers.jsx":6796,"core/plugins/oas3/components/request-body-editor.jsx":5327,"core/plugins/oas3/components/request-body.jsx":2458,"core/plugins/oas3/components/servers-container.jsx":9928,"core/plugins/oas3/components/servers.jsx":6617,"core/plugins/oas3/helpers.jsx":7779,"core/plugins/oas3/index.js":7451,"core/plugins/oas3/reducers.js":5013,"core/plugins/oas3/selectors.js":5065,"core/plugins/oas3/spec-extensions/selectors.js":1741,"core/plugins/oas3/spec-extensions/wrap-selectors.js":2044,"core/plugins/oas3/wrap-components/auth-item.jsx":356,"core/plugins/oas3/wrap-components/index.js":7761,"core/plugins/oas3/wrap-components/json-schema-string.jsx":287,"core/plugins/oas3/wrap-components/markdown.jsx":2460,"core/plugins/oas3/wrap-components/model.jsx":3499,"core/plugins/oas3/wrap-components/online-validator-badge.js":58,"core/plugins/oas3/wrap-components/version-stamp.jsx":9487,"core/plugins/on-complete/index.js":8560,"core/plugins/request-snippets/fn.js":8223,"core/plugins/request-snippets/index.js":6575,"core/plugins/request-snippets/request-snippets.jsx":4206,"core/plugins/request-snippets/selectors.js":4669,"core/plugins/safe-render/components/error-boundary.jsx":6195,"core/plugins/safe-render/components/fallback.jsx":9403,"core/plugins/safe-render/fn.jsx":6189,"core/plugins/safe-render/index.js":9595,"core/plugins/samples/fn.js":4128,"core/plugins/samples/index.js":8883,"core/plugins/spec/actions.js":7960,"core/plugins/spec/index.js":7038,"core/plugins/spec/reducers.js":32,"core/plugins/spec/selectors.js":3881,"core/plugins/spec/wrap-actions.js":7508,"core/plugins/swagger-js/configs-wrap-actions.js":4852,"core/plugins/swagger-js/index.js":8901,"core/plugins/util/index.js":8525,"core/plugins/view/fn.js":8347,"core/plugins/view/index.js":3420,"core/plugins/view/root-injects.jsx":290};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=5102},2517:e=>{"use strict";e.exports="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwcHgiICBoZWlnaHQ9IjIwMHB4IiAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQiIGNsYXNzPSJsZHMtcm9sbGluZyIgc3R5bGU9ImJhY2tncm91bmQtaW1hZ2U6IG5vbmU7IGJhY2tncm91bmQtcG9zaXRpb246IGluaXRpYWwgaW5pdGlhbDsgYmFja2dyb3VuZC1yZXBlYXQ6IGluaXRpYWwgaW5pdGlhbDsiPjxjaXJjbGUgY3g9IjUwIiBjeT0iNTAiIGZpbGw9Im5vbmUiIG5nLWF0dHItc3Ryb2tlPSJ7e2NvbmZpZy5jb2xvcn19IiBuZy1hdHRyLXN0cm9rZS13aWR0aD0ie3tjb25maWcud2lkdGh9fSIgbmctYXR0ci1yPSJ7e2NvbmZpZy5yYWRpdXN9fSIgbmctYXR0ci1zdHJva2UtZGFzaGFycmF5PSJ7e2NvbmZpZy5kYXNoYXJyYXl9fSIgc3Ryb2tlPSIjNTU1NTU1IiBzdHJva2Utd2lkdGg9IjEwIiByPSIzNSIgc3Ryb2tlLWRhc2hhcnJheT0iMTY0LjkzMzYxNDMxMzQ2NDE1IDU2Ljk3Nzg3MTQzNzgyMTM4Ij48YW5pbWF0ZVRyYW5zZm9ybSBhdHRyaWJ1dGVOYW1lPSJ0cmFuc2Zvcm0iIHR5cGU9InJvdGF0ZSIgY2FsY01vZGU9ImxpbmVhciIgdmFsdWVzPSIwIDUwIDUwOzM2MCA1MCA1MCIga2V5VGltZXM9IjA7MSIgZHVyPSIxcyIgYmVnaW49IjBzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSI+PC9hbmltYXRlVHJhbnNmb3JtPjwvY2lyY2xlPjwvc3ZnPgo="},5163:e=>{"use strict";e.exports='---\nurl: "https://petstore.swagger.io/v2/swagger.json"\ndom_id: "#swagger-ui"\nvalidatorUrl: "https://validator.swagger.io/validator"\n'},1733:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/array/from")},7104:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/array/is-array")},593:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/bind")},4883:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/concat")},7862:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/entries")},7834:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/every")},9998:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/filter")},3580:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/find")},4235:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/for-each")},2605:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/includes")},8493:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/index-of")},874:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/keys")},3942:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/map")},66:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/reduce")},600:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/slice")},5626:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/some")},9247:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/sort")},3262:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/starts-with")},7390:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/instance/trim")},8344:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/json/stringify")},2611:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/map")},4994:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/object/assign")},7252:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/object/keys")},9968:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/object/values")},9300:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/set-timeout")},9478:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/core-js-stable/url")},4555:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/assertThisInitialized")},6349:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/classCallCheck")},4606:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/createClass")},1771:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/createForOfIteratorHelper")},1885:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/createSuper")},1093:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/defineProperty")},4250:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/extends")},4291:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/inherits")},67:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/objectSpread2")},5579:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/objectWithoutProperties")},8030:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/slicedToArray")},6731:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/toConsumableArray")},6768:e=>{"use strict";e.exports=require("@babel/runtime-corejs3/helpers/typeof")},871:e=>{"use strict";e.exports=require("buffer")},9003:e=>{"use strict";e.exports=require("classnames")},5572:e=>{"use strict";e.exports=require("immutable")},9793:e=>{"use strict";e.exports=require("js-yaml")},1712:e=>{"use strict";e.exports=require("lodash/get")},5716:e=>{"use strict";e.exports=require("lodash/isFunction")},541:e=>{"use strict";e.exports=require("lodash/memoize")},580:e=>{"use strict";e.exports=require("prop-types")},185:e=>{"use strict";e.exports=require("randombytes")},6689:e=>{"use strict";e.exports=require("react")},2807:e=>{"use strict";e.exports=require("react-copy-to-clipboard")},8082:e=>{"use strict";e.exports=require("react-immutable-proptypes")},6695:e=>{"use strict";e.exports=require("redux")},963:e=>{"use strict";e.exports=require("remarkable")},6814:e=>{"use strict";e.exports=require("reselect")},41:e=>{"use strict";e.exports=require("serialize-error")},6765:e=>{"use strict";e.exports=require("swagger-client/es/helpers")},3883:e=>{"use strict";e.exports=require("url-parse")}},t={};function n(r){var a=t[r];if(void 0!==a)return a.exports;var o=t[r]={exports:{}};return e[r](o,o.exports,n),o.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var r={};return(()=>{"use strict";n.d(r,{default:()=>Wr});var e={};n.r(e),n.d(e,{Button:()=>Rn,Col:()=>In,Collapse:()=>Vn,Container:()=>kn,Input:()=>Tn,Link:()=>Mn,Row:()=>qn,Select:()=>On,TextArea:()=>Pn});var t={};n.r(t),n.d(t,{JsonSchemaArrayItemFile:()=>Rr,JsonSchemaArrayItemText:()=>qr,JsonSchemaForm:()=>kr,JsonSchema_array:()=>Ir,JsonSchema_boolean:()=>Pr,JsonSchema_object:()=>Or,JsonSchema_string:()=>Nr});var a=n(6768),o=n.n(a),s=n(4883),l=n.n(s);const i=require("@babel/runtime-corejs3/core-js-stable/instance/last-index-of");var c=n.n(i),u=n(9998),p=n.n(u),d=n(7252),m=n.n(d),h=n(8344),f=n.n(h);const g=require("deep-extend");var v=n.n(g),y=n(1093),E=n.n(y),S=n(6349),b=n.n(S),C=n(4606),x=n.n(C),w=n(593),_=n.n(w),A=n(4994),k=n.n(A),N=n(600),I=n.n(N),q=n(7104),R=n.n(q),P=n(66),T=n.n(P),O=n(3942),M=n.n(O),j=n(6689),V=n.n(j),D=n(6695),L=n(5572),U=n.n(L);const z=require("redux-immutable");var B=n(41);const J=require("lodash/merge");var F=n.n(J),W=n(4966),H=n(7504),K=n(1890),Z=function(e){return e};var G=function(){function e(){var t,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};b()(this,e),v()(this,{state:{},plugins:[],pluginsOptions:{},system:{configs:{},fn:{},components:{},rootInjects:{},statePlugins:{}},boundSystem:{},toolbox:{}},n),this.getSystem=_()(t=this._getSystem).call(t,this),this.store=ee(Z,(0,L.fromJS)(this.state),this.getSystem),this.buildSystem(!1),this.register(this.plugins)}return x()(e,[{key:"getStore",value:function(){return this.store}},{key:"register",value:function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],n=Y(e,this.getSystem(),this.pluginsOptions);Q(this.system,n),t&&this.buildSystem();var r=X.call(this.system,e,this.getSystem());r&&this.buildSystem()}},{key:"buildSystem",value:function(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=this.getStore().dispatch,n=this.getStore().getState;this.boundSystem=k()({},this.getRootInjects(),this.getWrappedAndBoundActions(t),this.getWrappedAndBoundSelectors(n,this.getSystem),this.getStateThunks(n),this.getFn(),this.getConfigs()),e&&this.rebuildReducer()}},{key:"_getSystem",value:function(){return this.boundSystem}},{key:"getRootInjects",value:function(){var e,t,n;return k()({getSystem:this.getSystem,getStore:_()(e=this.getStore).call(e,this),getComponents:_()(t=this.getComponents).call(t,this),getState:this.getStore().getState,getConfigs:_()(n=this._getConfigs).call(n,this),Im:U(),React:V()},this.system.rootInjects||{})}},{key:"_getConfigs",value:function(){return this.system.configs}},{key:"getConfigs",value:function(){return{configs:this.system.configs}}},{key:"setConfigs",value:function(e){this.system.configs=e}},{key:"rebuildReducer",value:function(){var e,t,n,r;this.store.replaceReducer((r=this.system.statePlugins,e=(0,K.Ay)(r,(function(e){return e.reducers})),n=T()(t=m()(e)).call(t,(function(t,n){return t[n]=function(e){return function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:new L.Map,n=arguments.length>1?arguments[1]:void 0;if(!e)return t;var r=e[n.type];if(r){var a=$(r)(t,n);return null===a?t:a}return t}}(e[n]),t}),{}),m()(n).length?(0,z.combineReducers)(n):Z))}},{key:"getType",value:function(e){var t=e[0].toUpperCase()+I()(e).call(e,1);return(0,K.Q2)(this.system.statePlugins,(function(n,r){var a=n[e];if(a)return E()({},r+t,a)}))}},{key:"getSelectors",value:function(){return this.getType("selectors")}},{key:"getActions",value:function(){var e=this.getType("actions");return(0,K.Ay)(e,(function(e){return(0,K.Q2)(e,(function(e,t){if((0,K.LQ)(e))return E()({},t,e)}))}))}},{key:"getWrappedAndBoundActions",value:function(e){var t=this,n=this.getBoundActions(e);return(0,K.Ay)(n,(function(e,n){var r=t.system.statePlugins[I()(n).call(n,0,-7)].wrapActions;return r?(0,K.Ay)(e,(function(e,n){var a=r[n];return a?(R()(a)||(a=[a]),T()(a).call(a,(function(e,n){var r=function(){return n(e,t.getSystem()).apply(void 0,arguments)};if(!(0,K.LQ)(r))throw new TypeError("wrapActions needs to return a function that returns a new function (ie the wrapped action)");return $(r)}),e||Function.prototype)):e})):e}))}},{key:"getWrappedAndBoundSelectors",value:function(e,t){var n=this,r=this.getBoundSelectors(e,t);return(0,K.Ay)(r,(function(t,r){var a=[I()(r).call(r,0,-9)],o=n.system.statePlugins[a].wrapSelectors;return o?(0,K.Ay)(t,(function(t,r){var s=o[r];return s?(R()(s)||(s=[s]),T()(s).call(s,(function(t,r){var o=function(){for(var o,s=arguments.length,i=new Array(s),c=0;c2&&void 0!==arguments[2]?arguments[2]:{},a=r.hasLoaded,o=a;return(0,K.Kn)(e)&&!(0,K.kJ)(e)&&"function"==typeof e.afterLoad&&(o=!0,$(e.afterLoad).call(this,t)),(0,K.Wl)(e)?X.call(this,e(t),t,{hasLoaded:o}):(0,K.kJ)(e)?M()(e).call(e,(function(e){return X.call(n,e,t,{hasLoaded:o})})):o}function Q(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!(0,K.Kn)(e))return{};if(!(0,K.Kn)(t))return e;t.wrapComponents&&((0,K.Ay)(t.wrapComponents,(function(n,r){var a=e.components&&e.components[r];a&&R()(a)?(e.components[r]=l()(a).call(a,[n]),delete t.wrapComponents[r]):a&&(e.components[r]=[a,n],delete t.wrapComponents[r])})),m()(t.wrapComponents).length||delete t.wrapComponents);var n=e.statePlugins;if((0,K.Kn)(n))for(var r in n){var a=n[r];if((0,K.Kn)(a)){var o=a.wrapActions,s=a.wrapSelectors;if((0,K.Kn)(o))for(var i in o){var c,u=o[i];if(R()(u)||(u=[u],o[i]=u),t&&t.statePlugins&&t.statePlugins[r]&&t.statePlugins[r].wrapActions&&t.statePlugins[r].wrapActions[i])t.statePlugins[r].wrapActions[i]=l()(c=o[i]).call(c,t.statePlugins[r].wrapActions[i])}if((0,K.Kn)(s))for(var p in s){var d,h=s[p];if(R()(h)||(h=[h],s[p]=h),t&&t.statePlugins&&t.statePlugins[r]&&t.statePlugins[r].wrapSelectors&&t.statePlugins[r].wrapSelectors[p])t.statePlugins[r].wrapSelectors[p]=l()(d=s[p]).call(d,t.statePlugins[r].wrapSelectors[p])}}}return v()(e,t)}function $(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=t.logErrors,r=void 0===n||n;return"function"!=typeof e?e:function(){try{for(var t,n=arguments.length,a=new Array(n),o=0;o=0&&(void 0===t.allowTryItOut?t.specSelectors.allowTryItOutFor(t.path,t.method):t.allowTryItOut),v=r.getIn(["operation","security"])||t.specSelectors.security();return{operationId:m,isDeepLinkingEnabled:f,showSummary:d,displayOperationId:c,displayRequestDuration:u,allowTryItOut:g,security:v,isAuthorized:t.authSelectors.isAuthorized(v),isShown:a.isShown(h,"full"===s),jumpToKey:l()(n="paths.".concat(t.path,".")).call(n,t.method),response:t.specSelectors.responseFor(t.path,t.method),request:t.specSelectors.requestFor(t.path,t.method)}}},{key:"componentDidMount",value:function(){var e=this.props.isShown,t=this.getResolvedSubtree();e&&void 0===t&&this.requestResolvedSubtree()}},{key:"UNSAFE_componentWillReceiveProps",value:function(e){var t=e.response,n=e.isShown,r=this.getResolvedSubtree();t!==this.props.response&&this.setState({executeInProgress:!1}),n&&void 0===r&&this.requestResolvedSubtree()}},{key:"render",value:function(){var e=this.props,t=e.op,n=e.tag,r=e.path,a=e.method,o=e.security,s=e.isAuthorized,l=e.operationId,i=e.showSummary,c=e.isShown,u=e.jumpToKey,p=e.allowTryItOut,d=e.response,m=e.request,h=e.displayOperationId,f=e.displayRequestDuration,g=e.isDeepLinkingEnabled,v=e.specPath,y=e.specSelectors,E=e.specActions,S=e.getComponent,b=e.getConfigs,C=e.layoutSelectors,x=e.layoutActions,w=e.authActions,_=e.authSelectors,A=e.oas3Actions,k=e.oas3Selectors,N=e.fn,I=S("operation"),q=this.getResolvedSubtree()||(0,L.Map)(),R=(0,L.fromJS)({op:q,tag:n,path:r,summary:t.getIn(["operation","summary"])||"",deprecated:q.get("deprecated")||t.getIn(["operation","deprecated"])||!1,method:a,security:o,isAuthorized:s,operationId:l,originalOperationId:q.getIn(["operation","__originalOperationId"]),showSummary:i,isShown:c,jumpToKey:u,allowTryItOut:p,request:m,displayOperationId:h,displayRequestDuration:f,isDeepLinkingEnabled:g,executeInProgress:this.state.executeInProgress,tryItOutEnabled:this.state.tryItOutEnabled});return V().createElement(I,{operation:R,response:d,request:m,isShown:c,toggleShown:this.toggleShown,onTryoutClick:this.onTryoutClick,onCancelClick:this.onCancelClick,onExecute:this.onExecute,specPath:v,specActions:E,specSelectors:y,oas3Actions:A,oas3Selectors:k,layoutActions:x,layoutSelectors:C,authActions:w,authSelectors:_,getComponent:S,getConfigs:b,fn:N})}}]),n}(j.PureComponent);E()(Ae,"defaultProps",{showSummary:!0,response:null,allowTryItOut:!0,displayOperationId:!1,displayRequestDuration:!1});var ke=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"getLayout",value:function(){var e=this.props,t=e.getComponent,n=e.layoutSelectors.current(),r=t(n,!0);return r||function(){return V().createElement("h1",null,' No layout defined for "',n,'" ')}}},{key:"render",value:function(){var e=this.getLayout();return V().createElement(e,null)}}]),n}(V().Component);ke.defaultProps={};var Ne=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s1&&void 0!==arguments[1]?arguments[1]:{},n=t.isSyntheticChange,a=void 0!==n&&n;"function"==typeof r.props.onSelect&&r.props.onSelect(e,{isSyntheticChange:a})})),E()(ye()(r),"_onDomSelect",(function(e){if("function"==typeof r.props.onSelect){var t=e.target.selectedOptions[0].getAttribute("value");r._onSelect(t,{isSyntheticChange:!1})}})),E()(ye()(r),"getCurrentExample",(function(){var e=r.props,t=e.examples,n=e.currentExampleKey,a=t.get(n),o=t.keySeq().first(),s=t.get(o);return a||s||Le()({})})),r}return x()(n,[{key:"componentDidMount",value:function(){var e=this.props,t=e.onSelect,n=e.examples;if("function"==typeof t){var r=n.first(),a=n.keyOf(r);this._onSelect(a,{isSyntheticChange:!0})}}},{key:"UNSAFE_componentWillReceiveProps",value:function(e){var t=e.currentExampleKey,n=e.examples;if(n!==this.props.examples&&!n.has(t)){var r=n.first(),a=n.keyOf(r);this._onSelect(a,{isSyntheticChange:!0})}}},{key:"render",value:function(){var e=this.props,t=e.examples,n=e.currentExampleKey,r=e.isValueModified,a=e.isModifiedValueAvailable,o=e.showLabels;return V().createElement("div",{className:"examples-select"},o?V().createElement("span",{className:"examples-select__section-label"},"Examples: "):null,V().createElement("select",{className:"examples-select-element",onChange:this._onDomSelect,value:a&&r?"__MODIFIED__VALUE__":n||""},a?V().createElement("option",{value:"__MODIFIED__VALUE__"},"[Modified value]"):null,M()(t).call(t,(function(e,t){return V().createElement("option",{key:t,value:t},e.get("summary")||t)})).valueSeq()))}}]),n}(V().PureComponent);E()(Ue,"defaultProps",{examples:U().Map({}),onSelect:function(){for(var e,t,n=arguments.length,r=new Array(n),a=0;a1&&void 0!==arguments[1]?arguments[1]:{},n=t.isSyntheticChange,a=r.props,o=a.onSelect,s=a.updateValue,i=a.currentUserInputValue,c=a.userHasEditedBody,u=r._getStateForCurrentNamespace(),p=u.lastUserEditedValue,d=r._getValueForExample(e);if("__MODIFIED__VALUE__"===e)return s(ze(p)),r._setStateForCurrentNamespace({isModifiedValueSelected:!0});if("function"==typeof o){for(var m,h=arguments.length,f=new Array(h>2?h-2:0),g=2;g-1){var u;a.setState({scopes:p()(u=a.state.scopes).call(u,(function(e){return e!==s}))})}})),E()(ye()(a),"onInputChange",(function(e){var t=e.target,n=t.dataset.name,r=t.value,o=E()({},n,r);a.setState(o)})),E()(ye()(a),"selectScopes",(function(e){var t;e.target.dataset.all?a.setState({scopes:Fe()(He()(t=a.props.schema.get("allowedScopes")||a.props.schema.get("scopes")).call(t))}):a.setState({scopes:[]})})),E()(ye()(a),"logout",(function(e){e.preventDefault();var t=a.props,n=t.authActions,r=t.errActions,o=t.name;r.clear({authId:o,type:"auth",source:"auth"}),n.logoutWithPersistOption([o])}));var o=a.props,s=o.name,i=o.schema,c=o.authorized,u=o.authSelectors,d=c&&c.get(s),m=u.getConfigs()||{},h=d&&d.get("username")||"",f=d&&d.get("clientId")||m.clientId||"",g=d&&d.get("clientSecret")||m.clientSecret||"",v=d&&d.get("passwordType")||"basic",y=d&&d.get("scopes")||m.scopes||[];return"string"==typeof y&&(y=y.split(m.scopeSeparator||" ")),a.state={appName:m.appName,name:s,schema:i,scopes:y,clientId:f,clientSecret:g,username:h,password:"",passwordType:v},a}return x()(n,[{key:"render",value:function(){var e,t,n=this,r=this.props,a=r.schema,o=r.getComponent,s=r.authSelectors,i=r.errSelectors,c=r.name,u=r.specSelectors,d=o("Input"),m=o("Row"),h=o("Col"),f=o("Button"),g=o("authError"),v=o("JumpToPath",!0),y=o("Markdown",!0),E=o("InitializedInput"),S=u.isOAS3,b=S()?a.get("openIdConnectUrl"):null,C="implicit",x="password",w=S()?b?"authorization_code":"authorizationCode":"accessCode",_=S()?b?"client_credentials":"clientCredentials":"application",A=!!(s.getConfigs()||{}).usePkceWithAuthorizationCodeGrant,k=a.get("flow"),N=k===w&&A?k+" with PKCE":k,I=a.get("allowedScopes")||a.get("scopes"),q=!!s.authorized().get(c),R=p()(e=i.allErrors()).call(e,(function(e){return e.get("authId")===c})),P=!p()(R).call(R,(function(e){return"validation"===e.get("source")})).size,T=a.get("description");return V().createElement("div",null,V().createElement("h4",null,c," (OAuth2, ",N,") ",V().createElement(v,{path:["securityDefinitions",c]})),this.state.appName?V().createElement("h5",null,"Application: ",this.state.appName," "):null,T&&V().createElement(y,{source:a.get("description")}),q&&V().createElement("h6",null,"Authorized"),b&&V().createElement("p",null,"OpenID Connect URL: ",V().createElement("code",null,b)),(k===C||k===w)&&V().createElement("p",null,"Authorization URL: ",V().createElement("code",null,a.get("authorizationUrl"))),(k===x||k===w||k===_)&&V().createElement("p",null,"Token URL:",V().createElement("code",null," ",a.get("tokenUrl"))),V().createElement("p",{className:"flow"},"Flow: ",V().createElement("code",null,N)),k!==x?null:V().createElement(m,null,V().createElement(m,null,V().createElement("label",{htmlFor:"oauth_username"},"username:"),q?V().createElement("code",null," ",this.state.username," "):V().createElement(h,{tablet:10,desktop:10},V().createElement("input",{id:"oauth_username",type:"text","data-name":"username",onChange:this.onInputChange,autoFocus:!0}))),V().createElement(m,null,V().createElement("label",{htmlFor:"oauth_password"},"password:"),q?V().createElement("code",null," ****** "):V().createElement(h,{tablet:10,desktop:10},V().createElement("input",{id:"oauth_password",type:"password","data-name":"password",onChange:this.onInputChange}))),V().createElement(m,null,V().createElement("label",{htmlFor:"password_type"},"Client credentials location:"),q?V().createElement("code",null," ",this.state.passwordType," "):V().createElement(h,{tablet:10,desktop:10},V().createElement("select",{id:"password_type","data-name":"passwordType",onChange:this.onInputChange},V().createElement("option",{value:"basic"},"Authorization header"),V().createElement("option",{value:"request-body"},"Request body"))))),(k===_||k===C||k===w||k===x)&&(!q||q&&this.state.clientId)&&V().createElement(m,null,V().createElement("label",{htmlFor:"client_id"},"client_id:"),q?V().createElement("code",null," ****** "):V().createElement(h,{tablet:10,desktop:10},V().createElement(E,{id:"client_id",type:"text",required:k===x,initialValue:this.state.clientId,"data-name":"clientId",onChange:this.onInputChange}))),(k===_||k===w||k===x)&&!A&&V().createElement(m,null,V().createElement("label",{htmlFor:"client_secret"},"client_secret:"),q?V().createElement("code",null," ****** "):V().createElement(h,{tablet:10,desktop:10},V().createElement(E,{id:"client_secret",initialValue:this.state.clientSecret,type:"password","data-name":"clientSecret",onChange:this.onInputChange}))),!q&&I&&I.size?V().createElement("div",{className:"scopes"},V().createElement("h2",null,"Scopes:",V().createElement("a",{onClick:this.selectScopes,"data-all":!0},"select all"),V().createElement("a",{onClick:this.selectScopes},"select none")),M()(I).call(I,(function(e,t){var r,a,o,s,i;return V().createElement(m,{key:t},V().createElement("div",{className:"checkbox"},V().createElement(d,{"data-value":t,id:l()(r=l()(a="".concat(t,"-")).call(a,k,"-checkbox-")).call(r,n.state.name),disabled:q,checked:Ze()(o=n.state.scopes).call(o,t),type:"checkbox",onChange:n.onScopeChange}),V().createElement("label",{htmlFor:l()(s=l()(i="".concat(t,"-")).call(i,k,"-checkbox-")).call(s,n.state.name)},V().createElement("span",{className:"item"}),V().createElement("div",{className:"text"},V().createElement("p",{className:"name"},t),V().createElement("p",{className:"description"},e)))))})).toArray()):null,M()(t=R.valueSeq()).call(t,(function(e,t){return V().createElement(g,{error:e,key:t})})),V().createElement("div",{className:"auth-btn-wrapper"},P&&(q?V().createElement(f,{className:"btn modal-btn auth authorize",onClick:this.logout},"Logout"):V().createElement(f,{className:"btn modal-btn auth authorize",onClick:this.authorize},"Authorize")),V().createElement(f,{className:"btn modal-btn auth btn-done",onClick:this.close},"Close")))}}]),n}(V().Component),Qe=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s2&&void 0!==arguments[2]?arguments[2]:{},r=n.selectedServer,a=void 0===r?"":r;if(e){if(it(e))return e;var o=ct(a,t);return it(o)?new(lt())(e,o).href:new(lt())(e,window.location.href).href}}function pt(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=n.selectedServer,a=void 0===r?"":r;try{return ut(e,t,{selectedServer:a})}catch(e){return}}var dt=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t=this.props,n=t.tagObj,r=t.tag,a=t.children,o=t.oas3Selectors,s=t.layoutSelectors,l=t.layoutActions,i=t.getConfigs,c=t.getComponent,u=t.specUrl,p=i(),d=p.docExpansion,m=p.deepLinking,h=m&&"false"!==m,f=c("Collapse"),g=c("Markdown",!0),v=c("DeepLink"),y=c("Link"),E=n.getIn(["tagDetails","description"],null),S=n.getIn(["tagDetails","externalDocs","description"]),b=n.getIn(["tagDetails","externalDocs","url"]);e=(0,K.Wl)(o)&&(0,K.Wl)(o.selectedServer)?pt(b,u,{selectedServer:o.selectedServer()}):b;var C=["operations-tag",r],x=s.isShown(C,"full"===d||"list"===d);return V().createElement("div",{className:x?"opblock-tag-section is-open":"opblock-tag-section"},V().createElement("h3",{onClick:function(){return l.show(C,!x)},className:E?"opblock-tag":"opblock-tag no-desc",id:M()(C).call(C,(function(e){return(0,K.J6)(e)})).join("-"),"data-tag":r,"data-is-open":x},V().createElement(v,{enabled:h,isShown:x,path:(0,K.oJ)(r),text:r}),E?V().createElement("small",null,V().createElement(g,{source:E})):V().createElement("small",null),S?V().createElement("div",{className:"info__externaldocs"},V().createElement("small",null,S,e?": ":null,e?V().createElement(y,{href:(0,K.Nm)(e),onClick:function(e){return e.stopPropagation()},target:"_blank"},e):null)):null,V().createElement("button",{"aria-expanded":x,className:"expand-operation",title:x?"Collapse operation":"Expand operation",onClick:function(){return l.show(C,!x)}},V().createElement("svg",{className:"arrow",width:"20",height:"20","aria-hidden":"true",focusable:"false"},V().createElement("use",{href:x?"#large-arrow-up":"#large-arrow-down",xlinkHref:x?"#large-arrow-up":"#large-arrow-down"})))),V().createElement(f,{isOpened:x},a))}}]),n}(V().Component);E()(dt,"defaultProps",{tagObj:U().fromJS({}),tag:""});var mt=function(e){Se()(r,e);var t=Ce()(r);function r(){return b()(this,r),t.apply(this,arguments)}return x()(r,[{key:"render",value:function(){var e=this.props,t=e.specPath,r=e.response,a=e.request,o=e.toggleShown,s=e.onTryoutClick,l=e.onCancelClick,i=e.onExecute,c=e.fn,u=e.getComponent,p=e.getConfigs,d=e.specActions,m=e.specSelectors,h=e.authActions,f=e.authSelectors,g=e.oas3Actions,v=e.oas3Selectors,y=this.props.operation,E=y.toJS(),S=E.deprecated,b=E.isShown,C=E.path,x=E.method,w=E.op,_=E.tag,A=E.operationId,k=E.allowTryItOut,N=E.displayRequestDuration,I=E.tryItOutEnabled,q=E.executeInProgress,R=w.description,P=w.externalDocs,T=w.schemes,O=P?pt(P.url,m.url(),{selectedServer:v.selectedServer()}):"",M=y.getIn(["op"]),j=M.get("responses"),D=(0,K.gp)(M,["parameters"]),L=m.operationScheme(C,x),U=["operations",_,A],z=(0,K.nX)(M),B=u("responses"),J=u("parameters"),F=u("execute"),W=u("clear"),H=u("Collapse"),Z=u("Markdown",!0),G=u("schemes"),Y=u("OperationServers"),X=u("OperationExt"),Q=u("OperationSummary"),$=u("Link"),ee=p().showExtensions;if(j&&r&&r.size>0){var te=!j.get(String(r.get("status")))&&!j.get("default");r=r.set("notDocumented",te)}var ne=[C,x];return V().createElement("div",{className:S?"opblock opblock-deprecated":b?"opblock opblock-".concat(x," is-open"):"opblock opblock-".concat(x),id:(0,K.J6)(U.join("-"))},V().createElement(Q,{operationProps:y,isShown:b,toggleShown:o,getComponent:u,authActions:h,authSelectors:f,specPath:t}),V().createElement(H,{isOpened:b},V().createElement("div",{className:"opblock-body"},M&&M.size||null===M?null:V().createElement("img",{height:"32px",width:"32px",src:n(2517),className:"opblock-loading-animation"}),S&&V().createElement("h4",{className:"opblock-title_normal"}," Warning: Deprecated"),R&&V().createElement("div",{className:"opblock-description-wrapper"},V().createElement("div",{className:"opblock-description"},V().createElement(Z,{source:R}))),O?V().createElement("div",{className:"opblock-external-docs-wrapper"},V().createElement("h4",{className:"opblock-title_normal"},"Find more details"),V().createElement("div",{className:"opblock-external-docs"},V().createElement("span",{className:"opblock-external-docs__description"},V().createElement(Z,{source:P.description})),V().createElement($,{target:"_blank",className:"opblock-external-docs__link",href:(0,K.Nm)(O)},O))):null,M&&M.size?V().createElement(J,{parameters:D,specPath:t.push("parameters"),operation:M,onChangeKey:ne,onTryoutClick:s,onCancelClick:l,tryItOutEnabled:I,allowTryItOut:k,fn:c,getComponent:u,specActions:d,specSelectors:m,pathMethod:[C,x],getConfigs:p,oas3Actions:g,oas3Selectors:v}):null,I?V().createElement(Y,{getComponent:u,path:C,method:x,operationServers:M.get("servers"),pathServers:m.paths().getIn([C,"servers"]),getSelectedServer:v.selectedServer,setSelectedServer:g.setSelectedServer,setServerVariableValue:g.setServerVariableValue,getServerVariable:v.serverVariableValue,getEffectiveServerValue:v.serverEffectiveValue}):null,I&&k&&T&&T.size?V().createElement("div",{className:"opblock-schemes"},V().createElement(G,{schemes:T,path:C,method:x,specActions:d,currentScheme:L})):null,V().createElement("div",{className:I&&r&&k?"btn-group":"execute-wrapper"},I&&k?V().createElement(F,{operation:M,specActions:d,specSelectors:m,oas3Selectors:v,oas3Actions:g,path:C,method:x,onExecute:i,disabled:q}):null,I&&r&&k?V().createElement(W,{specActions:d,path:C,method:x}):null),q?V().createElement("div",{className:"loading-container"},V().createElement("div",{className:"loading"})):null,j?V().createElement(B,{responses:j,request:a,tryItOutResponse:r,getComponent:u,getConfigs:p,specSelectors:m,oas3Actions:g,oas3Selectors:v,specActions:d,produces:m.producesOptionsFor([C,x]),producesValue:m.currentProducesFor([C,x]),specPath:t.push("responses"),path:C,method:x,displayRequestDuration:N,fn:c}):null,ee&&z.size?V().createElement(X,{extensions:z,getComponent:u}):null)))}}]),r}(j.PureComponent);E()(mt,"defaultProps",{operation:null,response:null,request:null,specPath:(0,L.List)(),summary:""});const ht=require("lodash/toString");var ft=n.n(ht),gt=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t=this.props,n=t.isShown,r=t.toggleShown,a=t.getComponent,o=t.authActions,s=t.authSelectors,i=t.operationProps,c=t.specPath,u=i.toJS(),p=u.summary,d=u.isAuthorized,m=u.method,h=u.op,f=u.showSummary,g=u.path,v=u.operationId,y=u.originalOperationId,E=u.displayOperationId,S=h.summary,b=i.get("security"),C=a("authorizeOperationBtn"),x=a("OperationSummaryMethod"),w=a("OperationSummaryPath"),_=a("JumpToPath",!0),A=b&&!!b.count(),k=A&&1===b.size&&b.first().isEmpty(),N=!A||k;return V().createElement("div",{className:"opblock-summary opblock-summary-".concat(m)},V().createElement("button",{"aria-label":l()(e="".concat(m," ")).call(e,g.replace(/\//g,"​/")),"aria-expanded":n,className:"opblock-summary-control",onClick:r},V().createElement(x,{method:m}),V().createElement(w,{getComponent:a,operationProps:i,specPath:c}),f?V().createElement("div",{className:"opblock-summary-description"},ft()(S||p)):null,E&&(y||v)?V().createElement("span",{className:"opblock-summary-operation-id"},y||v):null,V().createElement("svg",{className:"arrow",width:"20",height:"20","aria-hidden":"true",focusable:"false"},V().createElement("use",{href:n?"#large-arrow-up":"#large-arrow-down",xlinkHref:n?"#large-arrow-up":"#large-arrow-down"}))),N?null:V().createElement(C,{isAuthorized:d,onClick:function(){var e=s.definitionsForRequirements(b);o.showDefinitions(e)}}),V().createElement(_,{path:c}))}}]),n}(j.PureComponent);E()(gt,"defaultProps",{operationProps:null,specPath:(0,L.List)(),summary:""});var vt=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props.method;return V().createElement("span",{className:"opblock-summary-method"},e.toUpperCase())}}]),n}(j.PureComponent);E()(vt,"defaultProps",{operationProps:null});const yt=require("@babel/runtime-corejs3/core-js-stable/instance/splice");var Et=n.n(yt),St=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){for(var e,t=this.props,n=t.getComponent,r=t.operationProps.toJS(),a=r.deprecated,o=r.isShown,s=r.path,i=r.tag,c=r.operationId,u=r.isDeepLinkingEnabled,p=s.split(/(?=\/)/g),d=1;da&&(0===o&&n<0||a+o>=r&&n>0)&&e.preventDefault()};return V().createElement("div",{className:"highlight-code",ref:u},a?V().createElement("div",{className:"download-contents",onClick:function(){Mt()(t,n)}},"Download"):null,s&&V().createElement("div",{className:"copy-to-clipboard"},V().createElement(jt.CopyToClipboard,{text:t},V().createElement("button",null))),c?V().createElement(It.d3,{language:l,className:Nt()(r,"microlight"),style:(0,It.C2)(Rt()(i,"syntaxHighlight.theme","agate"))},t):V().createElement("pre",{className:Nt()(r,"microlight")},t))};Vt.defaultProps={fileName:"response.txt"};const Dt=Vt;var Lt=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s1&&void 0!==arguments[1]?arguments[1]:"_";return e.replace(/[^\w-]/g,t)}(l()(e="".concat(g)).call(e,f,"_responses")),A="".concat(_,"_select");return V().createElement("div",{className:"responses-wrapper"},V().createElement("div",{className:"opblock-section-header"},V().createElement("h4",null,"Responses"),u.isOAS3()?null:V().createElement("label",{htmlFor:A},V().createElement("span",null,"Response content type"),V().createElement(S,{value:d,ariaControls:_,ariaLabel:"Response content type",className:"execute-content-type",contentTypes:x,controlId:A,onChange:this.onChangeProducesWrapper}))),V().createElement("div",{className:"responses-inner"},s?V().createElement("div",null,V().createElement(b,{response:s,getComponent:i,getConfigs:c,specSelectors:u,path:this.props.path,method:this.props.method,displayRequestDuration:m}),V().createElement("h4",null,"Responses")):null,V().createElement("table",{"aria-live":"polite",className:"responses-table",id:_,role:"region"},V().createElement("thead",null,V().createElement("tr",{className:"responses-header"},V().createElement("td",{className:"col_header response-col_status"},"Code"),V().createElement("td",{className:"col_header response-col_description"},"Description"),u.isOAS3()?V().createElement("td",{className:"col col_header response-col_links"},"Links"):null)),V().createElement("tbody",null,M()(t=o.entrySeq()).call(t,(function(e){var t=Ct()(e,2),n=t[0],a=t[1],o=s&&s.get("status")==n?"response_current":"";return V().createElement(C,{key:n,path:f,method:g,specPath:h.push(n),isDefault:E===n,fn:p,className:o,code:n,response:a,specSelectors:u,controlsAcceptHeader:a===w,onContentTypeChange:r.onResponseContentTypeChange,contentType:d,getConfigs:c,activeExamplesKey:v.activeExamplesMember(f,g,"responses",n),oas3Actions:y,getComponent:i})})).toArray()))))}}]),n}(V().Component);E()(Lt,"defaultProps",{tryItOutResponse:null,produces:(0,L.fromJS)(["application/json"]),displayRequestDuration:!1});var Ut=n(67),zt=n.n(Ut);const Bt=require("@babel/runtime-corejs3/core-js-stable/instance/values");var Jt=n.n(Bt),Ft=n(2518),Wt=function(e){Se()(n,e);var t=Ce()(n);function n(e,r){var a;return b()(this,n),a=t.call(this,e,r),E()(ye()(a),"_onContentTypeChange",(function(e){var t=a.props,n=t.onContentTypeChange,r=t.controlsAcceptHeader;a.setState({responseContentType:e}),n({value:e,controlsAcceptHeader:r})})),E()(ye()(a),"getTargetExamplesKey",(function(){var e=a.props,t=e.response,n=e.contentType,r=e.activeExamplesKey,o=a.state.responseContentType||n,s=t.getIn(["content",o],(0,L.Map)({})).get("examples",null).keySeq().first();return r||s})),a.state={responseContentType:""},a}return x()(n,[{key:"render",value:function(){var e,t,n,r,a,o=this.props,s=o.path,i=o.method,c=o.code,u=o.response,p=o.className,d=o.specPath,m=o.fn,h=o.getComponent,f=o.getConfigs,g=o.specSelectors,v=o.contentType,y=o.controlsAcceptHeader,E=o.oas3Actions,S=m.inferSchema,b=g.isOAS3(),C=f().showExtensions,x=C?(0,K.nX)(u):null,w=u.get("headers"),_=u.get("links"),A=h("ResponseExtension"),k=h("headers"),N=h("highlightCode"),I=h("modelExample"),q=h("Markdown",!0),R=h("operationLink"),P=h("contentType"),T=h("ExamplesSelect"),O=h("Example"),j=this.state.responseContentType||v,D=u.getIn(["content",j],(0,L.Map)({})),U=D.get("examples",null);if(b){var z=D.get("schema");n=z?S(z.toJS()):null,r=z?(0,L.List)(["content",this.state.responseContentType,"schema"]):d}else n=u.get("schema"),r=u.has("schema")?d.push("schema"):d;var B,J=!1,F={includeReadOnly:!0};if(b){var W;if(B=null===(W=D.get("schema"))||void 0===W?void 0:W.toJS(),U){var H=this.getTargetExamplesKey(),Z=function(e){return e.get("value")};void 0===(a=Z(U.get(H,(0,L.Map)({}))))&&(a=Z(Jt()(U).call(U).next().value)),J=!0}else void 0!==D.get("example")&&(a=D.get("example"),J=!0)}else{B=n,F=zt()(zt()({},F),{},{includeWriteOnly:!0});var G=u.getIn(["examples",j]);G&&(a=G,J=!0)}var Y=function(e,t,n){if(null!=e){var r=null;return(0,Ft.O)(e)&&(r="json"),V().createElement("div",null,V().createElement(t,{className:"example",getConfigs:n,language:r,value:(0,K.Pz)(e)}))}return null}((0,K.xi)(B,j,F,J?a:void 0),N,f);return V().createElement("tr",{className:"response "+(p||""),"data-code":c},V().createElement("td",{className:"response-col_status"},c),V().createElement("td",{className:"response-col_description"},V().createElement("div",{className:"response-col_description__inner"},V().createElement(q,{source:u.get("description")})),C&&x.size?M()(e=x.entrySeq()).call(e,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(A,{key:l()(t="".concat(r,"-")).call(t,a),xKey:r,xVal:a})})):null,b&&u.get("content")?V().createElement("section",{className:"response-controls"},V().createElement("div",{className:Nt()("response-control-media-type",{"response-control-media-type--accept-controller":y})},V().createElement("small",{className:"response-control-media-type__title"},"Media type"),V().createElement(P,{value:this.state.responseContentType,contentTypes:u.get("content")?u.get("content").keySeq():(0,L.Seq)(),onChange:this._onContentTypeChange,ariaLabel:"Media Type"}),y?V().createElement("small",{className:"response-control-media-type__accept-message"},"Controls ",V().createElement("code",null,"Accept")," header."):null),U?V().createElement("div",{className:"response-control-examples"},V().createElement("small",{className:"response-control-examples__title"},"Examples"),V().createElement(T,{examples:U,currentExampleKey:this.getTargetExamplesKey(),onSelect:function(e){return E.setActiveExamplesMember({name:e,pathMethod:[s,i],contextType:"responses",contextName:c})},showLabels:!1})):null):null,Y||n?V().createElement(I,{specPath:r,getComponent:h,getConfigs:f,specSelectors:g,schema:(0,K.oG)(n),example:Y,includeReadOnly:!0}):null,b&&U?V().createElement(O,{example:U.get(this.getTargetExamplesKey(),(0,L.Map)({})),getComponent:h,getConfigs:f,omitValue:!0}):null,w?V().createElement(k,{headers:w,getComponent:h}):null),b?V().createElement("td",{className:"response-col_links"},_?M()(t=_.toSeq().entrySeq()).call(t,(function(e){var t=Ct()(e,2),n=t[0],r=t[1];return V().createElement(R,{key:n,name:n,link:r,getComponent:h})})):V().createElement("i",null,"No links")):null)}}]),n}(V().Component);E()(Wt,"defaultProps",{response:(0,L.fromJS)({}),onContentTypeChange:function(){}});const Ht=function(e){var t=e.xKey,n=e.xVal;return V().createElement("div",{className:"response__extension"},t,": ",String(n))},Kt=require("xml-but-prettier");var Zt=n.n(Kt);const Gt=require("lodash/toLower");var Yt=n.n(Gt),Xt=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s0?p?V().createElement("div",null,V().createElement("p",{className:"i"},"Unrecognized response type; displaying content as text."),V().createElement(d,{downloadable:!0,fileName:"".concat(m,".txt"),value:p,getConfigs:i,canCopy:!0})):V().createElement("p",{className:"i"},"Unrecognized response type; unable to display."):null;return t?V().createElement("div",null,V().createElement("h5",null,"Response body"),t):null}}]),n}(V().PureComponent),Qt=n(6731),$t=n.n(Qt),en=n(9968),tn=n.n(en),nn=function(e){Se()(n,e);var t=Ce()(n);function n(e){var r;return b()(this,n),r=t.call(this,e),E()(ye()(r),"onChange",(function(e,t,n){var a=r.props;(0,a.specActions.changeParamByIdentity)(a.onChangeKey,e,t,n)})),E()(ye()(r),"onChangeConsumesWrapper",(function(e){var t=r.props;(0,t.specActions.changeConsumesValue)(t.onChangeKey,e)})),E()(ye()(r),"toggleTab",(function(e){return"parameters"===e?r.setState({parametersVisible:!0,callbackVisible:!1}):"callbacks"===e?r.setState({callbackVisible:!0,parametersVisible:!1}):void 0})),E()(ye()(r),"onChangeMediaType",(function(e){var t=e.value,n=e.pathMethod,a=r.props,o=a.specActions,s=a.oas3Selectors,l=a.oas3Actions,i=s.hasUserEditedBody.apply(s,$t()(n)),c=s.shouldRetainRequestBodyValue.apply(s,$t()(n));l.setRequestContentType({value:t,pathMethod:n}),l.initRequestBodyValidateError({pathMethod:n}),i||(c||l.setRequestBodyValue({value:void 0,pathMethod:n}),o.clearResponse.apply(o,$t()(n)),o.clearRequest.apply(o,$t()(n)),o.clearValidateParams(n))})),r.state={callbackVisible:!1,parametersVisible:!0},r}return x()(n,[{key:"render",value:function(){var e,t,n=this,r=this.props,a=r.onTryoutClick,o=r.parameters,s=r.allowTryItOut,i=r.tryItOutEnabled,c=r.specPath,u=r.fn,p=r.getComponent,d=r.getConfigs,m=r.specSelectors,h=r.specActions,f=r.pathMethod,g=r.oas3Actions,v=r.oas3Selectors,y=r.operation,E=p("parameterRow"),S=p("TryItOutButton"),b=p("contentType"),C=p("Callbacks",!0),x=p("RequestBody",!0),w=i&&s,_=m.isOAS3(),A=y.get("requestBody"),k=T()(e=tn()(T()(o).call(o,(function(e,t){var n,r=t.get("in");return null!==(n=e[r])&&void 0!==n||(e[r]=[]),e[r].push(t),e}),{}))).call(e,(function(e,t){return l()(e).call(e,t)}),[]);return V().createElement("div",{className:"opblock-section"},V().createElement("div",{className:"opblock-section-header"},_?V().createElement("div",{className:"tab-header"},V().createElement("div",{onClick:function(){return n.toggleTab("parameters")},className:"tab-item ".concat(this.state.parametersVisible&&"active")},V().createElement("h4",{className:"opblock-title"},V().createElement("span",null,"Parameters"))),y.get("callbacks")?V().createElement("div",{onClick:function(){return n.toggleTab("callbacks")},className:"tab-item ".concat(this.state.callbackVisible&&"active")},V().createElement("h4",{className:"opblock-title"},V().createElement("span",null,"Callbacks"))):null):V().createElement("div",{className:"tab-header"},V().createElement("h4",{className:"opblock-title"},"Parameters")),s?V().createElement(S,{isOAS3:m.isOAS3(),hasUserEditedBody:v.hasUserEditedBody.apply(v,$t()(f)),enabled:i,onCancelClick:this.props.onCancelClick,onTryoutClick:a,onResetClick:function(){return g.setRequestBodyValue({value:void 0,pathMethod:f})}}):null),this.state.parametersVisible?V().createElement("div",{className:"parameters-container"},k.length?V().createElement("div",{className:"table-container"},V().createElement("table",{className:"parameters"},V().createElement("thead",null,V().createElement("tr",null,V().createElement("th",{className:"col_header parameters-col_name"},"Name"),V().createElement("th",{className:"col_header parameters-col_description"},"Description"))),V().createElement("tbody",null,M()(k).call(k,(function(e,t){var r;return V().createElement(E,{fn:u,specPath:c.push(t.toString()),getComponent:p,getConfigs:d,rawParam:e,param:m.parameterWithMetaByIdentity(f,e),key:l()(r="".concat(e.get("in"),".")).call(r,e.get("name")),onChange:n.onChange,onChangeConsumes:n.onChangeConsumesWrapper,specSelectors:m,specActions:h,oas3Actions:g,oas3Selectors:v,pathMethod:f,isExecute:w})}))))):V().createElement("div",{className:"opblock-description-wrapper"},V().createElement("p",null,"No parameters"))):null,this.state.callbackVisible?V().createElement("div",{className:"callbacks-container opblock-description-wrapper"},V().createElement(C,{callbacks:(0,L.Map)(y.get("callbacks")),specPath:I()(c).call(c,0,-1).push("callbacks")})):null,_&&A&&this.state.parametersVisible&&V().createElement("div",{className:"opblock-section opblock-section-request-body"},V().createElement("div",{className:"opblock-section-header"},V().createElement("h4",{className:"opblock-title parameter__name ".concat(A.get("required")&&"required")},"Request body"),V().createElement("label",null,V().createElement(b,{value:v.requestContentType.apply(v,$t()(f)),contentTypes:A.get("content",(0,L.List)()).keySeq(),onChange:function(e){n.onChangeMediaType({value:e,pathMethod:f})},className:"body-param-content-type",ariaLabel:"Request content type"}))),V().createElement("div",{className:"opblock-description-wrapper"},V().createElement(x,{setRetainRequestBodyValueFlag:function(e){return g.setRetainRequestBodyValueFlag({value:e,pathMethod:f})},userHasEditedBody:v.hasUserEditedBody.apply(v,$t()(f)),specPath:I()(c).call(c,0,-1).push("requestBody"),requestBody:A,requestBodyValue:v.requestBodyValue.apply(v,$t()(f)),requestBodyInclusionSetting:v.requestBodyInclusionSetting.apply(v,$t()(f)),requestBodyErrors:v.requestBodyErrors.apply(v,$t()(f)),isExecute:w,getConfigs:d,activeExamplesKey:v.activeExamplesMember.apply(v,l()(t=$t()(f)).call(t,["requestBody","requestBody"])),updateActiveExamplesKey:function(e){n.props.oas3Actions.setActiveExamplesMember({name:e,pathMethod:n.props.pathMethod,contextType:"requestBody",contextName:"requestBody"})},onChange:function(e,t){if(t){var n=v.requestBodyValue.apply(v,$t()(f)),r=L.Map.isMap(n)?n:(0,L.Map)();return g.setRequestBodyValue({pathMethod:f,value:r.setIn(t,e)})}g.setRequestBodyValue({value:e,pathMethod:f})},onChangeIncludeEmpty:function(e,t){g.setRequestBodyInclusion({pathMethod:f,value:t,name:e})},contentType:v.requestContentType.apply(v,$t()(f))}))))}}]),n}(j.Component);E()(nn,"defaultProps",{onTryoutClick:Function.prototype,onCancelClick:Function.prototype,tryItOutEnabled:!1,allowTryItOut:!0,onChangeKey:[],specPath:[]});const rn=function(e){var t=e.xKey,n=e.xVal;return V().createElement("div",{className:"parameter__extension"},t,": ",String(n))};var an={onChange:function(){},isIncludedOptions:{}},on=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s1&&void 0!==arguments[1]&&arguments[1],n=a.props,r=n.onChange,o=n.rawParam;return r(o,""===e||e&&0===e.size?null:e,t)})),E()(ye()(a),"_onExampleSelect",(function(e){a.props.oas3Actions.setActiveExamplesMember({name:e,pathMethod:a.props.pathMethod,contextType:"parameters",contextName:a.getParamKey()})})),E()(ye()(a),"onChangeIncludeEmpty",(function(e){var t=a.props,n=t.specActions,r=t.param,o=t.pathMethod,s=r.get("name"),l=r.get("in");return n.updateEmptyParamInclusion(o,s,l,e)})),E()(ye()(a),"setDefaultValue",(function(){var e=a.props,t=e.specSelectors,n=e.pathMethod,r=e.rawParam,o=e.oas3Selectors,s=t.parameterWithMetaByIdentity(n,r)||(0,L.Map)(),i=(0,sn.Z)(s,{isOAS3:t.isOAS3()}).schema,c=s.get("content",(0,L.Map)()).keySeq().first(),u=i?(0,K.xi)(i.toJS(),c,{includeWriteOnly:!0}):null;if(s&&void 0===s.get("value")&&"body"!==s.get("in")){var p;if(t.isSwagger2())p=void 0!==s.get("x-example")?s.get("x-example"):void 0!==s.getIn(["schema","example"])?s.getIn(["schema","example"]):i&&i.getIn(["default"]);else if(t.isOAS3()){var d,m=o.activeExamplesMember.apply(o,l()(d=$t()(n)).call(d,["parameters",a.getParamKey()]));p=void 0!==s.getIn(["examples",m,"value"])?s.getIn(["examples",m,"value"]):void 0!==s.getIn(["content",c,"example"])?s.getIn(["content",c,"example"]):void 0!==s.get("example")?s.get("example"):void 0!==(i&&i.get("example"))?i&&i.get("example"):void 0!==(i&&i.get("default"))?i&&i.get("default"):s.get("default")}void 0===p||L.List.isList(p)||(p=(0,K.Pz)(p)),void 0!==p?a.onChangeWrapper(p):i&&"object"===i.get("type")&&u&&!s.get("examples")&&a.onChangeWrapper(L.List.isList(u)?u:(0,K.Pz)(u))}})),a.setDefaultValue(),a}return x()(n,[{key:"UNSAFE_componentWillReceiveProps",value:function(e){var t,n=e.specSelectors,r=e.pathMethod,a=e.rawParam,o=n.isOAS3(),s=n.parameterWithMetaByIdentity(r,a)||new L.Map;if(s=s.isEmpty()?a:s,o){var l=(0,sn.Z)(s,{isOAS3:o}).schema;t=l?l.get("enum"):void 0}else t=s?s.get("enum"):void 0;var i,c=s?s.get("value"):void 0;void 0!==c?i=c:a.get("required")&&t&&t.size&&(i=t.first()),void 0!==i&&i!==c&&this.onChangeWrapper((0,K.D$)(i)),this.setDefaultValue()}},{key:"getParamKey",value:function(){var e,t=this.props.param;return t?l()(e="".concat(t.get("name"),"-")).call(e,t.get("in")):null}},{key:"render",value:function(){var e,t,n,r,a=this.props,o=a.param,s=a.rawParam,i=a.getComponent,c=a.getConfigs,u=a.isExecute,p=a.fn,d=a.onChangeConsumes,m=a.specSelectors,h=a.pathMethod,f=a.specPath,g=a.oas3Selectors,v=m.isOAS3(),y=c(),E=y.showExtensions,S=y.showCommonExtensions;if(o||(o=s),!s)return null;var b,C,x,w,_=i("JsonSchemaForm"),A=i("ParamBody"),k=o.get("in"),N="body"!==k?null:V().createElement(A,{getComponent:i,getConfigs:c,fn:p,param:o,consumes:m.consumesOptionsFor(h),consumesValue:m.contentTypeValues(h).get("requestContentType"),onChange:this.onChangeWrapper,onChangeConsumes:d,isExecute:u,specSelectors:m,pathMethod:h}),I=i("modelExample"),q=i("Markdown",!0),R=i("ParameterExt"),P=i("ParameterIncludeEmpty"),T=i("ExamplesSelectValueRetainer"),O=i("Example"),j=(0,sn.Z)(o,{isOAS3:v}).schema,D=m.parameterWithMetaByIdentity(h,s)||(0,L.Map)(),U=j?j.get("format"):null,z=j?j.get("type"):null,B=j?j.getIn(["items","type"]):null,J="formData"===k,F="FormData"in H.Z,W=o.get("required"),Z=D?D.get("value"):"",G=S?(0,K.po)(j):null,Y=E?(0,K.nX)(o):null,X=!1;return void 0!==o&&j&&(b=j.get("items")),void 0!==b?(C=b.get("enum"),x=b.get("default")):j&&(C=j.get("enum")),C&&C.size&&C.size>0&&(X=!0),void 0!==o&&(j&&(x=j.get("default")),void 0===x&&(x=o.get("default")),void 0===(w=o.get("example"))&&(w=o.get("x-example"))),V().createElement("tr",{"data-param-name":o.get("name"),"data-param-in":o.get("in")},V().createElement("td",{className:"parameters-col_name"},V().createElement("div",{className:W?"parameter__name required":"parameter__name"},o.get("name"),W?V().createElement("span",null," *"):null),V().createElement("div",{className:"parameter__type"},z,B&&"[".concat(B,"]"),U&&V().createElement("span",{className:"prop-format"},"($",U,")")),V().createElement("div",{className:"parameter__deprecated"},v&&o.get("deprecated")?"deprecated":null),V().createElement("div",{className:"parameter__in"},"(",o.get("in"),")"),S&&G.size?M()(e=G.entrySeq()).call(e,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(R,{key:l()(t="".concat(r,"-")).call(t,a),xKey:r,xVal:a})})):null,E&&Y.size?M()(t=Y.entrySeq()).call(t,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(R,{key:l()(t="".concat(r,"-")).call(t,a),xKey:r,xVal:a})})):null),V().createElement("td",{className:"parameters-col_description"},o.get("description")?V().createElement(q,{source:o.get("description")}):null,!N&&u||!X?null:V().createElement(q,{className:"parameter__enum",source:"Available values : "+M()(C).call(C,(function(e){return e})).toArray().join(", ")}),!N&&u||void 0===x?null:V().createElement(q,{className:"parameter__default",source:"Default value : "+x}),!N&&u||void 0===w?null:V().createElement(q,{source:"Example : "+w}),J&&!F&&V().createElement("div",null,"Error: your browser does not support FormData"),v&&o.get("examples")?V().createElement("section",{className:"parameter-controls"},V().createElement(T,{examples:o.get("examples"),onSelect:this._onExampleSelect,updateValue:this.onChangeWrapper,getComponent:i,defaultToFirstExample:!0,currentKey:g.activeExamplesMember.apply(g,l()(n=$t()(h)).call(n,["parameters",this.getParamKey()])),currentUserInputValue:Z})):null,N?null:V().createElement(_,{fn:p,getComponent:i,value:Z,required:W,disabled:!u,description:o.get("name"),onChange:this.onChangeWrapper,errors:D.get("errors"),schema:j}),N&&j?V().createElement(I,{getComponent:i,specPath:f.push("schema"),getConfigs:c,isExecute:u,specSelectors:m,schema:j,example:N,includeWriteOnly:!0}):null,!N&&u&&o.get("allowEmptyValue")?V().createElement(P,{onChange:this.onChangeIncludeEmpty,isIncluded:m.parameterInclusionSettingFor(h,o.get("name"),o.get("in")),isDisabled:!(0,K.O2)(Z)}):null,v&&o.get("examples")?V().createElement(O,{example:o.getIn(["examples",g.activeExamplesMember.apply(g,l()(r=$t()(h)).call(r,["parameters",this.getParamKey()]))]),getComponent:i,getConfigs:c}):null))}}]),n}(j.Component),cn=n(9300),un=n.n(cn),pn=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s0&&"none"!==p),f=r.isOAS3(),g=a("ModelWrapper"),v=a("Collapse"),y=a("ModelCollapse"),E=a("JumpToPath",!0);return V().createElement("section",{className:h?"models is-open":"models",ref:this.onLoadModels},V().createElement("h4",null,V().createElement("button",{"aria-expanded":h,className:"models-control",onClick:function(){return s.show(m,!h)}},V().createElement("span",null,f?"Schemas":"Models"),V().createElement("svg",{width:"20",height:"20","aria-hidden":"true",focusable:"false"},V().createElement("use",{xlinkHref:h?"#large-arrow-up":"#large-arrow-down"})))),V().createElement(v,{isOpened:h},M()(e=c.entrySeq()).call(e,(function(e){var n,c=Ct()(e,1)[0],u=l()(n=[]).call(n,$t()(m),[c]),p=U().List(u),h=r.specResolvedSubtree(u),f=r.specJson().getIn(u),v=L.Map.isMap(h)?h:U().Map(),S=L.Map.isMap(f)?f:U().Map(),b=v.get("title")||S.get("title")||c,C=o.isShown(u,!1);C&&0===v.size&&S.size>0&&t.props.specActions.requestResolvedSubtree(u);var x=V().createElement(g,{name:c,expandDepth:d,schema:v||U().Map(),displayName:b,fullPath:u,specPath:p,getComponent:a,specSelectors:r,getConfigs:i,layoutSelectors:o,layoutActions:s,includeReadOnly:!0,includeWriteOnly:!0}),w=V().createElement("span",{className:"model-box"},V().createElement("span",{className:"model model-title"},b));return V().createElement("div",{id:"model-".concat(c),className:"model-container",key:"models-section-".concat(c),"data-name":c,ref:t.onLoadModel},V().createElement("span",{className:"models-jump-to-path"},V().createElement(E,{specPath:p})),V().createElement(y,{classes:"model-box",collapsedContent:t.getCollapsedContent(c),onToggle:t.handleToggle,title:w,displayName:b,modelName:c,specPath:p,layoutSelectors:o,layoutActions:s,hideSelfOnExpand:!0,expanded:d>0&&C},x))})).toArray()))}}]),n}(j.Component);const ur=function(e){var t=e.value,n=(0,e.getComponent)("ModelCollapse"),r=V().createElement("span",null,"Array [ ",t.count()," ]");return V().createElement("span",{className:"prop-enum"},"Enum:",V().createElement("br",null),V().createElement(n,{collapsedContent:r},"[ ",t.join(", ")," ]"))};var pr=["schema","name","displayName","isRef","getComponent","getConfigs","depth","onToggle","expanded","specPath"],dr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t,n,r,a=this.props,o=a.schema,s=a.name,i=a.displayName,c=a.isRef,u=a.getComponent,d=a.getConfigs,m=a.depth,h=a.onToggle,g=a.expanded,v=a.specPath,y=bn()(a,pr),E=y.specSelectors,S=y.expandDepth,b=y.includeReadOnly,C=y.includeWriteOnly,x=E.isOAS3;if(!o)return null;var w=d().showExtensions,_=o.get("description"),A=o.get("properties"),k=o.get("additionalProperties"),N=o.get("title")||i||s,q=o.get("required"),R=p()(o).call(o,(function(e,t){var n;return-1!==we()(n=["maxProperties","minProperties","nullable","example"]).call(n,t)})),P=o.get("deprecated"),T=u("JumpToPath",!0),O=u("Markdown",!0),j=u("Model"),D=u("ModelCollapse"),U=u("Property"),z=function(){return V().createElement("span",{className:"model-jump-to-path"},V().createElement(T,{specPath:v}))},B=V().createElement("span",null,V().createElement("span",null,"{"),"...",V().createElement("span",null,"}"),c?V().createElement(z,null):""),J=E.isOAS3()?o.get("anyOf"):null,F=E.isOAS3()?o.get("oneOf"):null,W=E.isOAS3()?o.get("not"):null,H=N&&V().createElement("span",{className:"model-title"},c&&o.get("$$ref")&&V().createElement("span",{className:"model-hint"},o.get("$$ref")),V().createElement("span",{className:"model-title__text"},N));return V().createElement("span",{className:"model"},V().createElement(D,{modelName:s,title:H,onToggle:h,expanded:!!g||m<=S,collapsedContent:B},V().createElement("span",{className:"brace-open object"},"{"),c?V().createElement(z,null):null,V().createElement("span",{className:"inner-object"},V().createElement("table",{className:"model"},V().createElement("tbody",null,_?V().createElement("tr",{className:"description"},V().createElement("td",null,"description:"),V().createElement("td",null,V().createElement(O,{source:_}))):null,P?V().createElement("tr",{className:"property"},V().createElement("td",null,"deprecated:"),V().createElement("td",null,"true")):null,A&&A.size?M()(e=p()(t=A.entrySeq()).call(t,(function(e){var t=Ct()(e,2)[1];return(!t.get("readOnly")||b)&&(!t.get("writeOnly")||C)}))).call(e,(function(e){var t,n,r=Ct()(e,2),a=r[0],o=r[1],i=x()&&o.get("deprecated"),c=L.List.isList(q)&&q.contains(a),p=["property-row"];return i&&p.push("deprecated"),c&&p.push("required"),V().createElement("tr",{key:a,className:p.join(" ")},V().createElement("td",null,a,c&&V().createElement("span",{className:"star"},"*")),V().createElement("td",null,V().createElement(j,En()({key:l()(t=l()(n="object-".concat(s,"-")).call(n,a,"_")).call(t,o)},y,{required:c,getComponent:u,specPath:v.push("properties",a),getConfigs:d,schema:o,depth:m+1}))))})).toArray():null,w?V().createElement("tr",null,V().createElement("td",null," ")):null,w?M()(n=o.entrySeq()).call(n,(function(e){var t=Ct()(e,2),n=t[0],r=t[1];if("x-"===I()(n).call(n,0,2)){var a=r?r.toJS?r.toJS():r:null;return V().createElement("tr",{key:n,className:"extension"},V().createElement("td",null,n),V().createElement("td",null,f()(a)))}})).toArray():null,k&&k.size?V().createElement("tr",null,V().createElement("td",null,"< * >:"),V().createElement("td",null,V().createElement(j,En()({},y,{required:!1,getComponent:u,specPath:v.push("additionalProperties"),getConfigs:d,schema:k,depth:m+1})))):null,J?V().createElement("tr",null,V().createElement("td",null,"anyOf ->"),V().createElement("td",null,M()(J).call(J,(function(e,t){return V().createElement("div",{key:t},V().createElement(j,En()({},y,{required:!1,getComponent:u,specPath:v.push("anyOf",t),getConfigs:d,schema:e,depth:m+1})))})))):null,F?V().createElement("tr",null,V().createElement("td",null,"oneOf ->"),V().createElement("td",null,M()(F).call(F,(function(e,t){return V().createElement("div",{key:t},V().createElement(j,En()({},y,{required:!1,getComponent:u,specPath:v.push("oneOf",t),getConfigs:d,schema:e,depth:m+1})))})))):null,W?V().createElement("tr",null,V().createElement("td",null,"not ->"),V().createElement("td",null,V().createElement("div",null,V().createElement(j,En()({},y,{required:!1,getComponent:u,specPath:v.push("not"),getConfigs:d,schema:W,depth:m+1}))))):null))),V().createElement("span",{className:"brace-close"},"}")),R.size?M()(r=R.entrySeq()).call(r,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(U,{key:l()(t="".concat(r,"-")).call(t,a),propKey:r,propVal:a,propClass:"property"})})):null)}}]),n}(j.Component),mr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t=this.props,n=t.getComponent,r=t.getConfigs,a=t.schema,o=t.depth,s=t.expandDepth,i=t.name,c=t.displayName,u=t.specPath,d=a.get("description"),m=a.get("items"),h=a.get("title")||c||i,f=p()(a).call(a,(function(e,t){var n;return-1===we()(n=["type","items","description","$$ref"]).call(n,t)})),g=n("Markdown",!0),v=n("ModelCollapse"),y=n("Model"),E=n("Property"),S=h&&V().createElement("span",{className:"model-title"},V().createElement("span",{className:"model-title__text"},h));return V().createElement("span",{className:"model"},V().createElement(v,{title:S,expanded:o<=s,collapsedContent:"[...]"},"[",f.size?M()(e=f.entrySeq()).call(e,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(E,{key:l()(t="".concat(r,"-")).call(t,a),propKey:r,propVal:a,propClass:"property"})})):null,d?V().createElement(g,{source:d}):f.size?V().createElement("div",{className:"markdown"}):null,V().createElement("span",null,V().createElement(y,En()({},this.props,{getConfigs:r,specPath:u.push("items"),name:null,schema:m,required:!1,depth:o+1}))),"]"))}}]),n}(j.Component),hr="property primitive",fr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e,t,n,r=this.props,a=r.schema,o=r.getComponent,s=r.getConfigs,i=r.name,c=r.displayName,u=r.depth,d=r.expandDepth,m=s().showExtensions;if(!a||!a.get)return V().createElement("div",null);var h=a.get("type"),f=a.get("format"),g=a.get("xml"),v=a.get("enum"),y=a.get("title")||c||i,E=a.get("description"),S=(0,K.nX)(a),b=p()(a).call(a,(function(e,t){var n;return-1===we()(n=["enum","type","format","description","$$ref"]).call(n,t)})).filterNot((function(e,t){return S.has(t)})),C=o("Markdown",!0),x=o("EnumModel"),w=o("Property"),_=o("ModelCollapse"),A=y&&V().createElement("span",{className:"model-title"},V().createElement("span",{className:"model-title__text"},y));return V().createElement("span",{className:"model"},V().createElement(_,{title:A,expanded:u>=d,collapsedContent:" ",hideSelfOnExpand:d!==u},V().createElement("span",{className:"prop"},i&&u>1&&V().createElement("span",{className:"prop-name"},y),V().createElement("span",{className:"prop-type"},h),f&&V().createElement("span",{className:"prop-format"},"($",f,")"),b.size?M()(e=b.entrySeq()).call(e,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(w,{key:l()(t="".concat(r,"-")).call(t,a),propKey:r,propVal:a,propClass:hr})})):null,m&&S.size?M()(t=S.entrySeq()).call(t,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement(w,{key:l()(t="".concat(r,"-")).call(t,a),propKey:r,propVal:a,propClass:hr})})):null,E?V().createElement(C,{source:E}):null,g&&g.size?V().createElement("span",null,V().createElement("br",null),V().createElement("span",{className:hr},"xml:"),M()(n=g.entrySeq()).call(n,(function(e){var t,n=Ct()(e,2),r=n[0],a=n[1];return V().createElement("span",{key:l()(t="".concat(r,"-")).call(t,a),className:hr},V().createElement("br",null),"   ",r,": ",String(a))})).toArray()):null,v&&V().createElement(x,{value:v,getComponent:o}))))}}]),n}(j.Component);const gr=function(e){var t=e.propKey,n=e.propVal,r=e.propClass;return V().createElement("span",{className:r},V().createElement("br",null),t,": ",String(n))};var vr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props,t=e.onTryoutClick,n=e.onCancelClick,r=e.onResetClick,a=e.enabled,o=e.hasUserEditedBody,s=e.isOAS3&&o;return V().createElement("div",{className:s?"try-out btn-group":"try-out"},a?V().createElement("button",{className:"btn try-out__btn cancel",onClick:n},"Cancel"):V().createElement("button",{className:"btn try-out__btn",onClick:t},"Try it out "),s&&V().createElement("button",{className:"btn try-out__btn reset",onClick:r},"Reset"))}}]),n}(V().Component);E()(vr,"defaultProps",{onTryoutClick:Function.prototype,onCancelClick:Function.prototype,onResetClick:Function.prototype,enabled:!1,hasUserEditedBody:!1,isOAS3:!1});var yr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props,t=e.bypass,n=e.isSwagger2,r=e.isOAS3,a=e.alsoShow;return t?V().createElement("div",null,this.props.children):n&&r?V().createElement("div",{className:"version-pragma"},a,V().createElement("div",{className:"version-pragma__message version-pragma__message--ambiguous"},V().createElement("div",null,V().createElement("h3",null,"Unable to render this definition"),V().createElement("p",null,V().createElement("code",null,"swagger")," and ",V().createElement("code",null,"openapi")," fields cannot be present in the same Swagger or OpenAPI definition. Please remove one of the fields."),V().createElement("p",null,"Supported version fields are ",V().createElement("code",null,"swagger: ",'"2.0"')," and those that match ",V().createElement("code",null,"openapi: 3.0.n")," (for example, ",V().createElement("code",null,"openapi: 3.0.0"),").")))):n||r?V().createElement("div",null,this.props.children):V().createElement("div",{className:"version-pragma"},a,V().createElement("div",{className:"version-pragma__message version-pragma__message--missing"},V().createElement("div",null,V().createElement("h3",null,"Unable to render this definition"),V().createElement("p",null,"The provided definition does not specify a valid version field."),V().createElement("p",null,"Please indicate a valid Swagger or OpenAPI version field. Supported version fields are ",V().createElement("code",null,"swagger: ",'"2.0"')," and those that match ",V().createElement("code",null,"openapi: 3.0.n")," (for example, ",V().createElement("code",null,"openapi: 3.0.0"),")."))))}}]),n}(V().PureComponent);E()(yr,"defaultProps",{alsoShow:null,children:null,bypass:!1});const Er=function(e){var t=e.version;return V().createElement("small",null,V().createElement("pre",{className:"version"}," ",t," "))};const Sr=function(e){var t=e.enabled,n=e.path,r=e.text;return V().createElement("a",{className:"nostyle",onClick:t?function(e){return e.preventDefault()}:null,href:t?"#/".concat(n):null},V().createElement("span",null,r))};const br=function(){return V().createElement("div",null,V().createElement("svg",{xmlns:"http://www.w3.org/2000/svg",xmlnsXlink:"http://www.w3.org/1999/xlink",className:"svg-assets"},V().createElement("defs",null,V().createElement("symbol",{viewBox:"0 0 20 20",id:"unlocked"},V().createElement("path",{d:"M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V6h2v-.801C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8z"})),V().createElement("symbol",{viewBox:"0 0 20 20",id:"locked"},V().createElement("path",{d:"M15.8 8H14V5.6C14 2.703 12.665 1 10 1 7.334 1 6 2.703 6 5.6V8H4c-.553 0-1 .646-1 1.199V17c0 .549.428 1.139.951 1.307l1.197.387C5.672 18.861 6.55 19 7.1 19h5.8c.549 0 1.428-.139 1.951-.307l1.196-.387c.524-.167.953-.757.953-1.306V9.199C17 8.646 16.352 8 15.8 8zM12 8H8V5.199C8 3.754 8.797 3 10 3c1.203 0 2 .754 2 2.199V8z"})),V().createElement("symbol",{viewBox:"0 0 20 20",id:"close"},V().createElement("path",{d:"M14.348 14.849c-.469.469-1.229.469-1.697 0L10 11.819l-2.651 3.029c-.469.469-1.229.469-1.697 0-.469-.469-.469-1.229 0-1.697l2.758-3.15-2.759-3.152c-.469-.469-.469-1.228 0-1.697.469-.469 1.228-.469 1.697 0L10 8.183l2.651-3.031c.469-.469 1.228-.469 1.697 0 .469.469.469 1.229 0 1.697l-2.758 3.152 2.758 3.15c.469.469.469 1.229 0 1.698z"})),V().createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow"},V().createElement("path",{d:"M13.25 10L6.109 2.58c-.268-.27-.268-.707 0-.979.268-.27.701-.27.969 0l7.83 7.908c.268.271.268.709 0 .979l-7.83 7.908c-.268.271-.701.27-.969 0-.268-.269-.268-.707 0-.979L13.25 10z"})),V().createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow-down"},V().createElement("path",{d:"M17.418 6.109c.272-.268.709-.268.979 0s.271.701 0 .969l-7.908 7.83c-.27.268-.707.268-.979 0l-7.908-7.83c-.27-.268-.27-.701 0-.969.271-.268.709-.268.979 0L10 13.25l7.418-7.141z"})),V().createElement("symbol",{viewBox:"0 0 20 20",id:"large-arrow-up"},V().createElement("path",{d:"M 17.418 14.908 C 17.69 15.176 18.127 15.176 18.397 14.908 C 18.667 14.64 18.668 14.207 18.397 13.939 L 10.489 6.109 C 10.219 5.841 9.782 5.841 9.51 6.109 L 1.602 13.939 C 1.332 14.207 1.332 14.64 1.602 14.908 C 1.873 15.176 2.311 15.176 2.581 14.908 L 10 7.767 L 17.418 14.908 Z"})),V().createElement("symbol",{viewBox:"0 0 24 24",id:"jump-to"},V().createElement("path",{d:"M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z"})),V().createElement("symbol",{viewBox:"0 0 24 24",id:"expand"},V().createElement("path",{d:"M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"})))))};var Cr=n(2552),xr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"render",value:function(){var e=this.props,t=e.errSelectors,n=e.specSelectors,r=e.getComponent,a=r("SvgAssets"),o=r("InfoContainer",!0),s=r("VersionPragmaFilter"),l=r("operations",!0),i=r("Models",!0),c=r("Row"),u=r("Col"),p=r("errors",!0),d=r("ServersContainer",!0),m=r("SchemesContainer",!0),h=r("AuthorizeBtnContainer",!0),f=r("FilterContainer",!0),g=n.isSwagger2(),v=n.isOAS3(),y=!n.specStr(),E=n.loadingStatus(),S=null;if("loading"===E&&(S=V().createElement("div",{className:"info"},V().createElement("div",{className:"loading-container"},V().createElement("div",{className:"loading"})))),"failed"===E&&(S=V().createElement("div",{className:"info"},V().createElement("div",{className:"loading-container"},V().createElement("h4",{className:"title"},"Failed to load API definition."),V().createElement(p,null)))),"failedConfig"===E){var b=t.lastError(),C=b?b.get("message"):"";S=V().createElement("div",{className:"info failed-config"},V().createElement("div",{className:"loading-container"},V().createElement("h4",{className:"title"},"Failed to load remote configuration."),V().createElement("p",null,C)))}if(!S&&y&&(S=V().createElement("h4",null,"No API definition provided.")),S)return V().createElement("div",{className:"swagger-ui"},V().createElement("div",{className:"loading-container"},S));var x=n.servers(),w=n.schemes(),_=x&&x.size,A=w&&w.size,k=!!n.securityDefinitions();return V().createElement("div",{className:"swagger-ui"},V().createElement(a,null),V().createElement(s,{isSwagger2:g,isOAS3:v,alsoShow:V().createElement(p,null)},V().createElement(p,null),V().createElement(c,{className:"information-container"},V().createElement(u,{mobile:12},V().createElement(o,null))),_||A||k?V().createElement("div",{className:"scheme-container"},V().createElement(u,{className:"schemes wrapper",mobile:12},_?V().createElement(d,null):null,A?V().createElement(m,null):null,k?V().createElement(h,null):null)):null,V().createElement(f,null),V().createElement(c,null,V().createElement(u,{mobile:12,desktop:12},V().createElement(l,null))),V().createElement(c,null,V().createElement(u,{mobile:12,desktop:12},V().createElement(i,null)))))}}]),n}(V().Component);const wr=require("react-debounce-input");var _r=n.n(wr),Ar={value:"",onChange:function(){},schema:{},keyName:"",required:!1,errors:(0,L.List)()},kr=function(e){Se()(n,e);var t=Ce()(n);function n(){return b()(this,n),t.apply(this,arguments)}return x()(n,[{key:"componentDidMount",value:function(){var e=this.props,t=e.dispatchInitialValue,n=e.value,r=e.onChange;t?r(n):!1===t&&r("")}},{key:"render",value:function(){var e,t=this.props,n=t.schema,r=t.errors,a=t.value,o=t.onChange,s=t.getComponent,i=t.fn,c=t.disabled,u=n&&n.get?n.get("format"):null,p=n&&n.get?n.get("type"):null,d=function(e){return s(e,!1,{failSilently:!0})},m=p?d(u?l()(e="JsonSchema_".concat(p,"_")).call(e,u):"JsonSchema_".concat(p)):s("JsonSchema_string");return m||(m=s("JsonSchema_string")),V().createElement(m,En()({},this.props,{errors:r,fn:i,getComponent:s,value:a,onChange:o,schema:n,disabled:c}))}}]),n}(j.Component);E()(kr,"defaultProps",Ar);var Nr=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s0),v=o.getIn(["items","enum"]),y=o.getIn(["items","type"]),E=o.getIn(["items","format"]),S=o.get("items"),b=!1,C="file"===y||"string"===y&&"binary"===E;y&&E?u=r(l()(d="JsonSchema_".concat(y,"_")).call(d,E)):"boolean"!==y&&"array"!==y&&"object"!==y||(u=r("JsonSchema_".concat(y)));if(u||C||(b=!0),v){var x=r("Select");return V().createElement(x,{className:s.length?"invalid":"",title:s.length?s:"",multiple:!0,value:f,disabled:c,allowedValues:v,allowEmptyValue:!a,onChange:this.onEnumChange})}var w=r("Button");return V().createElement("div",{className:"json-schema-array"},g?M()(f).call(f,(function(e,n){var a,o=(0,L.fromJS)($t()(M()(a=p()(s).call(s,(function(e){return e.index===n}))).call(a,(function(e){return e.error}))));return V().createElement("div",{key:n,className:"json-schema-form-item"},C?V().createElement(Rr,{value:e,onChange:function(e){return t.onItemChange(e,n)},disabled:c,errors:o,getComponent:r}):b?V().createElement(qr,{value:e,onChange:function(e){return t.onItemChange(e,n)},disabled:c,errors:o}):V().createElement(u,En()({},t.props,{value:e,onChange:function(e){return t.onItemChange(e,n)},disabled:c,errors:o,schema:S,getComponent:r,fn:i})),c?null:V().createElement(w,{className:"btn btn-sm json-schema-form-item-remove ".concat(h.length?"invalid":null),title:h.length?h:"",onClick:function(){return t.removeItem(n)}}," - "))})):null,c?null:V().createElement(w,{className:"btn btn-sm json-schema-form-item-add ".concat(m.length?"invalid":null),title:m.length?m:"",onClick:this.addItem},"Add ",y?"".concat(y," "):"","item"))}}]),n}(j.PureComponent);E()(Ir,"defaultProps",Ar);var qr=function(e){Se()(n,e);var t=Ce()(n);function n(){var e,r;b()(this,n);for(var a=arguments.length,o=new Array(a),s=0;s + + + Swagger UI: OAuth2 Redirect + + + + + diff --git a/beef/index.html b/beef/index.html new file mode 100644 index 00000000000..c83e64756ad --- /dev/null +++ b/beef/index.html @@ -0,0 +1,933 @@ + + + + + + + + + + + + + + +Beef - Faraday + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Beef

+

This plugin can be set from Faraday's Plugin Configuration, where the information of the BeEF's server and RESTful AuthKey:

+

[AuthKey]
+[Host]

+

+

By default this plugin is disabled, change the enable boolean in order to use it

+

The information required for connecting to BeEF is generated when you start it:

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/faraday-cli/index.html b/faraday-cli/index.html new file mode 100644 index 00000000000..87f05196367 --- /dev/null +++ b/faraday-cli/index.html @@ -0,0 +1,931 @@ + + + + + + + + + + + + + + +Faraday Cli - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Faraday CLI

+

Use Faraday directly from your favorite terminal. faraday-cli is the official client that make automating your security workflows, easier.

+

Check our documentation to get more information.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/faraday-dispatcher-v4/index.html b/faraday-dispatcher-v4/index.html new file mode 100644 index 00000000000..e293260df27 --- /dev/null +++ b/faraday-dispatcher-v4/index.html @@ -0,0 +1,952 @@ + + + + + + + + + + + + +Faraday Dispatcher - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Faraday Dispatcher

+

Faraday Agents Dispatcher helps user develop integrations with Faraday written in any language.

+

Integrating systems is an elusive but mandatory job in any software product's life. Developers have to deal with languages they don't know, undocumented APIs or new paradigms. This leads to the fact that many product teams decide not to open the possibility to integrate to them.

+

The following documentation will allow the users to integrate using agents with other tools.

+

Documentation

+

For more info on how to use it, check our [documentation][doc]

+ +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/files/faraday_swagger.json b/files/faraday_swagger.json new file mode 100644 index 00000000000..e8a1d3da3b9 --- /dev/null +++ b/files/faraday_swagger.json @@ -0,0 +1,11451 @@ +{ + "info": { + "description": "The Faraday REST API enables you to interact with [our server](https://github.com/infobyte/faraday).\nUse this API to interact or integrate with Faraday server. This page documents the REST API, with HTTP response codes and example requests and responses.", + "title": "Faraday 5.0.0 API", + "version": "v3" + }, + "security": { + "basicAuth": [] + }, + "servers": [ + { + "url": "http://localhost:5985/_api" + } + ], + "paths": { + "/login": {}, + "/confirmation": { + "get": { + "tags": [ + "User", + "2FA" + ], + "description": "Confirm a login by 2FA token", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "post": { + "tags": [ + "User", + "2FA" + ], + "description": "Confirm a login by 2FA token", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/logout": {}, + "/verify": {}, + "/change": {}, + "/v3/ws/{workspace_name}/commands/activity_feed": { + "get": { + "tags": [ + "Command" + ], + "description": "Gets a summary of the latest executed commands", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/commands/count": { + "get": { + "tags": [ + "Command" + ], + "summary": "Group Command by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/commands/{object_id}": { + "delete": { + "tags": [ + "Command" + ], + "summary": "Deletes Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Command" + ], + "summary": "Retrieves Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Command" + ], + "summary": "Updates Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + }, + "put": { + "tags": [ + "Command" + ], + "summary": "Updates Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/commands": { + "get": { + "tags": [ + "Command" + ], + "summary": "Get a list of Command.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + }, + "post": { + "tags": [ + "Command" + ], + "summary": "Creates Command", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/commands/last": { + "get": { + "tags": [ + "Command" + ], + "description": "Gets the last executed command", + "responses": { + "200": { + "description": "Last executed command or an empty json" + } + } + } + }, + "/v3/global_commands/{object_id}": { + "get": { + "tags": [ + "Command" + ], + "summary": "Retrieves Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "/v3/global_commands": { + "get": { + "tags": [ + "Command" + ], + "summary": "Get a list of Command.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "/v3/global_hosts": { + "get": { + "tags": [ + "host" + ], + "summary": "Retrieves host counts", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "total_hosts": "int" + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/activities/count": { + "get": { + "tags": [ + "Command" + ], + "summary": "Group Command by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/activities/{object_id}": { + "delete": { + "tags": [ + "Command" + ], + "summary": "Deletes Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Command" + ], + "summary": "Retrieves Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Command" + ], + "summary": "Updates Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + } + } + }, + "put": { + "tags": [ + "Command" + ], + "summary": "Updates Command", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/activities": { + "get": { + "tags": [ + "Command" + ], + "summary": "Get a list of Command.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + } + } + }, + "post": { + "tags": [ + "Command" + ], + "summary": "Creates Command", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ActivityFeed" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/credential": { + "delete": { + "tags": [ + "Credential" + ], + "summary": "Delete a group of Credential by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "patch": { + "tags": [ + "Credential" + ], + "summary": "Delete a group of Credential by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Credential" + ], + "summary": "Get a list of Credential.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + } + } + }, + "post": { + "tags": [ + "Credential" + ], + "summary": "Creates Credential", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/credential/count": { + "get": { + "tags": [ + "Credential" + ], + "summary": "Group Credential by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/credential/{object_id}": { + "delete": { + "tags": [ + "Credential" + ], + "summary": "Deletes Credential", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Credential" + ], + "summary": "Retrieves Credential", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Credential" + ], + "summary": "Updates Credential", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + } + } + }, + "put": { + "tags": [ + "Credential" + ], + "summary": "Updates Credential", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Credential" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/bulk_create": { + "post": { + "tags": [ + "Bulk", + "Host" + ], + "description": "Creates hosts in bulk", + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/hosts": { + "delete": { + "tags": [ + "Host" + ], + "summary": "Delete a group of Host by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "patch": { + "tags": [ + "Host" + ], + "summary": "Delete a group of Host by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "summary": "Get a list of hosts.", + "tags": [ + "Host" + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + } + } + }, + "post": { + "tags": [ + "Host" + ], + "summary": "Creates Host", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/count": { + "get": { + "tags": [ + "Host" + ], + "summary": "Group Host by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/count_multi_workspace": { + "get": { + "tags": [ + "Host" + ], + "summary": "Count Host by multiples workspaces", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "400": { + "description": "No workspace passed or group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/countVulns": { + "get": { + "tags": [ + "Host" + ], + "summary": "Counts Vulnerabilities per host", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HostCount" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/countDetailed": { + "get": { + "tags": [ + "Host" + ], + "summary": "Counts Vulnerabilities per host, with detailed info", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HostDetailedCount" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/{object_id}": { + "delete": { + "tags": [ + "Host" + ], + "summary": "Deletes Host", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Host" + ], + "summary": "Retrieves Host", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Host" + ], + "summary": "Updates Host", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + } + } + }, + "put": { + "tags": [ + "Host" + ], + "summary": "Updates Host", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Host" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/filter": { + "get": { + "tags": [ + "Filter", + "Host" + ], + "description": "Filters, sorts and groups hosts using a json with parameters. These parameters must be part of the model.", + "parameters": [ + { + "in": "query", + "name": "q", + "description": "Recursive json with filters that supports operators. The json could also contain sort and group." + } + ], + "responses": { + "200": { + "description": "Returns filtered, sorted and grouped results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlaskRestless" + } + } + } + }, + "400": { + "description": "Invalid q was sent to the server" + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/{host_id}/services": { + "get": { + "tags": [ + "Host", + "Service" + ], + "summary": "Get the services of a host", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/set_tags": { + "post": { + "tags": [ + "Tag", + "Host" + ], + "description": "Set multiples tags to multiples hosts", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/hosts/{host_id}/tools_history": { + "get": { + "tags": [ + "Host", + "Command" + ], + "summary": "Get the command impacted by a host", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Command" + } + } + } + } + } + } + }, + "/v3/info": { + "get": { + "tags": [ + "Informational" + ], + "description": "Gives basic info about the faraday service", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/config": { + "get": { + "tags": [ + "Informational" + ], + "description": "Gives basic info about the faraday configuration", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/logo": { + "get": { + "tags": [ + "File" + ], + "description": "Get the logo file", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/licenses/{object_id}": { + "delete": { + "tags": [ + "License" + ], + "summary": "Deletes License", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "License" + ], + "summary": "Retrieves License", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + } + } + }, + "patch": { + "tags": [ + "License" + ], + "summary": "Updates License", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + } + } + }, + "put": { + "tags": [ + "License" + ], + "summary": "Updates License", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + } + } + } + }, + "/v3/licenses": { + "get": { + "tags": [ + "License" + ], + "summary": "Get a list of License.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + } + } + }, + "post": { + "tags": [ + "License" + ], + "summary": "Creates License", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/License" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/services": { + "delete": { + "tags": [ + "Service" + ], + "summary": "Delete a group of Service by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "patch": { + "tags": [ + "Service" + ], + "summary": "Delete a group of Service by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Service" + ], + "summary": "Get a list of Service.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + } + }, + "post": { + "tags": [ + "Service" + ], + "summary": "Creates Service", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/services/count": { + "get": { + "tags": [ + "Service" + ], + "summary": "Group Service by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/services/{object_id}": { + "delete": { + "tags": [ + "Service" + ], + "summary": "Deletes Service", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Service" + ], + "summary": "Retrieves Service", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Service" + ], + "summary": "Updates Service", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + } + }, + "put": { + "tags": [ + "Service" + ], + "summary": "Updates Service", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Service" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/services/summary": { + "get": { + "tags": [ + "Service" + ], + "summary": "Get a summary of service of the workspace", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ServiceSummary" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/services/set_tags": { + "post": { + "tags": [ + "Tag", + "Service" + ], + "description": "Set multiples tags to multiples services", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/session": { + "get": { + "tags": [ + "Informational" + ], + "description": "Gives info about the current session", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/duplicates/associate": { + "post": { + "tags": [ + "Duplicate", + "Vulnerability" + ], + "description": "Disassociate a vulnerability as duplicated", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Vulnerability not found" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns": { + "delete": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Delete a group of VulnerabilityGeneric by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "patch": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Delete a group of VulnerabilityGeneric by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Get a list of VulnerabilityGeneric.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + } + } + }, + "post": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Creates VulnerabilityGeneric", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/count": { + "get": { + "tags": [ + "Vulnerability" + ], + "summary": "Group vulnerabilities by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/count_multi_workspace": { + "get": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Count VulnerabilityGeneric by multiples workspaces", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + }, + "400": { + "description": "No workspace passed or group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/{object_id}": { + "delete": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Deletes VulnerabilityGeneric", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Retrieves VulnerabilityGeneric", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + } + } + }, + "patch": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Updates VulnerabilityGeneric", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/{vuln_id}/attachment/{attachment_filename}": { + "delete": { + "tags": [ + "Vulnerability", + "File" + ], + "description": "Remove a vuln attachment", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Vulnerability", + "File" + ], + "description": "Get a vuln attachment", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/duplicates/disassociate": { + "post": { + "tags": [ + "Duplicate", + "Vulnerability" + ], + "description": "Disassociate a vulnerability as duplicated", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Vulnerability not found" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/export_csv": { + "get": { + "tags": [ + "Vulnerability", + "File" + ], + "description": "Get a CSV file with all vulns from a workspace", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/filter": { + "get": { + "tags": [ + "Filter", + "Vulnerability" + ], + "description": "Filters, sorts and groups vulnerabilities using a json with parameters. These parameters must be part of the model.", + "parameters": [ + { + "in": "query", + "name": "q", + "description": "Recursive json with filters that supports operators. The json could also contain sort and group." + } + ], + "responses": { + "200": { + "description": "Returns filtered, sorted and grouped results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlaskRestless" + } + } + } + }, + "400": { + "description": "Invalid q was sent to the server" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/{vuln_id}/duplicates": { + "get": { + "tags": [ + "Duplicate", + "Vulnerability" + ], + "summary": "Get all duplicates from the given vulnerability", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/{vuln_id}/attachment": { + "get": { + "tags": [ + "Vulnerability", + "File" + ], + "description": "Gets an attachment for a vulnerability", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/File" + } + } + } + }, + "403": { + "description": "Workspace disabled or no permission" + }, + "404": { + "description": "Not Found" + } + } + }, + "post": { + "tags": [ + "Vulnerability", + "File" + ], + "description": "Creates a new attachment in the vuln", + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/duplicates/mark_as_main": { + "post": { + "tags": [ + "Duplicate", + "Vulnerability" + ], + "description": "Mark a vulnerability as main", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "Vulnerability not found" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/{vuln_id}/enrichment": { + "post": { + "tags": [ + "Vulnerability", + "Enrichment" + ], + "description": "Update vulnerability enrichment and risk data", + "responses": { + "200": { + "description": "Ok" + }, + "404": { + "description": "Vulnerability not found" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/set_tags": { + "post": { + "tags": [ + "Tag", + "Vulnerability" + ], + "description": "Set multiples tags to multiples vulnerabilities", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/{vuln_id}/status": { + "post": { + "tags": [ + "Vulnerability", + "Deprecated" + ], + "description": "Set status to a vulnerability. DEPRECATED, TO BE REMOVED in 3.18.0", + "responses": { + "201": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/timeline": { + "get": { + "tags": [ + "Vulnerability" + ], + "summary": "Get a timeline of creation of vulnerabilities", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns/top_users": { + "get": { + "tags": [ + "Vulnerability" + ], + "params": "limit", + "description": "Gets a list of top users having account its uploaded vulns", + "responses": { + "200": { + "description": "List of top users" + } + } + } + }, + "/v3/vulnerability_template/bulk_create": { + "post": { + "tags": [ + "Bulk", + "VulnerabilityTemplate" + ], + "description": "Creates Vulnerability templates in bulk", + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/vulnerability_template": { + "delete": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Delete a group of VulnerabilityTemplate by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "patch": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Update a group of VulnerabilityTemplate by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Get a list of VulnerabilityTemplate.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + } + } + }, + "post": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Creates VulnerabilityTemplate", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + } + } + } + }, + "/v3/vulnerability_template/{object_id}": { + "delete": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Deletes VulnerabilityTemplate", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Retrieves VulnerabilityTemplate", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + } + } + }, + "patch": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Updates VulnerabilityTemplate", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + } + } + }, + "put": { + "tags": [ + "VulnerabilityTemplate" + ], + "summary": "Updates VulnerabilityTemplate", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityTemplate" + } + } + } + } + } + } + }, + "/v3/vulnerability_template/filter": { + "get": { + "tags": [ + "Filter", + "VulnerabilityTemplate" + ], + "description": "Filters, sorts and groups non workspaced objects using a json with parameters. These parameters must be part of the model.", + "parameters": [ + { + "in": "query", + "name": "q", + "description": "Recursive json with filters that supports operators. The json could also contain sort and group." + } + ], + "responses": { + "200": { + "description": "Returns filtered, sorted and grouped results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlaskRestless" + } + } + } + }, + "400": { + "description": "Invalid q was sent to the server" + } + } + } + }, + "/v3/ws": { + "delete": { + "tags": [ + "Workspace" + ], + "summary": "Delete a group of Workspace by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "summary": "Get a list of workspaces.", + "tags": [ + "Workspace" + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + } + } + }, + "post": { + "tags": [ + "Workspace" + ], + "summary": "Creates Workspace", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + } + } + } + }, + "/v3/ws/{object_id}": { + "delete": { + "tags": [ + "Workspace" + ], + "summary": "Deletes Workspace", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Workspace" + ], + "summary": "Retrieves Workspace", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Workspace" + ], + "summary": "Updates Workspace", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + } + } + }, + "put": { + "tags": [ + "Workspace" + ], + "summary": "Updates Workspace", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Workspace" + } + } + } + } + } + } + }, + "/v3/ws/filter": { + "get": { + "tags": [ + "Filter" + ], + "summary": "Filters, sorts and groups objects using a json with parameters.", + "parameters": [ + { + "in": "query", + "name": "q", + "description": "recursive json with filters that supports operators. The json could also contain sort and group" + } + ], + "responses": { + "200": { + "description": "return filtered, sorted and grouped results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlaskRestless" + } + } + } + }, + "400": { + "description": "invalid q was sent to the server" + } + } + } + }, + "/v3/ws/{workspace_name}/users": { + "get": { + "tags": [ + "Workspace", + "User" + ], + "summary": "Get list of users of the workspace", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_id}/most_used_tools": { + "get": { + "tags": [ + "Workspace" + ], + "summary": "Get top 10 most used tools", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MostUsedTools" + } + } + } + } + } + } + }, + "/v3/users/{object_id}": { + "delete": { + "tags": [ + "User" + ], + "summary": "Deletes User", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "User" + ], + "summary": "Retrieves User", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "patch": { + "tags": [ + "User" + ], + "summary": "Updates User", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "put": { + "tags": [ + "User" + ], + "summary": "Updates User", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + }, + "/v3/users/{user_id}/disable2fa": { + "post": { + "tags": [ + "2FA", + "User" + ], + "summary": "Disable 2FA of the given user", + "responses": { + "200": { + "description": "Ok" + }, + "403": { + "description": "forbidden" + } + } + } + }, + "/v3/users/filter": { + "get": { + "tags": [ + "Filter", + "User" + ], + "description": "Filters, sorts and groups non workspaced objects using a json with parameters. These parameters must be part of the model.", + "parameters": [ + { + "in": "query", + "name": "q", + "description": "Recursive json with filters that supports operators. The json could also contain sort and group." + } + ], + "responses": { + "200": { + "description": "Returns filtered, sorted and grouped results", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/FlaskRestless" + } + } + } + }, + "400": { + "description": "Invalid q was sent to the server" + } + } + } + }, + "/v3/users": { + "get": { + "tags": [ + "User" + ], + "summary": "Get a list of User.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + }, + "post": { + "tags": [ + "User" + ], + "summary": "Creates User", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + }, + "/v3/users/list_usernames": { + "get": { + "tags": [ + "User" + ], + "summary": "Get list of usernames", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/users/{user_id}/request2fa": { + "post": { + "tags": [ + "2FA", + "User" + ], + "summary": "Set 2FA as required for the given user", + "responses": { + "200": { + "description": "Ok" + }, + "403": { + "description": "forbidden" + } + } + } + }, + "/v3/2fa/confirm": { + "post": { + "tags": [ + "2FA" + ], + "summary": "Confirm 2FA as required for the current user", + "responses": { + "200": { + "description": "Ok" + }, + "403": { + "description": "Some passed data is incorrect" + } + } + } + }, + "/v3/2fa/disable": { + "post": { + "tags": [ + "2FA" + ], + "summary": "Disable 2FA for the current user", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/2fa/qrcode": { + "get": { + "tags": [ + "2FA" + ], + "summary": "Get QR to set 2FA", + "responses": { + "200": { + "description": "Ok" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/2fa/request": { + "post": { + "tags": [ + "2FA" + ], + "summary": "Set 2FA as required for the current user", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/comment": { + "delete": { + "tags": [ + "Comment" + ], + "summary": "Delete a group of Comment by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Comment" + ], + "summary": "Get a list of Comment.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + }, + "post": { + "tags": [ + "Comment" + ], + "summary": "Creates Comment", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/comment/count": { + "get": { + "tags": [ + "Comment" + ], + "summary": "Group Comment by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/comment/{object_id}": { + "delete": { + "tags": [ + "Comment" + ], + "summary": "Deletes Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Comment" + ], + "summary": "Retrieves Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Comment" + ], + "summary": "Updates Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + }, + "put": { + "tags": [ + "Comment" + ], + "summary": "Updates Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/comment/{object_type}/{object_id}": { + "get": { + "tags": [ + "Comment", + "Host", + "Service", + "Vulnerability" + ], + "summary": "Get all the comment from the given object. object can be Host, Service, Vulnerability or Comment", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "404": { + "description": "Object not found" + } + } + } + }, + "/v3/comment": { + "delete": { + "tags": [ + "Comment" + ], + "summary": "Delete a group of Comment by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Comment" + ], + "summary": "Get a list of Comment.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + }, + "post": { + "tags": [ + "Comment" + ], + "summary": "Creates Comment", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + } + }, + "/v3/comment/{object_id}": { + "delete": { + "tags": [ + "Comment" + ], + "summary": "Deletes Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Comment" + ], + "summary": "Retrieves Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Comment" + ], + "summary": "Updates Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + }, + "put": { + "tags": [ + "Comment" + ], + "summary": "Updates Comment", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + } + }, + "/v3/comment/{object_type}/{object_id}": { + "get": { + "tags": [ + "Comment", + "ProjectTask" + ], + "summary": "Get all the comment from the given object. object can be ProjectTask or Comment", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "404": { + "description": "Object not found" + } + } + } + }, + "/v3/ws/{workspace_name}/comment_unique": { + "post": { + "tags": [ + "Comment" + ], + "summary": "Creates Comment", + "parameters": [ + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Comment" + } + } + } + } + } + } + }, + "/v3/vulners/exploits/{cveid}": { + "get": { + "tags": [ + "Vulnerability" + ], + "description": "Use Vulns API to get all exploits available for a specific CVE-ID", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/{report_id}/clone": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Clone the given Executive report", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/count": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Group ExecutiveReport by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/countVulns": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Counts Vulnerabilities for given report", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReportCount" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/reports/{object_id}": { + "delete": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Deletes ExecutiveReport", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Retrieves ExecutiveReport", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + } + } + }, + "patch": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Updates ExecutiveReport", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + } + } + }, + "put": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Updates ExecutiveReport", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/reports/delete_template": { + "delete": { + "tags": [ + "File" + ], + "description": "Deletes an executive report custom template file", + "responses": { + "200": { + "description": "Created" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/{report_id}/download": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Download the given Executive report", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/download_template": { + "get": { + "tags": [ + "File" + ], + "description": "Downloads an executive report custom template file", + "responses": { + "200": { + "description": "Created" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + }, + "404": { + "description": "File not found" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/{report_id}/custom_logo": { + "get": { + "tags": [ + "ExecutionReport", + "File" + ], + "description": "Get the custom logo of a report", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Get a list of ExecutiveReport.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ExecutiveReport" + } + } + } + } + } + }, + "post": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Post Report", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/info_template": { + "post": { + "tags": [ + "File" + ], + "description": "Tests an executive report custom template file", + "responses": { + "200": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/{report_id}/regenerate": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "Regenerate the given Executive report", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/listTemplates": { + "get": { + "tags": [ + "ExecutiveReport" + ], + "summary": "List all executive report templates", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/test_template": { + "post": { + "tags": [ + "File" + ], + "description": "Tests an executive report template file", + "responses": { + "200": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/reports/upload_template": { + "post": { + "tags": [ + "File" + ], + "description": "Uploads an executive report custom template file", + "responses": { + "200": { + "description": "Created" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/tags/host_tags": { + "get": { + "summary": "Get the list of tags of hosts of a given workspace.", + "tags": [ + "Tag" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/tags": { + "get": { + "summary": "Get the list of tags of vuln of a given workspace.", + "tags": [ + "Tag" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/tags/service_tags": { + "get": { + "summary": "Get the list of tags of service of a given workspace.", + "tags": [ + "Tag" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/upload_report": { + "post": { + "tags": [ + "Workspace", + "File" + ], + "description": "Upload a report file to create data within the given workspace", + "responses": { + "201": { + "description": "Created" + }, + "400": { + "description": "Bad request" + }, + "403": { + "description": "Forbidden" + } + } + } + }, + "/v3/ws/{workspace_name}/websocket_token": { + "post": { + "get": { + "tags": [ + "Token" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "get": { + "tags": [ + "Token" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/mult_websocket_token": { + "post": { + "get": { + "tags": [ + "Token" + ], + "description": "Get a list of token for notifications of multiple workspaces", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "get": { + "tags": [ + "Token" + ], + "description": "Get a list of token for notifications of multiple workspaces", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/agent_websocket_token": { + "post": { + "tags": [ + "Token", + "Agent" + ], + "description": "Gives a token to establish a websocket connection. For agents logic only", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/vulns-threadfix": { + "get": { + "tags": [ + "VulnerabilityGeneric" + ], + "summary": "Get a list of VulnerabilityGeneric.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VulnerabilityWeb" + } + } + } + } + } + } + }, + "/v3/custom_fields_schema": { + "delete": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Delete a group of CustomFieldsSchema by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Get a list of CustomFieldsSchema.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + } + } + }, + "post": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Creates CustomFieldsSchema", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + } + } + } + }, + "/v3/custom_fields_schema/{object_id}": { + "delete": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Deletes CustomFieldsSchema", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Retrieves CustomFieldsSchema", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + } + } + }, + "patch": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Updates CustomFieldsSchema", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + } + } + }, + "put": { + "tags": [ + "CustomFieldsSchema" + ], + "summary": "Updates CustomFieldsSchema", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CustomFieldsSchema" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/notification/count": { + "get": { + "tags": [ + "Notification" + ], + "summary": "Group Notification by the field set in the group_by GET parameter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + }, + "404": { + "description": "group_by is not specified" + } + } + } + }, + "/v3/ws/{workspace_name}/notification/{object_id}": { + "get": { + "tags": [ + "Notification" + ], + "summary": "Retrieves Notification", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Notification" + ], + "summary": "Updates Notification", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + }, + "put": { + "tags": [ + "Notification" + ], + "summary": "Updates Notification", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + }, + { + "in": "path", + "name": "workspace_name", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/notification": { + "get": { + "tags": [ + "Notification" + ], + "summary": "Get a list of Notification.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + }, + "delete": { + "summary": "Delete all notifications.", + "tags": [ + "Notification" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/ws/{workspace_name}/notification/mark_as_read_all": { + "get": { + "summary": "Mark all notifications as read.", + "tags": [ + "Notification" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/notifications/{object_id}": { + "get": { + "tags": [ + "Notification" + ], + "summary": "Retrieves Notification", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + }, + "/v3/notifications": { + "get": { + "tags": [ + "Notification" + ], + "summary": "Get a list of Notification.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + }, + "/v3/agents/active_agents": { + "get": { + "tags": [ + "Agent" + ], + "summary": "Get all manifests, Optionally choose latest version with parameter", + "parameters": [ + { + "in": "version", + "name": "agent_version", + "description": "latest version to request" + } + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/agents/{object_id}": { + "delete": { + "tags": [ + "Agent" + ], + "summary": "Deletes Agent", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Agent" + ], + "summary": "Retrieves Agent", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Agent" + ], + "summary": "Updates Agent", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + } + } + }, + "put": { + "tags": [ + "Agent" + ], + "summary": "Updates Agent", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + } + } + } + }, + "/v3/agents": { + "get": { + "tags": [ + "Agent" + ], + "summary": "Get a list of Agent.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + } + } + } + }, + "/v3/agents/get_manifests": { + "get": { + "tags": [ + "Agent" + ], + "summary": "Get all manifests, Optionally choose latest version with parameter", + "parameters": [ + { + "in": "version", + "name": "agent_version", + "description": "latest version to request" + } + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/agents/{agent_id}/run": { + "post": { + "tags": [ + "Agent" + ], + "description": "Runs an agent", + "responses": { + "400": { + "description": "Bad request" + }, + "201": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Agent" + } + } + } + } + } + } + }, + "/v3/agent_token": { + "get": { + "summary": "Get the current TOTP token to register new agents.", + "tags": [ + "Agent" + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentAuthToken" + } + } + } + } + } + } + }, + "/v3/ws/{workspace_name}/bulk_create": { + "post": { + "tags": [ + "Bulk" + ], + "description": "Creates all faraday objects in bulk for a workspace", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkCreate" + } + } + } + }, + "responses": { + "201:tags": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/BulkCreate" + } + } + } + }, + "401": { + "$ref": "#/components/responses/UnauthorizedError" + }, + "403": { + "description": "Disabled workspace" + }, + "404": { + "description": "Workspace not found" + } + } + } + }, + "/v3/token": { + "get": { + "tags": [ + "Token" + ], + "description": "Gets a new user token", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/searchfilter": { + "delete": { + "tags": [ + "SearchFilter" + ], + "summary": "Delete a group of SearchFilter by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "patch": { + "tags": [ + "SearchFilter" + ], + "summary": "Update a group of SearchFilter by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "SearchFilter" + ], + "summary": "Get a list of SearchFilter.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + } + } + }, + "post": { + "tags": [ + "SearchFilter" + ], + "summary": "Creates SearchFilter", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + } + } + } + }, + "/v3/searchfilter/{object_id}": { + "delete": { + "tags": [ + "SearchFilter" + ], + "summary": "Deletes SearchFilter", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "SearchFilter" + ], + "summary": "Retrieves SearchFilter", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + } + } + }, + "patch": { + "tags": [ + "SearchFilter" + ], + "summary": "Updates SearchFilter", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + } + } + }, + "put": { + "tags": [ + "SearchFilter" + ], + "summary": "Updates SearchFilter", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SearchFilter" + } + } + } + } + } + } + }, + "/v3/preferences": { + "get": { + "tags": [ + "User" + ], + "description": "Show the user preferences", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "post": { + "set": { + "tags": [ + "User" + ], + "description": "Set the user preferences", + "responses": { + "200": { + "description": "Ok" + } + } + } + } + }, + "/v3/ws/{workspace_name}/export_data": { + "get": { + "tags": [ + "File", + "Workspace" + ], + "description": "Exports all the workspace data in a XML file", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/logs": { + "get": { + "tags": [ + "File" + ], + "description": "Get a recompilation of logs file", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/auth/forgot_password": { + "post": { + "tags": [ + "User" + ], + "description": "Send a token within an email to the user for password recovery", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/auth/reset_password/{token}": { + "post": { + "tags": [ + "User" + ], + "description": "Reset the user's password based on the given token", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/jobs/{job_id}/clone": { + "post": { + "tags": [ + "Job" + ], + "summary": "Clone job", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/jobs/{object_id}": { + "delete": { + "tags": [ + "Workflow" + ], + "summary": "Deletes Workflow", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Workflow" + ], + "summary": "Retrieves Workflow", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Workflow" + ], + "summary": "Updates Workflow", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + } + } + }, + "put": { + "tags": [ + "Workflow" + ], + "summary": "Updates Workflow", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + } + } + } + }, + "/v3/jobs/{job_id}/enabled": { + "get": { + "tags": [ + "Job" + ], + "summary": "Get the enabled status of a job", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/jobs/{job_id}/export_job": { + "get": { + "tags": [ + "Job" + ], + "summary": "Export job as json", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/jobs/{job_id}/tasks": { + "get": { + "tags": [ + "Job", + "Action" + ], + "summary": "Get the actions associated to a job", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + } + } + } + }, + "/v3/jobs/rules/attributes": { + "get": { + "tags": [ + "Job" + ], + "summary": "Get the Attributes for rules", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/jobs/{job_id}/conditions": { + "get": { + "tags": [ + "Job" + ], + "summary": "Get the conditions of a job", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Condition" + } + } + } + } + } + } + }, + "/v3/jobs/{job_id}/executions": { + "get": { + "tags": [ + "Job" + ], + "summary": "Get the executions of a job", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/WorkflowExecution" + } + } + } + } + } + } + }, + "/v3/jobs/import_job": { + "post": { + "get": { + "tags": [ + "Job" + ], + "summary": "Import job from json", + "responses": { + "201": { + "description": "Ok" + } + } + }, + "tags": [ + "Job" + ], + "responses": { + "201": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "Job" + ], + "summary": "Import job from json", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/jobs": { + "get": { + "tags": [ + "Workflow" + ], + "summary": "Get a list of Workflow.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + } + } + }, + "post": { + "tags": [ + "Workflow" + ], + "summary": "Creates Workflow", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + } + } + } + }, + "/v3/tasks/{object_id}": { + "delete": { + "tags": [ + "Action" + ], + "summary": "Deletes Action", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Action" + ], + "summary": "Retrieves Action", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Action" + ], + "summary": "Updates Action", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + } + } + }, + "put": { + "tags": [ + "Action" + ], + "summary": "Updates Action", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + } + } + } + }, + "/v3/tasks/fields": { + "get": { + "tags": [ + "Action" + ], + "summary": "Get the valid fields for tasks", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/tasks/{task_id}/jobs": { + "get": { + "tags": [ + "Action" + ], + "summary": "Get the jobs associated to a task", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Job" + } + } + } + } + } + } + }, + "/v3/tasks": { + "get": { + "tags": [ + "Action" + ], + "summary": "Get a list of Action.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + } + } + }, + "post": { + "tags": [ + "Action" + ], + "summary": "Creates Action", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Taskwf" + } + } + } + } + } + } + }, + "/v3/pipelines/{object_id}": { + "delete": { + "tags": [ + "Pipeline" + ], + "summary": "Deletes Pipeline", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Pipeline" + ], + "summary": "Retrieves Pipeline", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Pipeline" + ], + "summary": "Updates Pipeline", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + } + } + }, + "put": { + "tags": [ + "Pipeline" + ], + "summary": "Updates Pipeline", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + } + } + } + }, + "/v3/pipelines/{pipeline_id}/disable": { + "post": { + "tags": [ + "Pipeline" + ], + "summary": "Disable Pipeline", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/pipelines/{pipeline_id}/enable": { + "post": { + "tags": [ + "Pipeline" + ], + "summary": "Enable Pipeline and Disable all others in same Workspace", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/pipelines/{pipeline_id}/export": { + "get": { + "tags": [ + "Pipeline" + ], + "summary": "Export pipeline as json", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/pipelines/{pipeline_id}/clone": { + "post": { + "tags": [ + "Pipeline" + ], + "summary": "Clone pipeline", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/pipelines": { + "get": { + "tags": [ + "Pipeline" + ], + "summary": "Get a list of Pipeline.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + } + } + }, + "post": { + "tags": [ + "Pipeline" + ], + "summary": "Creates Pipeline", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Pipeline1" + } + } + } + } + } + } + }, + "/v3/pipelines/{pipeline_id}/run": { + "post": { + "tags": [ + "Pipeline" + ], + "summary": "Run pipeline with historical data", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/agents_schedule/{object_id}": { + "delete": { + "tags": [ + "AgentsSchedule" + ], + "summary": "Deletes AgentsSchedule", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "AgentsSchedule" + ], + "summary": "Retrieves AgentsSchedule", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + } + } + }, + "patch": { + "tags": [ + "AgentsSchedule" + ], + "summary": "Updates AgentsSchedule", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + } + } + }, + "put": { + "tags": [ + "AgentsSchedule" + ], + "summary": "Updates AgentsSchedule", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + } + } + } + }, + "/v3/agents_schedule": { + "get": { + "tags": [ + "AgentsSchedule" + ], + "summary": "Get a list of AgentsSchedule.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + } + } + }, + "post": { + "tags": [ + "AgentsSchedule" + ], + "summary": "Creates AgentsSchedule", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AgentsScheduleSchema" + } + } + } + } + } + } + }, + "/v3/agents_schedule/{schedule_id}/run": { + "post": { + "tags": [ + "Agent Schedule" + ], + "description": "Runs an agent schedule", + "responses": { + "400": { + "description": "Bad request" + }, + "201": { + "description": "Ok" + } + } + } + }, + "/v3/settings/reports": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/settings/executive_reports": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/settings/notifications": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/settings/vulnerabilities": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/settings/smtp": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/settings/saml": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/whoami": { + "get": { + "tags": [ + "User" + ], + "description": "Get basic user info used when LDAP is enabled", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/add_jira_user": { + "post": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Add a jira user to the database", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Add a jira user to the database", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "put": { + "tags": [ + "Ticketing Tools" + ], + "description": "Update config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/get_insight_objects": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Get Insight's objects from IQL string", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/get_project_saved_data": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Get Jira instance's specific project with their issuetypes and issue fields saved in database", + "params": "project_key", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/get_projects_from_jira": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Get all Jira instance's projects with their issuetypes and issue fields and save them in the database", + "params": "expand", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/oauth/authenticate/get_public_key": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Get Jira instance's public key of its RSA key pair.", + "params": "expand", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/issues": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Send an issue to Integration", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/oauth/authenticate/access_token": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Authenticate with Jira OAuth based on previously call to authentication url", + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/v3/integrations/jira/oauth/authenticate/authorize": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Ask Jira for an OAuth authentication url", + "responses": { + "201": { + "description": "Created" + } + } + } + }, + "/v3/integrations/jira/oauth/deauthenticate": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Disable OAuth authentication.", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/remove_jira_user": { + "delete": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Remove a jira user to the database", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "Remove a jira user to the database", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/jira/templates": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List Integration issue templates name", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/servicenow": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "put": { + "tags": [ + "Ticketing Tools" + ], + "description": "Update config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/servicenow/issues": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Send an issue to Integration", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/servicenow/oauth/authenticate": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Authenticate to integration using OAuth2.0", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/servicenow/oauth/deauthenticate": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Disable OAuth authentication.", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/servicenow/templates": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List Integration issue templates name", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/whd": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "put": { + "tags": [ + "Ticketing Tools" + ], + "description": "Update config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/whd/issues": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Send an issue to Integration", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/whd/templates": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List Integration issue templates name", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/gitlab": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + }, + "put": { + "tags": [ + "Ticketing Tools" + ], + "description": "Update config of a ticketing tool", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/gitlab/issues": { + "post": { + "tags": [ + "Ticketing Tools" + ], + "description": "Send an issue to Integration", + "responses": { + "201": { + "description": "Ok" + } + } + } + }, + "/v3/integrations/gitlab/templates": { + "get": { + "tags": [ + "Ticketing Tools" + ], + "description": "List Integration issue templates name", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/settings/ldap": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/analytics/clone/{analytics_id}": { + "post": { + "tags": [ + "Analytics" + ], + "description": "Clone saved graph including linked data and filters", + "responses": { + "200": { + "description": "Ok" + }, + "404": { + "description": "Analytics not found" + } + } + } + }, + "/v3/analytics/data_collection": { + "get": { + "tags": [ + "Analytics" + ], + "description": "Get linked data according to a graph type", + "responses": { + "200": { + "description": "Ok" + }, + "400": { + "description": "Bad request" + } + } + } + }, + "/v3/analytics/{object_id}": { + "delete": { + "tags": [ + "Analytics" + ], + "summary": "Deletes Analytics", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "Analytics" + ], + "summary": "Retrieves Analytics", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + } + } + }, + "patch": { + "tags": [ + "Analytics" + ], + "summary": "Updates analytics' graph", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + } + } + }, + "put": { + "tags": [ + "Analytics" + ], + "summary": "Updates Analytics", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + } + } + } + }, + "/v3/analytics": { + "get": { + "tags": [ + "Analytics" + ], + "summary": "Get a list of Analytics.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + } + } + }, + "post": { + "tags": [ + "Analytics" + ], + "summary": "Creates Analytics", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Analytics" + } + } + } + } + } + } + }, + "/v3/projects/{object_id}": { + "delete": { + "tags": [ + "PlannerProject" + ], + "summary": "Deletes PlannerProject", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "PlannerProject" + ], + "description": "Get project", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + } + } + }, + "patch": { + "tags": [ + "PlannerProject" + ], + "summary": "Updates PlannerProject", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + } + } + }, + "put": { + "tags": [ + "PlannerProject" + ], + "summary": "Updates PlannerProject", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + } + } + } + }, + "/v3/projects/{project_id}/tasks": { + "get": { + "tags": [ + "PlannerProject" + ], + "description": "Gets the tasks assigned to project", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + } + } + } + }, + "/v3/projects": { + "get": { + "tags": [ + "PlannerProject" + ], + "description": "Get projects", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + } + } + }, + "post": { + "tags": [ + "PlannerProject" + ], + "summary": "Creates PlannerProject", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Project" + } + } + } + } + } + } + }, + "/v3/ptasks/{object_id}": { + "delete": { + "tags": [ + "ProjectTask" + ], + "summary": "Deletes ProjectTask", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "ProjectTask" + ], + "description": "Gets task", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + } + } + }, + "patch": { + "tags": [ + "ProjectTask" + ], + "summary": "Updates ProjectTask", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + } + } + }, + "put": { + "tags": [ + "ProjectTask" + ], + "summary": "Updates ProjectTask", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + } + } + } + }, + "/v3/ptasks": { + "get": { + "tags": [ + "ProjectTask" + ], + "description": "Gets tasks", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + } + } + }, + "post": { + "tags": [ + "ProjectTask" + ], + "summary": "Creates ProjectTask", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ProjectTask" + } + } + } + } + } + } + }, + "/v3/swagger": { + "get": { + "summary": "Get the swagger documentation.", + "tags": [ + "Swagger" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/settings/enrichment": { + "get": { + "tags": [ + "settings" + ], + "summary": "Retrieves settings of {route_base}", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + }, + "patch": { + "tags": [ + "settings" + ], + "summary": "Creates/Updates settings of {route_base}", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "responses": { + "200": { + "description": "Created", + "content": { + "application/json": { + "schema": { + "schema_class": null + } + } + } + }, + "403": { + "description": "Admin user required" + } + } + } + }, + "/v3/slack_token": { + "get": { + "tags": [ + "UserNotification" + ], + "description": "Check if the slack token is set", + "responses": { + "200": { + "description": "Ok" + } + } + } + }, + "/v3/notification_center/{object_id}": { + "get": { + "tags": [ + "UserNotificationSettings" + ], + "summary": "Retrieves UserNotificationSettings", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + } + } + }, + "patch": { + "tags": [ + "UserNotificationSettings" + ], + "summary": "Updates UserNotificationSettings", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + } + } + }, + "put": { + "tags": [ + "UserNotificationSettings" + ], + "summary": "Updates UserNotificationSettings", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + }, + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + }, + "409": { + "description": "Duplicated key found", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NotificationCenterSchemaAdmin" + } + } + } + } + } + } + }, + "/v3/notifications_log": { + "delete": { + "tags": [ + "UserNotification" + ], + "summary": "Delete a group of UserNotification by ids.", + "responses": { + "204": { + "description": "Ok" + } + } + }, + "get": { + "tags": [ + "UserNotification" + ], + "summary": "Get a list of UserNotification.", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserNotification" + } + } + } + } + } + } + }, + "/v3/notifications_log/{object_id}": { + "delete": { + "tags": [ + "UserNotification" + ], + "summary": "Deletes UserNotification", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "204": { + "description": "The resource was deleted successfully" + } + } + }, + "get": { + "tags": [ + "UserNotification" + ], + "summary": "Retrieves UserNotification", + "parameters": [ + { + "in": "path", + "name": "object_id", + "required": true, + "schema": { + "type": "integer" + } + } + ], + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UserNotification" + } + } + } + } + } + } + }, + "/v3/notifications_log/mark_as_read": { + "post": { + "summary": "Mark notifications as read in bulk", + "tags": [ + "UserNotification" + ], + "responses": { + "200": { + "description": "Ok" + } + } + } + } + }, + "openapi": "3.0.2", + "components": { + "schemas": { + "Command": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "command": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "duration": { + "nullable": true + }, + "itime": {}, + "ip": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "hostname": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "params": { + "type": "string", + "nullable": true + }, + "user": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "creator": { + "readOnly": true + }, + "workspace": { + "readOnly": true + }, + "tool": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "import_source": { + "enum": [ + "report", + "shell", + "agent" + ], + "nullable": true, + "maxLength": 6 + }, + "metadata": {}, + "warnings": { + "type": "string", + "nullable": true, + "maxLength": 250 + } + }, + "required": [ + "command", + "itime", + "tool" + ] + }, + "ActivityFeed": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "command": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "ip": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "hostname": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "params": { + "type": "string", + "nullable": true + }, + "user": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "workspace": { + "readOnly": true + }, + "tool": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "import_source": { + "enum": [ + "report", + "shell", + "agent" + ], + "nullable": true, + "maxLength": 6 + }, + "itime": {}, + "sum_created_vulnerabilities": { + "readOnly": true, + "nullable": true + }, + "sum_created_hosts": { + "readOnly": true, + "nullable": true + }, + "sum_created_services": { + "readOnly": true, + "nullable": true + }, + "sum_created_vulnerability_critical": { + "type": "integer", + "readOnly": true + }, + "sum_created_vulnerability_high": { + "type": "integer", + "readOnly": true + }, + "sum_created_vulnerability_medium": { + "type": "integer", + "readOnly": true + }, + "sum_created_vulnerability_low": { + "type": "integer", + "readOnly": true + }, + "sum_created_vulnerability_info": { + "type": "integer", + "readOnly": true + }, + "sum_created_vulnerability_unclassified": { + "type": "integer", + "readOnly": true + }, + "creator": { + "readOnly": true + } + }, + "required": [ + "command", + "itime", + "tool" + ] + }, + "Credential": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "_id": { + "type": "integer", + "readOnly": true + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "parent": {}, + "username": { + "type": "string", + "minLength": 1 + }, + "description": { + "type": "string" + }, + "name": { + "type": "string", + "nullable": true + }, + "password": { + "type": "string" + }, + "owner": { + "type": "string", + "readOnly": true + }, + "owned": { + "type": "boolean", + "readOnly": true + }, + "couchdbid": { + "type": "string" + }, + "parent_type": {}, + "metadata": {}, + "host_ip": { + "type": "string", + "readOnly": true + }, + "service_name": { + "type": "string", + "readOnly": true + }, + "target": { + "type": "string", + "readOnly": true + } + }, + "required": [ + "parent", + "parent_type", + "username" + ] + }, + "Host": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "_id": { + "type": "integer", + "readOnly": true + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "ip": { + "type": "string" + }, + "description": { + "type": "string" + }, + "mac": { + "type": "string", + "nullable": true + }, + "credentials": { + "type": "integer", + "readOnly": true + }, + "default_gateway": { + "type": "string", + "nullable": true + }, + "metadata": {}, + "name": { + "type": "string", + "readOnly": true + }, + "os": { + "type": "string" + }, + "owned": { + "type": "boolean" + }, + "owner": { + "readOnly": true + }, + "services": { + "type": "integer", + "readOnly": true + }, + "vulns": { + "readOnly": true + }, + "hostnames": {}, + "type": { + "readOnly": true + }, + "tags": {}, + "service_summaries": { + "readOnly": true + }, + "versions": { + "readOnly": true + }, + "importance": { + "type": "integer" + }, + "severity_counts": { + "readOnly": true + }, + "command_id": { + "type": "integer", + "writeOnly": true + } + }, + "required": [ + "description" + ] + }, + "HostCount": { + "type": "object", + "properties": { + "host_id": { + "type": "integer", + "readOnly": true + }, + "critical": { + "type": "integer", + "readOnly": true + }, + "high": { + "type": "integer", + "readOnly": true + }, + "med": { + "type": "integer", + "readOnly": true + }, + "low": { + "type": "integer", + "readOnly": true + }, + "info": { + "type": "integer", + "readOnly": true + }, + "unclassified": { + "type": "integer", + "readOnly": true + }, + "total": { + "readOnly": true + } + } + }, + "HostDetailedCount": { + "type": "object", + "properties": { + "host_id": { + "type": "integer", + "readOnly": true + }, + "critical": { + "type": "integer", + "readOnly": true + }, + "high": { + "type": "integer", + "readOnly": true + }, + "med": { + "type": "integer", + "readOnly": true + }, + "low": { + "type": "integer", + "readOnly": true + }, + "info": { + "type": "integer", + "readOnly": true + }, + "unclassified": { + "type": "integer", + "readOnly": true + }, + "total": { + "readOnly": true + }, + "host_data": {} + } + }, + "FlaskRestless": { + "type": "object", + "properties": {} + }, + "Service": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "_id": { + "type": "integer", + "readOnly": true + }, + "status": { + "type": "string", + "default": "open", + "enum": [ + "open", + "closed", + "filtered" + ] + }, + "parent": { + "type": "integer" + }, + "type": { + "readOnly": true + }, + "protocol": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "description": { + "type": "string", + "nullable": true + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "owned": { + "type": "boolean" + }, + "owner": { + "readOnly": true + }, + "credentials": { + "type": "integer", + "readOnly": true + }, + "vulns": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "nullable": true + }, + "version": { + "type": "string", + "nullable": true + }, + "port": { + "type": "integer", + "readOnly": true, + "minimum": 0 + }, + "ports": {}, + "metadata": {}, + "summary": { + "type": "string", + "readOnly": true + }, + "host_id": { + "type": "integer", + "readOnly": true + }, + "tags": {}, + "command_id": { + "type": "integer", + "writeOnly": true + } + }, + "required": [ + "port", + "ports", + "protocol" + ] + }, + "License": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "id": { + "type": "integer" + }, + "product": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "start": { + "type": "string", + "format": "date-time" + }, + "end": { + "type": "string", + "format": "date-time" + }, + "lictype": { + "type": "string", + "nullable": true + }, + "notes": { + "type": "string", + "nullable": true + } + }, + "required": [ + "product" + ] + }, + "ServiceSummary": { + "type": "object", + "properties": { + "service": { + "type": "string", + "readOnly": true + }, + "count": { + "type": "integer", + "readOnly": true + } + } + }, + "Reference": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "Service1": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "ports": {}, + "status": { + "type": "string", + "default": "open", + "enum": [ + "open", + "closed", + "filtered" + ] + }, + "protocol": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "name": { + "type": "string", + "nullable": true + }, + "version": { + "type": "string", + "nullable": true + }, + "summary": { + "type": "string", + "readOnly": true + } + }, + "required": [ + "ports", + "protocol" + ] + }, + "DuplicateVuln": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "readOnly": true + } + } + }, + "VulnerabilityWeb": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "id": { + "type": "integer", + "readOnly": true + }, + "status": { + "enum": [ + "open", + "closed", + "re-opened", + "risk-accepted", + "opened" + ] + }, + "parent_type": {}, + "website": { + "type": "string" + }, + "issuetracker": {}, + "issuetracker_json": {}, + "description": { + "type": "string", + "readOnly": true + }, + "parent": {}, + "tags": {}, + "severity": { + "type": "string" + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "easeofresolution": { + "type": "string", + "enum": [ + "trivial", + "simple", + "moderate", + "difficult", + "infeasible" + ], + "nullable": true + }, + "owned": { + "type": "boolean", + "readOnly": true + }, + "hostnames": { + "readOnly": true + }, + "pname": { + "type": "string" + }, + "query": { + "type": "string" + }, + "owner": { + "readOnly": true + }, + "path": { + "type": "string" + }, + "date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "data": { + "type": "string", + "nullable": true + }, + "response": { + "type": "string" + }, + "refs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Reference" + } + }, + "desc": { + "type": "string" + }, + "impact": {}, + "confirmed": { + "type": "boolean" + }, + "name": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "service": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/Service1" + } + ] + }, + "obj_id": { + "type": "string", + "readOnly": true + }, + "type": {}, + "policyviolations": { + "type": "array", + "items": { + "type": "string" + } + }, + "request": { + "type": "string" + }, + "_attachments": {}, + "params": { + "type": "string" + }, + "target": { + "type": "string", + "readOnly": true + }, + "host_os": { + "type": "string", + "readOnly": true + }, + "resolution": { + "type": "string", + "nullable": true + }, + "method": { + "type": "string" + }, + "metadata": {}, + "status_code": { + "type": "integer", + "nullable": true + }, + "custom_fields": {}, + "external_id": { + "type": "string", + "nullable": true + }, + "vulnerability_duplicate_id": { + "type": "integer", + "readOnly": true, + "nullable": true + }, + "vulnerability_template_id": { + "type": "integer", + "readOnly": true, + "nullable": true + }, + "cvss2": {}, + "cvss3": {}, + "duplicates_associated": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/DuplicateVuln" + } + ] + }, + "tool": { + "type": "string" + }, + "cve": { + "type": "array", + "items": { + "type": "string" + } + }, + "cwe": { + "type": "array", + "items": { + "type": "string" + } + }, + "owasp": { + "type": "array", + "readOnly": true, + "items": { + "type": "string" + } + }, + "duplicates_main": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/DuplicateVuln" + } + ] + }, + "reference_instances": {}, + "command_id": { + "type": "integer", + "writeOnly": true + }, + "risk": { + "readOnly": true + } + }, + "required": [ + "name", + "parent", + "parent_type", + "severity", + "type" + ] + }, + "File": { + "type": "object", + "properties": { + "content_type": { + "readOnly": true + }, + "data": { + "readOnly": true + } + } + }, + "VulnerabilityTemplate": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "_id": { + "type": "integer", + "readOnly": true + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "cwe": { + "type": "string", + "readOnly": true + }, + "description": { + "type": "string", + "nullable": true + }, + "desc": { + "type": "string", + "readOnly": true + }, + "exploitation": { + "type": "string" + }, + "name": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "references": {}, + "refs": { + "type": "array", + "readOnly": true, + "items": { + "type": "string" + } + }, + "resolution": { + "type": "string", + "nullable": true + }, + "impact": {}, + "easeofresolution": { + "type": "string", + "enum": [ + "trivial", + "simple", + "moderate", + "difficult", + "infeasible" + ], + "nullable": true + }, + "policyviolations": { + "type": "array", + "items": { + "type": "string" + } + }, + "data": { + "type": "string" + }, + "external_id": { + "type": "string", + "nullable": true + }, + "creator": { + "readOnly": true + }, + "create_at": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "creator_id": { + "type": "integer", + "readOnly": true + }, + "customfields": {} + }, + "required": [ + "exploitation", + "name" + ] + }, + "Histogram": { + "type": "object", + "properties": { + "date": { + "type": "string", + "readOnly": true + }, + "medium": { + "type": "integer", + "readOnly": true + }, + "high": { + "type": "integer", + "readOnly": true + }, + "critical": { + "type": "integer", + "readOnly": true + }, + "confirmed": { + "type": "integer", + "readOnly": true + } + } + }, + "Workspace": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "id": { + "type": "integer" + }, + "customer": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "description": { + "type": "string", + "nullable": true + }, + "active": { + "type": "boolean" + }, + "duration": {}, + "name": { + "type": "string" + }, + "public": { + "type": "boolean" + }, + "scope": {}, + "stats": {}, + "create_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "users": { + "type": "array", + "items": { + "type": "string" + } + }, + "readonly": { + "type": "boolean" + }, + "last_run_agent_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "histogram": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Histogram" + } + }, + "importance": { + "type": "integer" + } + }, + "required": [ + "name" + ] + }, + "MostUsedTools": { + "type": "object", + "properties": { + "tool_name": { + "type": "string", + "readOnly": true + }, + "count": { + "type": "integer", + "readOnly": true + } + } + }, + "User": { + "type": "object", + "properties": { + "id": {}, + "_id": { + "type": "integer", + "readOnly": true + }, + "username": { + "type": "string", + "readOnly": true + }, + "roles": {}, + "name": { + "type": "string", + "pattern": "^[a-z0-9@._-]{4,100}$" + }, + "password": { + "type": "string", + "writeOnly": true, + "nullable": true + }, + "last_login_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "nullable": true + }, + "email": { + "type": "string", + "format": "email", + "nullable": true + }, + "current_login_at": { + "type": "string", + "format": "date-time", + "readOnly": true, + "nullable": true + }, + "last_login_ip": { + "type": "string", + "readOnly": true, + "nullable": true + }, + "current_login_ip": { + "type": "string", + "readOnly": true, + "nullable": true + }, + "login_count": { + "type": "integer", + "readOnly": true, + "nullable": true + }, + "status_2fa": { + "type": "string", + "readOnly": true + }, + "active": { + "type": "boolean" + }, + "workspaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "user_type": { + "type": "string", + "readOnly": true + } + }, + "required": [ + "name" + ] + }, + "Comment": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "text": { + "type": "string" + }, + "object_type": { + "type": "string", + "enum": [ + "host", + "service", + "comment", + "vulnerability", + "project_task" + ] + }, + "comment_type": { + "type": "string", + "readOnly": true + }, + "object_id": { + "type": "integer" + }, + "creator": { + "readOnly": true + }, + "create_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "metadata": {} + }, + "required": [ + "object_id", + "object_type", + "text" + ] + }, + "ExecutiveReport": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "grouped": { + "type": "boolean" + }, + "name": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "status": { + "type": "string", + "readOnly": true + }, + "template_name": {}, + "conclusions": { + "type": "string", + "nullable": true + }, + "enterprise": { + "type": "string", + "nullable": true + }, + "objectives": { + "type": "string", + "nullable": true + }, + "recommendations": { + "type": "string", + "nullable": true + }, + "scope": { + "type": "string", + "nullable": true + }, + "summary": { + "type": "string", + "nullable": true + }, + "title": { + "type": "string", + "nullable": true + }, + "metadata": {}, + "tags": {}, + "vuln_count": { + "type": "integer", + "readOnly": true + }, + "confirmed": { + "type": "boolean" + }, + "filter": {}, + "advanced_filter": { + "type": "boolean" + }, + "advanced_filter_parsed": { + "type": "string", + "nullable": true + }, + "custom_logo": {} + }, + "required": [ + "name" + ] + }, + "ReportCount": { + "type": "object", + "properties": { + "critical": { + "type": "integer", + "readOnly": true + }, + "high": { + "type": "integer", + "readOnly": true + }, + "med": { + "type": "integer", + "readOnly": true + }, + "info": { + "type": "integer", + "readOnly": true + }, + "unclassified": { + "type": "integer", + "readOnly": true + }, + "total": { + "type": "integer", + "readOnly": true + } + } + }, + "CustomFieldsSchema": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "field_name": { + "type": "string" + }, + "field_type": { + "type": "string" + }, + "field_metadata": { + "type": "string", + "nullable": true + }, + "field_display_name": { + "type": "string" + }, + "field_order": { + "type": "integer" + }, + "table_name": { + "type": "string" + } + }, + "required": [ + "field_display_name", + "field_name", + "field_order", + "field_type", + "table_name" + ] + }, + "Notification": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "user_notified": { + "readOnly": true + }, + "workspace": { + "readOnly": true + }, + "object_type": { + "type": "string", + "readOnly": true + }, + "object_id": { + "type": "integer", + "readOnly": true + }, + "notification_text": { + "type": "string", + "readOnly": true + }, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "mark_read": { + "type": "boolean", + "nullable": true + } + } + }, + "AgentsSchedule": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "description": { + "type": "string" + } + }, + "required": [ + "description" + ] + }, + "Executor": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "readOnly": true + }, + "agent_id": { + "type": "integer", + "readOnly": true + }, + "last_run": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "parameters_metadata": { + "type": "object", + "readOnly": true + }, + "schedules": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/AgentsSchedule" + } + ] + } + } + }, + "Agent": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "name": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "status": { + "type": "string", + "readOnly": true + }, + "active": { + "type": "boolean", + "nullable": true + }, + "create_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "creator": { + "readOnly": true + }, + "is_online": { + "type": "boolean", + "readOnly": true + }, + "executors": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/Executor" + } + ] + }, + "last_run": { + "type": "string", + "format": "date-time", + "readOnly": true + } + }, + "required": [ + "name" + ] + }, + "AgentAuthToken": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "expires_in": { + "type": "number" + }, + "total_duration": { + "type": "number" + } + }, + "required": [ + "expires_in", + "token", + "total_duration" + ] + }, + "BulkCredential": { + "type": "object", + "properties": { + "username": { + "type": "string", + "nullable": true + }, + "password": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string", + "nullable": true + }, + "name": { + "type": "string", + "nullable": true + } + } + }, + "BulkService": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "_id": { + "type": "integer", + "readOnly": true + }, + "status": { + "type": "string", + "default": "open", + "enum": [ + "open", + "closed", + "filtered" + ] + }, + "type": { + "readOnly": true + }, + "protocol": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "description": { + "type": "string", + "nullable": true + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "owned": { + "type": "boolean" + }, + "owner": { + "readOnly": true + }, + "credentials": { + "default": [], + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkCredential" + } + }, + "vulns": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "nullable": true + }, + "version": { + "type": "string", + "nullable": true + }, + "port": { + "type": "integer", + "minimum": 0 + }, + "metadata": {}, + "summary": { + "type": "string", + "readOnly": true + }, + "host_id": { + "type": "integer", + "readOnly": true + }, + "tags": {}, + "command_id": { + "type": "integer", + "writeOnly": true + }, + "vulnerabilities": { + "default": [] + } + }, + "required": [ + "port", + "protocol" + ] + }, + "Vulnerability": { + "type": "object", + "properties": { + "_id": { + "type": "integer", + "readOnly": true + }, + "id": { + "type": "integer", + "readOnly": true + }, + "status": { + "enum": [ + "open", + "closed", + "re-opened", + "risk-accepted", + "opened" + ] + }, + "description": { + "type": "string", + "readOnly": true + }, + "tags": {}, + "severity": { + "type": "string" + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "easeofresolution": { + "type": "string", + "enum": [ + "trivial", + "simple", + "moderate", + "difficult", + "infeasible" + ], + "nullable": true + }, + "owned": { + "type": "boolean", + "readOnly": true + }, + "hostnames": { + "readOnly": true + }, + "owner": { + "readOnly": true + }, + "update_user": { + "readOnly": true + }, + "date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "data": { + "type": "string", + "nullable": true + }, + "refs": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Reference" + } + }, + "reference_instances": {}, + "desc": { + "type": "string" + }, + "impact": {}, + "confirmed": { + "type": "boolean" + }, + "name": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "service": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/Service1" + } + ] + }, + "obj_id": { + "type": "string", + "readOnly": true + }, + "type": {}, + "policyviolations": { + "type": "array", + "items": { + "type": "string" + } + }, + "_attachments": {}, + "target": { + "type": "string", + "readOnly": true + }, + "host_os": { + "type": "string", + "readOnly": true + }, + "resolution": { + "type": "string", + "nullable": true + }, + "metadata": {}, + "issuetracker": {}, + "custom_fields": {}, + "external_id": { + "type": "string", + "nullable": true + }, + "vulnerability_duplicate_id": { + "type": "integer", + "readOnly": true, + "nullable": true + }, + "duplicates_main": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/DuplicateVuln" + } + ] + }, + "vulnerability_template_id": { + "type": "integer", + "readOnly": true, + "nullable": true + }, + "duplicates_associated": { + "readOnly": true, + "allOf": [ + { + "$ref": "#/components/schemas/DuplicateVuln" + } + ] + }, + "tool": { + "type": "string" + }, + "cwe": { + "type": "array", + "items": { + "type": "string" + } + }, + "cve": { + "type": "array", + "items": { + "type": "string" + } + }, + "cvss2": {}, + "cvss3": {}, + "command_id": { + "type": "integer", + "writeOnly": true + }, + "risk": { + "readOnly": true + }, + "run_date": {} + }, + "required": [ + "name", + "severity", + "type" + ] + }, + "HostBulk": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "_id": { + "type": "integer", + "readOnly": true + }, + "_rev": { + "type": "string", + "readOnly": true + }, + "ip": { + "type": "string" + }, + "description": { + "type": "string" + }, + "mac": { + "type": "string", + "nullable": true + }, + "credentials": { + "default": [], + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkCredential" + } + }, + "default_gateway": { + "type": "string", + "nullable": true + }, + "metadata": {}, + "name": { + "type": "string", + "readOnly": true + }, + "os": { + "type": "string" + }, + "owned": { + "type": "boolean" + }, + "owner": { + "readOnly": true + }, + "services": { + "default": [], + "type": "array", + "items": { + "$ref": "#/components/schemas/BulkService" + } + }, + "vulns": { + "readOnly": true + }, + "hostnames": {}, + "type": { + "readOnly": true + }, + "tags": {}, + "service_summaries": { + "readOnly": true + }, + "versions": { + "readOnly": true + }, + "importance": { + "type": "integer" + }, + "severity_counts": { + "readOnly": true + }, + "command_id": { + "type": "integer", + "writeOnly": true + }, + "vulnerabilities": { + "default": [], + "type": "array", + "items": { + "$ref": "#/components/schemas/Vulnerability" + } + } + }, + "required": [ + "description", + "ip" + ] + }, + "BulkCommand": { + "type": "object", + "properties": { + "command": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "duration": { + "type": "integer", + "x-unit": "microseconds" + }, + "start_date": { + "type": "string", + "format": "date-time" + }, + "ip": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "hostname": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "params": { + "type": "string", + "nullable": true + }, + "user": { + "type": "string", + "nullable": true, + "maxLength": 250 + }, + "creator": {}, + "tool": { + "type": "string", + "nullable": true, + "minLength": 1 + }, + "import_source": { + "enum": [ + "report", + "shell", + "agent" + ], + "nullable": true, + "maxLength": 6 + } + }, + "required": [ + "command", + "start_date", + "tool" + ] + }, + "BulkCreate": { + "type": "object", + "properties": { + "hosts": { + "type": "array", + "items": { + "$ref": "#/components/schemas/HostBulk" + } + }, + "command": { + "$ref": "#/components/schemas/BulkCommand" + }, + "execution_id": { + "type": "integer" + } + }, + "required": [ + "command", + "hosts" + ] + }, + "SearchFilter": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "nullable": true + }, + "json_query": { + "type": "string", + "nullable": true + }, + "user_query": { + "type": "string", + "nullable": true + } + }, + "required": [ + "json_query", + "name", + "user_query" + ] + }, + "Condition": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "and", + "or", + "xor", + "leaf" + ] + }, + "parent_id": { + "type": "integer" + }, + "children": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Condition" + } + }, + "field": { + "type": "string", + "nullable": true + }, + "operator": { + "type": "string", + "enum": [ + "is_null", + "is_not_null", + "==", + "!=", + ">", + "<", + ">=", + "<=", + "in", + "not_in" + ], + "nullable": true + }, + "data": { + "type": "string", + "nullable": true + }, + "job_id": { + "type": "integer", + "readOnly": true + }, + "is_root": { + "type": "boolean" + }, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "id": { + "type": "integer" + } + }, + "required": [ + "type" + ] + }, + "Taskwf": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string" + }, + "command": { + "type": "string", + "enum": [ + "UPDATE", + "DELETE", + "ALERT", + "APPEND" + ] + }, + "field": { + "type": "string", + "nullable": true + }, + "value": { + "type": "string", + "nullable": true + }, + "custom_field": { + "type": "boolean" + }, + "job_id": { + "type": "integer", + "nullable": true + }, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "command" + ] + }, + "Pipeline": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "jobs_order": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "workspace_id": { + "type": "integer", + "nullable": true + }, + "jobs_ids": { + "type": "array", + "writeOnly": true, + "items": { + "type": "integer" + } + }, + "running": { + "type": "boolean", + "readOnly": true + }, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "Job": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "model": { + "type": "string", + "enum": [ + "vulnerability", + "vulnerability_web", + "host", + "service" + ] + }, + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/Condition" + } + }, + "rules_json": { + "type": "array", + "writeOnly": true, + "items": { + "type": "object" + } + }, + "tasks": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/Taskwf" + } + }, + "pipelines": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/Pipeline" + } + }, + "tasks_ids": { + "type": "array", + "writeOnly": true, + "items": { + "type": "integer" + } + }, + "metadata": {}, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "model", + "rules_json", + "tasks_ids" + ] + }, + "WorkflowExecution": { + "type": "object", + "properties": { + "id": { + "type": "string", + "readOnly": true + }, + "successful": { + "type": "boolean" + }, + "message": { + "type": "string" + }, + "object_and_id": { + "type": "string" + }, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "message", + "object_and_id", + "successful" + ] + }, + "Job1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "model": { + "type": "string", + "enum": [ + "vulnerability", + "vulnerability_web", + "host", + "service" + ] + }, + "enabled": { + "type": "boolean" + }, + "rules": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/Condition" + } + }, + "rules_json": { + "type": "array", + "writeOnly": true, + "items": { + "type": "object" + } + }, + "tasks": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/Taskwf" + } + }, + "tasks_ids": { + "type": "array", + "writeOnly": true, + "items": { + "type": "integer" + } + }, + "metadata": {}, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "model", + "rules_json", + "tasks_ids" + ] + }, + "Pipeline1": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "jobs_order": { + "type": "string" + }, + "jobs": { + "type": "array", + "readOnly": true, + "items": { + "$ref": "#/components/schemas/Job1" + } + }, + "enabled": { + "type": "boolean" + }, + "workspace_id": { + "type": "integer", + "nullable": true + }, + "jobs_ids": { + "type": "array", + "writeOnly": true, + "items": { + "type": "integer" + } + }, + "running": { + "type": "boolean", + "readOnly": true + }, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + } + }, + "AnalyticsFilters": { + "type": "object", + "properties": { + "workspaces": { + "type": "array", + "items": { + "type": "string" + } + }, + "hosts": { + "type": "array", + "items": { + "type": "string" + } + }, + "only_confirmed": { + "type": "boolean" + }, + "include_closed": { + "type": "boolean" + }, + "date_from": { + "type": "string" + }, + "date_to": { + "type": "string" + } + } + }, + "Analytics": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "filters": { + "$ref": "#/components/schemas/AnalyticsFilters" + }, + "data": { + "type": "object" + }, + "show_data_table": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": [ + "vulnerabilities_per_host", + "vulnerabilities_per_status", + "vulnerabilities_per_severity", + "top_ten_most_affected_hosts", + "top_ten_most_repeated_vulns", + "monthly_evolution_by_status", + "monthly_evolution_by_severity", + "vulnerabilities_by_risk_score" + ] + }, + "create_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "readOnly": true + } + }, + "required": [ + "description", + "filters", + "name", + "type" + ] + }, + "Project": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "name": { + "type": "string" + }, + "start_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "end_date": { + "type": "string", + "format": "date-time", + "readOnly": true + }, + "metadata": {}, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "name" + ] + }, + "ProjectTask": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "start_date": { + "type": "integer", + "nullable": true + }, + "end_date": { + "type": "integer" + }, + "type": { + "type": "string", + "enum": [ + "task", + "milestone" + ] + }, + "status": { + "type": "string", + "enum": [ + "new", + "review", + "completed", + "in progress" + ], + "nullable": true + }, + "users_assigned": { + "nullable": true + }, + "task_dependencies": { + "nullable": true + }, + "name": { + "type": "string" + }, + "description": { + "type": "string" + }, + "project_id": { + "type": "integer" + }, + "vulnerabilities_related": { + "nullable": true + }, + "metadata": {}, + "create_date": { + "type": "string", + "format": "date-time", + "nullable": true + }, + "update_date": { + "type": "string", + "format": "date-time", + "nullable": true + } + }, + "required": [ + "description", + "end_date", + "project_id" + ] + }, + "NotificationCenterSchemaAdmin": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "user_id": { + "type": "integer", + "readOnly": true + }, + "paused": { + "type": "boolean" + }, + "slack_id": { + "type": "string" + }, + "no_self_notify": { + "type": "boolean" + }, + "comments_enabled": { + "type": "boolean" + }, + "comments_app": { + "type": "boolean" + }, + "comments_email": { + "type": "boolean" + }, + "comments_slack": { + "type": "boolean" + }, + "hosts_enabled": { + "type": "boolean" + }, + "hosts_app": { + "type": "boolean" + }, + "hosts_email": { + "type": "boolean" + }, + "hosts_slack": { + "type": "boolean" + }, + "users_enabled": { + "type": "boolean" + }, + "users_app": { + "type": "boolean" + }, + "users_email": { + "type": "boolean" + }, + "users_slack": { + "type": "boolean" + }, + "reports_enabled": { + "type": "boolean" + }, + "reports_app": { + "type": "boolean" + }, + "reports_email": { + "type": "boolean" + }, + "reports_slack": { + "type": "boolean" + }, + "vulnerabilities_enabled": { + "type": "boolean" + }, + "vulnerabilities_app": { + "type": "boolean" + }, + "vulnerabilities_email": { + "type": "boolean" + }, + "vulnerabilities_slack": { + "type": "boolean" + }, + "workspaces_enabled": { + "type": "boolean" + }, + "workspaces_app": { + "type": "boolean" + }, + "workspaces_email": { + "type": "boolean" + }, + "workspaces_slack": { + "type": "boolean" + }, + "planner_enabled": { + "type": "boolean" + }, + "planner_app": { + "type": "boolean" + }, + "planner_email": { + "type": "boolean" + }, + "planner_slack": { + "type": "boolean" + }, + "adv_high_crit_vuln": { + "type": "boolean" + }, + "adv_risk_score_threshold": { + "type": "integer" + }, + "adv_vuln_open_days": { + "type": "integer" + }, + "integrations_enabled": { + "type": "boolean" + }, + "integrations_app": { + "type": "boolean" + }, + "integrations_email": { + "type": "boolean" + }, + "integrations_slack": { + "type": "boolean" + }, + "pipelines_enabled": { + "type": "boolean" + }, + "pipelines_app": { + "type": "boolean" + }, + "pipelines_email": { + "type": "boolean" + }, + "pipelines_slack": { + "type": "boolean" + }, + "agents_enabled": { + "type": "boolean" + }, + "agents_app": { + "type": "boolean" + }, + "agents_email": { + "type": "boolean" + }, + "agents_slack": { + "type": "boolean" + } + } + }, + "TriggeredBy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "user", + "agent", + "system", + "unknown" + ] + }, + "id": { + "type": "integer", + "nullable": true + }, + "username": { + "type": "string", + "nullable": true + } + }, + "required": [ + "type" + ] + }, + "LinksTo": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": [ + "vulnerability", + "agent", + "system", + "workspaces", + "host", + "planner", + "report", + "pipeline", + "command" + ], + "nullable": true + }, + "id": { + "type": "integer", + "nullable": true + } + } + }, + "UserNotification": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "readOnly": true + }, + "message": { + "type": "string" + }, + "extra_data": { + "type": "object" + }, + "triggered_by": { + "$ref": "#/components/schemas/TriggeredBy" + }, + "type": { + "type": "string", + "enum": [ + "agents", + "cli", + "comments", + "hosts", + "users", + "reports", + "vulnerabilities", + "workspaces", + "pipelines", + "planner", + "integrations", + "other", + "advanced" + ] + }, + "subtype": { + "type": "string" + }, + "links_to": { + "nullable": true, + "allOf": [ + { + "$ref": "#/components/schemas/LinksTo" + } + ] + }, + "user_id": { + "type": "integer" + }, + "read": { + "type": "boolean" + }, + "event_date": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "message", + "subtype", + "user_id" + ] + } + }, + "responses": { + "UnauthorizedError": { + "description": "You are not authenticated or your API key is missing or invalid" + } + }, + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "Basic" + } + } + }, + "tags": [ + { + "name": "2FA" + }, + { + "name": "Action" + }, + { + "name": "Agent" + }, + { + "name": "Agent Schedule" + }, + { + "name": "AgentsSchedule" + }, + { + "name": "Analytics" + }, + { + "name": "Bulk" + }, + { + "name": "Command" + }, + { + "name": "Comment" + }, + { + "name": "Credential" + }, + { + "name": "CustomFieldsSchema" + }, + { + "name": "Deprecated" + }, + { + "name": "Duplicate" + }, + { + "name": "Enrichment" + }, + { + "name": "ExecutionReport" + }, + { + "name": "ExecutiveReport" + }, + { + "name": "File" + }, + { + "name": "Filter" + }, + { + "name": "Host" + }, + { + "name": "Informational" + }, + { + "name": "Job" + }, + { + "name": "License" + }, + { + "name": "Notification" + }, + { + "name": "Pipeline" + }, + { + "name": "PlannerProject" + }, + { + "name": "ProjectTask" + }, + { + "name": "SearchFilter" + }, + { + "name": "Service" + }, + { + "name": "Swagger" + }, + { + "name": "Tag" + }, + { + "name": "Ticketing Tools" + }, + { + "name": "Token" + }, + { + "name": "User" + }, + { + "name": "UserNotification" + }, + { + "name": "UserNotificationSettings" + }, + { + "name": "Vulnerability" + }, + { + "name": "VulnerabilityGeneric" + }, + { + "name": "VulnerabilityTemplate" + }, + { + "name": "Workflow" + }, + { + "name": "Workspace" + }, + { + "name": "host" + }, + { + "name": "settings" + } + ] +} \ No newline at end of file diff --git a/files/templates/task/methodology_hardware_top_10.csv b/files/templates/task/methodology_hardware_top_10.csv new file mode 100644 index 00000000000..83731503570 --- /dev/null +++ b/files/templates/task/methodology_hardware_top_10.csv @@ -0,0 +1,11 @@ +"name","description" +"1. Unsigned firmware updates", "Check if the device accepts firmware updates, and if it verifies the authenticity of the binaries. An attacker can easily gain code execution via unsigned firmware updates by uploading a malicious firmware." +"2. Hardcoded credentials", "Usually, firmware can be recovered in some way, either via unencrypted updates or dumping it from flash or RAM. Then it can be disassembled and analyzed for hardcoded debug/admin credentials that can then be used to compromise the device." +"3. Debug ports", "Developers usually leave debug ports in the form of serial consoles or JTAG ports. If unsecured, an attacker with physical access can use those ports to compromise the device, either because they are not authenticated, or using hardcoded credentials." +"4.Outdated/vulnerable software", "Most embedded hardware device's firmware is updated at a slow rate, if at all. An attacker can identify unpatched software versions or libraries that the firmware is using, and exploit the vulnerabilities to gain code execution or dump additional data." +"5. Allowing old firmware updates", "The device should not allow flashing for an older firmware version. An attacker could force flash an older firmware with known vulnerabilities and then use them to gain code execution or privileges. Note that the older firmware might be signed and still be vulnerable." +"6. Weak RNG", "Embedded devices usually do not contain a high-quality random number generator. This weakens most crypto operations, specially if the device generates credentials in some way. An attacker can predict or control the output of the generator, and in this way extract parts or the complete generated keys." +"7. Subsystem trust abuse", "Many embedded devices are composed of multiple CPUs/subsystems connected via different bus types. The subsystems usually trust each other and developers don't expect a malicious or compromised subsystem, and don't validate the communications with them. An attacker with physical access to the device can easily impersonate one or several subsystems and gain code execution or privileges on the other modules." +"8. Lack of brown-out detector", "Embedded CPUs contain circuitry to detect 'brown-outs' or voltage drops. If power is not within accepted range, the CPU usually resets. If this system is not enabled, an attacker could feed invalid voltages to the CPU to force unexpected behavior and control several aspects of the execution. This is known as a glitch attack." +"9. Side-channels", "Embedded devices could be susceptible to leaking critical data via side channels. Some devices processing might be slow so timing attacks are particularly effective. Devices can also leak data via thermal or electromagnetic emissions." +"10. Lack of hardware-based security", "Many low-power devices lack hardware-based security like a MMU or page-level permissions. This prevents developers to properly implement process-separation and other basic security measures. An attacker could leverage this to easily escalate privileges, or greatly reduce the complexity of software exploits." diff --git a/files/templates/task/methodology_mobile_security.csv b/files/templates/task/methodology_mobile_security.csv new file mode 100644 index 00000000000..c3d8b045366 --- /dev/null +++ b/files/templates/task/methodology_mobile_security.csv @@ -0,0 +1,10 @@ +"name","description" +"1. Smartphone overview", "Verify if the smartphone is rooted/jailbreaked. You could find a lot of weak & common attack vectors. Check which OS version is running." +"2. Insecure data storage", "Check applications logs, usually they contain sensitive data. When analyzing the code, verify (with regexp or common words) if credentials are hardcoded. Also, mobile apps don't use secure storages for storing sensitive data and save them in app local storage (like temp/cached data)." +"3. Insecure communication", "Check if mobile app components are using unencrypted channels for communication, such as FTP/TELNET/HTTP." +"4. Weak components", "Applications may use various third-party libraries/components that can be outdated and contain vulnerabilities with public exploits. Those are a great vector for starting an attack." +"5. Cryptography issues", "Check if the app is validating the server's TLS/SSL certificate (certificate pinning). Also, try changing HTTPS requests to HTTP (as tools like SSLStrip would do) to intercept plain information. Check if the app is using cryptographic protocols or algorithms that are widely considered deprecated." +"6. Authentication/Authorization", "Verify if the app generates random access tokens for user authentication and, when session ends, the token is deleted. Bruteforce attacks are useful to check if accounts are locked after X attempts." +"7. Code quality", "Verify that debugging code has been removed and the app doesn't log verbose errors or debugging messages." +"8. Data tampering", "Try to inject data that the app is not expecting (like numbers when it's waiting for a string) and check the different error messages." +"9. Reverse engineering", "At decompiling, commonly you can read its source code because it's not obfuscated or it's using very poor obfuscation techniques. Also, try debugging techniques, developers usually forget to disable android:debuggable parameter." diff --git a/files/templates/task/methodology_network_pentest.csv b/files/templates/task/methodology_network_pentest.csv new file mode 100644 index 00000000000..a77da2c2fe1 --- /dev/null +++ b/files/templates/task/methodology_network_pentest.csv @@ -0,0 +1,10 @@ +"name","description" +"1. Network Footprinting", "The tester would attempt to gather as much information as possible about the selected network. This would usually involve trying to discover publicly available information by utilising a web browser, DNS zone transfer or a social engineering type of attack." +"2. Discovery & Probing", "Enumeration can serve two distinct purposes in an assessment: OS fingerprinting or TCP/IP stack fingerprinting and fingerprinting services and remote applications. There are two main ways to do OS fingerprinting: actively (i.e. nmap) or passively (i.e. scanrand). By port scanning it is then possible to build up a picture of which services and applications are running and tailor the tests accordingly." +"3. Enumeration", "Check common services like FTP, SSH, SMTP, TELNET, HTTP, MySQL, PPTP, etc. Attempt to enumerate valid users to identify potential victims and attack vectors." +"4. Password cracking", "Use tools like Rainbow crack, ophcrack, John the Ripper, pwdump, etc. in order to be able to break passwords and gain access to the system." +"5. Vulnerability Assessment", "Utilising vulnerability scanners all discovered hosts can be tested for vulnerabilities. The result would then be analysed to determine if there are any vulnerabilities that could be exploited to gain access to a target host on a network." +"6. Network Backbone", "Always check the network traffic. Use tools like Wireshark, Cain & Abel, Yersinia, etc. and try to get more access to be able to scale and propagate in the network." +"7. Penetration & Exploit", "An exploit usually relates to the existence of some flaw or vulnerability in an application or operating system that if used could lead to privilege escalation or denial of service against the computer system that is being attacked." +"8. Wireless Penetration", "Wireless Assessment. The following information should ideally be obtained/enumerated when carrying out your wireless assessment - cypher type (WEP, WPA, etc), VLANs, channels, traffic, etc." +"9. Physical Security", "Review how perimeter security works. Check for active network jacks, printers, phones and any information in the room. Note what type of locks are used in building, pin tumblers, padlocks, cabinet locks, dimple keys, proximity sensors and do some lock picking attack." \ No newline at end of file diff --git a/files/templates/task/methodology_owasp_top_10.csv b/files/templates/task/methodology_owasp_top_10.csv new file mode 100644 index 00000000000..4d96011887e --- /dev/null +++ b/files/templates/task/methodology_owasp_top_10.csv @@ -0,0 +1,11 @@ +"name","description" +"A1 Injection", "Enforce input field type and lengths. Validate fields and provide feedback. Ensure option selects and radio contain only sent values." +"A2 Weak authentication and session management", "Validate user is authenticated and if the role is sufficient for this view. Check Set 'secure' and 'HttpOnly' flags for session cookies and always review if forms send CSRF token." +"A3 XSS", "Set correct content type. Set safe character set (UTF-8) and set correct locale. Output encode all user data as per output context. Set input constraints and remember that On Submit enforce input field type and lengths." +"A4 Insecure Direct Object References", "If data is from internal trusted sources, validate that no data is sent. Send indirect random access reference map value and provide feedback." +"A5 Security Misconfiguration", "Ensure web servers and application servers are hardened. For example in PHP: Ensure allow_url_fopen and allow_url_include are both disabled in php.ini." +"A6 Sensitive Data Exposure", "Validate strong ciphers (AES 128 or better) with secure mode of operations (do not use ECB). Use strong hashes (SHA 256 or better) with salts for passwords and protect keys more than any other asset. Use TLS 1.2 or later for all web communications. Some people send keys or hashes to the browser, never do that." +"A7 Missing Function Level Access Control", "Ensure all non-web data is outside the web root (logs, configuration, etc). Use octet byte streaming instead of providing access to real files such as PDFs or CSVs or similar. Ensure every page requires a role and user is authenticated, even if it is 'guest'." +"A8 Cross Site Request Forgery", "Validate user is authenticated and role is sufficient for this view. Send CSRF token." +"A9 Using Components with Known Vulnerabilities", "Applications may use various third-party libraries/components that can be outdated and contain vulnerabilities with public exploits. Those are a great vector for starting an attack. You can run OWASP dependency check for the components." +"A10 Unvalidated Redirects and Forwards", "Design the app without URL redirection parameters and use random indirect object references for redirection parameters." diff --git a/files/templates/task/methodology_pci_dss_11.2.csv b/files/templates/task/methodology_pci_dss_11.2.csv new file mode 100644 index 00000000000..2ad8adf6d5d --- /dev/null +++ b/files/templates/task/methodology_pci_dss_11.2.csv @@ -0,0 +1,5 @@ +"name","description" +"11.2", "Run internal and external network vulnerability scans at least quarterly and after any significant change in the network (such as new system component installations, changes in network topology, firewall rule modifications, product upgrades)." +"11.2.1", "Perform quarterly internal vulnerability scans. Address vulnerabilities and perform rescans to verify all "high risk" vulnerabilities are resolved in accordance with the entity's vulnerability ranking (per Requirement 6.1). Scans must be performed by qualified personnel." +"11.2.2", "Perform quarterly external vulnerability scans, via an Approved Scanning Vendor (ASV) approved by the Payment Card Industry Security Standards Council (PCI SSC). Perform rescans as needed, until passing scans are achieved." +"11.2.3", "Perform internal and external scans, and rescans as needed, after any significant change. Scans must be performed by qualified personnel." \ No newline at end of file diff --git a/files/templates/task/methodology_pci_dss_6.5.csv b/files/templates/task/methodology_pci_dss_6.5.csv new file mode 100644 index 00000000000..67cad9a8050 --- /dev/null +++ b/files/templates/task/methodology_pci_dss_6.5.csv @@ -0,0 +1,12 @@ +"name","description" +"6.5 Address common coding vulnerabilities in software-development processes as follows", "Train developers at least annually in up- to-date secure coding techniques, including how to avoid common coding vulnerabilities. Develop applications based on secure coding guidelines." +"6.5.1 Injection flaws", "Particularly SQL injection. Also consider OS Command Injection, LDAP and XPath injection flaws as well as other injection flaws." +"6.5.2 Buffer overflows", "Verify that buffer overflows are addressed by coding techniques that include: Validating buffer boundaries and Truncating input strings." +"6.5.3 Insecure cryptographic storage", "Verify that insecure cryptographic storage is addressed by coding techniques that: Prevent cryptographic flaws and use strong cryptographic algorithms and keys." +"6.5.4 Insecure communications", "Verify that insecure communications are addressed by coding techniques that properly authenticate and encrypt all sensitive communications." +"6.5.5 Improper error handling", "Verify that improper error handling is addressed by coding techniques that do not leak information via error messages (for example, by returning generic rather than specific error details)." +"6.5.6 All 'high risk' vulnerabilities identified", "Verify that coding techniques address any 'high risk' vulnerabilities that could affect the application, as identified in PCI DSS Requirement 6.1." +"6.5.7 Cross-site scripting (XSS)", "Verify that cross-site scripting (XSS) is addressed by coding techniques that include validating all parameters before inclusion or utilizing context-sensitive escaping." +"6.5.8 Improper access control", "Verify insecure direct object references, failure to restrict URL access, directory traversal, and failure to restrict user access to functions." +"6.5.9 Cross-site request forgery (CSRF)", "Verify that CSRF is addressed by coding techniques that ensure applications do not rely on authorization credentials and tokens automatically submitted by browsers." +"6.5.10 Broken authentication and session management", "Verify that broken authentication and session management are addressed via coding techniques that commonly include: Flagging session tokens (for example cookies) as 'secure', not exposing session IDs in the URL, incorporating appropriate time-outs and rotation of session IDs after a successful login." diff --git a/files/templates/template-markdown.zip b/files/templates/template-markdown.zip new file mode 100644 index 00000000000..3027c3d119d Binary files /dev/null and b/files/templates/template-markdown.zip differ diff --git a/files/templates/templates.zip b/files/templates/templates.zip new file mode 100644 index 00000000000..44d0107a80a Binary files /dev/null and b/files/templates/templates.zip differ diff --git a/images/2FA/2fa_activate.png b/images/2FA/2fa_activate.png new file mode 100644 index 00000000000..168ef49f6ba Binary files /dev/null and b/images/2FA/2fa_activate.png differ diff --git a/images/2FA/account.png b/images/2FA/account.png new file mode 100644 index 00000000000..ea524269a77 Binary files /dev/null and b/images/2FA/account.png differ diff --git a/images/2FA/menu.png b/images/2FA/menu.png new file mode 100644 index 00000000000..9a63dc247e7 Binary files /dev/null and b/images/2FA/menu.png differ diff --git a/images/FAQ/version_file.png b/images/FAQ/version_file.png new file mode 100644 index 00000000000..2abdd3e8f75 Binary files /dev/null and b/images/FAQ/version_file.png differ diff --git a/images/FAQ/webui_version.png b/images/FAQ/webui_version.png new file mode 100644 index 00000000000..31972deed0d Binary files /dev/null and b/images/FAQ/webui_version.png differ diff --git a/images/KB/create-from-vuln.png b/images/KB/create-from-vuln.png new file mode 100644 index 00000000000..36b0bc0c245 Binary files /dev/null and b/images/KB/create-from-vuln.png differ diff --git a/images/KB/import-button.png b/images/KB/import-button.png new file mode 100644 index 00000000000..ae486fa98ea Binary files /dev/null and b/images/KB/import-button.png differ diff --git a/images/KB/new-button.png b/images/KB/new-button.png new file mode 100644 index 00000000000..44c970e8aa2 Binary files /dev/null and b/images/KB/new-button.png differ diff --git a/images/KB/v4-view-kb.png b/images/KB/v4-view-kb.png new file mode 100644 index 00000000000..9e13e04b6ab Binary files /dev/null and b/images/KB/v4-view-kb.png differ diff --git a/images/KB/vuln-create-kb.png b/images/KB/vuln-create-kb.png new file mode 100644 index 00000000000..8742927bd81 Binary files /dev/null and b/images/KB/vuln-create-kb.png differ diff --git a/images/OSINT-provider/censys.png b/images/OSINT-provider/censys.png new file mode 100644 index 00000000000..0fd60fb9ff1 Binary files /dev/null and b/images/OSINT-provider/censys.png differ diff --git a/images/OSINT-provider/netdb.png b/images/OSINT-provider/netdb.png new file mode 100644 index 00000000000..64cb714caf6 Binary files /dev/null and b/images/OSINT-provider/netdb.png differ diff --git a/images/OSINT-provider/shodan.png b/images/OSINT-provider/shodan.png new file mode 100644 index 00000000000..4d5002717d8 Binary files /dev/null and b/images/OSINT-provider/shodan.png differ diff --git a/images/SSO/SAML/auth0_configuration.png b/images/SSO/SAML/auth0_configuration.png new file mode 100644 index 00000000000..1b229ecaab3 Binary files /dev/null and b/images/SSO/SAML/auth0_configuration.png differ diff --git a/images/SSO/SAML/auth0_data.png b/images/SSO/SAML/auth0_data.png new file mode 100644 index 00000000000..57558867678 Binary files /dev/null and b/images/SSO/SAML/auth0_data.png differ diff --git a/images/SSO/SAML/auth0_enable_saml.png b/images/SSO/SAML/auth0_enable_saml.png new file mode 100644 index 00000000000..0d41c6840f3 Binary files /dev/null and b/images/SSO/SAML/auth0_enable_saml.png differ diff --git a/images/SSO/SAML/auth0_settings.png b/images/SSO/SAML/auth0_settings.png new file mode 100644 index 00000000000..9c4f51721c1 Binary files /dev/null and b/images/SSO/SAML/auth0_settings.png differ diff --git a/images/SSO/SAML/google_app_name.png b/images/SSO/SAML/google_app_name.png new file mode 100644 index 00000000000..e378efcea94 Binary files /dev/null and b/images/SSO/SAML/google_app_name.png differ diff --git a/images/SSO/SAML/google_certificate_config.png b/images/SSO/SAML/google_certificate_config.png new file mode 100644 index 00000000000..5d38746dca7 Binary files /dev/null and b/images/SSO/SAML/google_certificate_config.png differ diff --git a/images/SSO/SAML/google_configure_attributes.png b/images/SSO/SAML/google_configure_attributes.png new file mode 100644 index 00000000000..3e42a096a7c Binary files /dev/null and b/images/SSO/SAML/google_configure_attributes.png differ diff --git a/images/SSO/SAML/google_configure_faraday_endpoints.png b/images/SSO/SAML/google_configure_faraday_endpoints.png new file mode 100644 index 00000000000..17e25a2860b Binary files /dev/null and b/images/SSO/SAML/google_configure_faraday_endpoints.png differ diff --git a/images/SSO/SAML/google_create_app.png b/images/SSO/SAML/google_create_app.png new file mode 100644 index 00000000000..9e7fbed9b9a Binary files /dev/null and b/images/SSO/SAML/google_create_app.png differ diff --git a/images/SSO/SAML/google_enable_everyone.png b/images/SSO/SAML/google_enable_everyone.png new file mode 100644 index 00000000000..fee1ed3ff62 Binary files /dev/null and b/images/SSO/SAML/google_enable_everyone.png differ diff --git a/images/SSO/SAML/google_enable_users.png b/images/SSO/SAML/google_enable_users.png new file mode 100644 index 00000000000..2858a00eec4 Binary files /dev/null and b/images/SSO/SAML/google_enable_users.png differ diff --git a/images/SSO/SAML/okta_data.png b/images/SSO/SAML/okta_data.png new file mode 100644 index 00000000000..4b2b67faa7b Binary files /dev/null and b/images/SSO/SAML/okta_data.png differ diff --git a/images/SSO/SAML/okta_saml.png b/images/SSO/SAML/okta_saml.png new file mode 100644 index 00000000000..0efdb57623b Binary files /dev/null and b/images/SSO/SAML/okta_saml.png differ diff --git a/images/SSO/SAML/saml_configuration.png b/images/SSO/SAML/saml_configuration.png new file mode 100644 index 00000000000..2f919a7d20d Binary files /dev/null and b/images/SSO/SAML/saml_configuration.png differ diff --git a/images/Vulns-v4/columns-v4.png b/images/Vulns-v4/columns-v4.png new file mode 100644 index 00000000000..c6b83be2eec Binary files /dev/null and b/images/Vulns-v4/columns-v4.png differ diff --git a/images/Vulns-v4/confirmed_vulns-v4.png b/images/Vulns-v4/confirmed_vulns-v4.png new file mode 100644 index 00000000000..da5340960a6 Binary files /dev/null and b/images/Vulns-v4/confirmed_vulns-v4.png differ diff --git a/images/Vulns-v4/create_tag-v4.png b/images/Vulns-v4/create_tag-v4.png new file mode 100644 index 00000000000..f091a62d91e Binary files /dev/null and b/images/Vulns-v4/create_tag-v4.png differ diff --git a/images/Vulns-v4/delete_vuln-v4.png b/images/Vulns-v4/delete_vuln-v4.png new file mode 100644 index 00000000000..6850cbcbaaa Binary files /dev/null and b/images/Vulns-v4/delete_vuln-v4.png differ diff --git a/images/Vulns-v4/edit_vuln-v4.png b/images/Vulns-v4/edit_vuln-v4.png new file mode 100644 index 00000000000..a1ce2eb69c4 Binary files /dev/null and b/images/Vulns-v4/edit_vuln-v4.png differ diff --git a/images/Vulns-v4/new_vuln-v4.png b/images/Vulns-v4/new_vuln-v4.png new file mode 100644 index 00000000000..d1d3def8d62 Binary files /dev/null and b/images/Vulns-v4/new_vuln-v4.png differ diff --git a/images/Vulns-v4/search-v4.png b/images/Vulns-v4/search-v4.png new file mode 100644 index 00000000000..4ddd2acffd7 Binary files /dev/null and b/images/Vulns-v4/search-v4.png differ diff --git a/images/Vulns-v4/search_many-v4.png b/images/Vulns-v4/search_many-v4.png new file mode 100644 index 00000000000..29b1ecd6d5a Binary files /dev/null and b/images/Vulns-v4/search_many-v4.png differ diff --git a/images/Vulns-v4/search_tags-v4.png b/images/Vulns-v4/search_tags-v4.png new file mode 100644 index 00000000000..6d0e929c565 Binary files /dev/null and b/images/Vulns-v4/search_tags-v4.png differ diff --git a/images/Vulns-v4/select_tag-v4.png b/images/Vulns-v4/select_tag-v4.png new file mode 100644 index 00000000000..34ff66eac3f Binary files /dev/null and b/images/Vulns-v4/select_tag-v4.png differ diff --git a/images/Vulns-v4/status_report-v4.png b/images/Vulns-v4/status_report-v4.png new file mode 100644 index 00000000000..48c7e9a9593 Binary files /dev/null and b/images/Vulns-v4/status_report-v4.png differ diff --git a/images/Vulns-v4/upload_options-v4.png b/images/Vulns-v4/upload_options-v4.png new file mode 100644 index 00000000000..7fc199fcb90 Binary files /dev/null and b/images/Vulns-v4/upload_options-v4.png differ diff --git a/images/Vulns-v4/vuln_preview-v4.png b/images/Vulns-v4/vuln_preview-v4.png new file mode 100644 index 00000000000..1b53e3975d1 Binary files /dev/null and b/images/Vulns-v4/vuln_preview-v4.png differ diff --git a/images/Vulns-v4/vulns_selected-v4.png b/images/Vulns-v4/vulns_selected-v4.png new file mode 100644 index 00000000000..65bf54b655b Binary files /dev/null and b/images/Vulns-v4/vulns_selected-v4.png differ diff --git a/images/Vulns-v4/vulns_tagged-v4.png b/images/Vulns-v4/vulns_tagged-v4.png new file mode 100644 index 00000000000..53a3d990342 Binary files /dev/null and b/images/Vulns-v4/vulns_tagged-v4.png differ diff --git a/images/WHD/Config-view-whd.png b/images/WHD/Config-view-whd.png new file mode 100644 index 00000000000..c24d7f3858a Binary files /dev/null and b/images/WHD/Config-view-whd.png differ diff --git a/images/WHD/Send-view-whd.png b/images/WHD/Send-view-whd.png new file mode 100644 index 00000000000..693c8150f04 Binary files /dev/null and b/images/WHD/Send-view-whd.png differ diff --git a/images/activity-dashboard/Activity_Dashboard.png b/images/activity-dashboard/Activity_Dashboard.png new file mode 100644 index 00000000000..0ba8c8525be Binary files /dev/null and b/images/activity-dashboard/Activity_Dashboard.png differ diff --git a/images/activity-dashboard/Activity_Dashboard_1.png b/images/activity-dashboard/Activity_Dashboard_1.png new file mode 100644 index 00000000000..6f18e15968c Binary files /dev/null and b/images/activity-dashboard/Activity_Dashboard_1.png differ diff --git a/images/activity-dashboard/Activity_Dashboard_3.png b/images/activity-dashboard/Activity_Dashboard_3.png new file mode 100644 index 00000000000..45f6c29fed3 Binary files /dev/null and b/images/activity-dashboard/Activity_Dashboard_3.png differ diff --git a/images/addons/firefox-icon.png b/images/addons/firefox-icon.png new file mode 100644 index 00000000000..8c56c79c87b Binary files /dev/null and b/images/addons/firefox-icon.png differ diff --git a/images/agents/agent_overview-v4.png b/images/agents/agent_overview-v4.png new file mode 100644 index 00000000000..a359a18ace6 Binary files /dev/null and b/images/agents/agent_overview-v4.png differ diff --git a/images/agents/agent_run-v4.png b/images/agents/agent_run-v4.png new file mode 100644 index 00000000000..7e5da6c503a Binary files /dev/null and b/images/agents/agent_run-v4.png differ diff --git a/images/agents/architecture-v4.png b/images/agents/architecture-v4.png new file mode 100644 index 00000000000..3b67159e738 Binary files /dev/null and b/images/agents/architecture-v4.png differ diff --git a/images/agents/architecture.png b/images/agents/architecture.png new file mode 100644 index 00000000000..3b67159e738 Binary files /dev/null and b/images/agents/architecture.png differ diff --git a/images/agents/createNewSchedule-v4.png b/images/agents/createNewSchedule-v4.png new file mode 100644 index 00000000000..2d6d41ab90c Binary files /dev/null and b/images/agents/createNewSchedule-v4.png differ diff --git a/images/agents/dispatcher_yaml_location-v4.png b/images/agents/dispatcher_yaml_location-v4.png new file mode 100644 index 00000000000..2fc5a0ffc4b Binary files /dev/null and b/images/agents/dispatcher_yaml_location-v4.png differ diff --git a/images/agents/new-agent-v4.png b/images/agents/new-agent-v4.png new file mode 100644 index 00000000000..8fc37a01198 Binary files /dev/null and b/images/agents/new-agent-v4.png differ diff --git a/images/agents/newAgent_displayed-v4.png b/images/agents/newAgent_displayed-v4.png new file mode 100644 index 00000000000..eddbedd38e9 Binary files /dev/null and b/images/agents/newAgent_displayed-v4.png differ diff --git a/images/agents/newAgent_toolNmap-v4.png b/images/agents/newAgent_toolNmap-v4.png new file mode 100644 index 00000000000..1be086dcc63 Binary files /dev/null and b/images/agents/newAgent_toolNmap-v4.png differ diff --git a/images/agents/new_agent_finalstep-v4.png b/images/agents/new_agent_finalstep-v4.png new file mode 100644 index 00000000000..9357f221a87 Binary files /dev/null and b/images/agents/new_agent_finalstep-v4.png differ diff --git a/images/agents/new_agent_step2-v4.png b/images/agents/new_agent_step2-v4.png new file mode 100644 index 00000000000..8f9adfd0f10 Binary files /dev/null and b/images/agents/new_agent_step2-v4.png differ diff --git a/images/agents/schedule-v4.png b/images/agents/schedule-v4.png new file mode 100644 index 00000000000..040c5b1471e Binary files /dev/null and b/images/agents/schedule-v4.png differ diff --git a/images/agents/schedule_agent-v4.png b/images/agents/schedule_agent-v4.png new file mode 100644 index 00000000000..cade290bc30 Binary files /dev/null and b/images/agents/schedule_agent-v4.png differ diff --git a/images/agents/scheduling.png b/images/agents/scheduling.png new file mode 100644 index 00000000000..d6786cb1b5f Binary files /dev/null and b/images/agents/scheduling.png differ diff --git a/images/agents/scheduling_2.png b/images/agents/scheduling_2.png new file mode 100644 index 00000000000..a65086737ae Binary files /dev/null and b/images/agents/scheduling_2.png differ diff --git a/images/architecture/Faraday_Architecture.jpg b/images/architecture/Faraday_Architecture.jpg new file mode 100644 index 00000000000..ea8332fb0bb Binary files /dev/null and b/images/architecture/Faraday_Architecture.jpg differ diff --git a/images/architecture/Faraday_Architecture.png b/images/architecture/Faraday_Architecture.png new file mode 100644 index 00000000000..533ff12d9ab Binary files /dev/null and b/images/architecture/Faraday_Architecture.png differ diff --git a/images/architecture/faraday_schema.png b/images/architecture/faraday_schema.png new file mode 100644 index 00000000000..a155d3e9740 Binary files /dev/null and b/images/architecture/faraday_schema.png differ diff --git a/images/architecture/plugin_architecture.png b/images/architecture/plugin_architecture.png new file mode 100644 index 00000000000..7e0f508cc37 Binary files /dev/null and b/images/architecture/plugin_architecture.png differ diff --git a/images/architecture/plugin_controller.png b/images/architecture/plugin_controller.png new file mode 100644 index 00000000000..e5956d880de Binary files /dev/null and b/images/architecture/plugin_controller.png differ diff --git a/images/assets-services/4.serviceList-v4.png b/images/assets-services/4.serviceList-v4.png new file mode 100644 index 00000000000..16a481c0daa Binary files /dev/null and b/images/assets-services/4.serviceList-v4.png differ diff --git a/images/assets-services/4.serviceList.png b/images/assets-services/4.serviceList.png new file mode 100644 index 00000000000..16a481c0daa Binary files /dev/null and b/images/assets-services/4.serviceList.png differ diff --git a/images/assets-services/6.manageServices1-v4.png b/images/assets-services/6.manageServices1-v4.png new file mode 100644 index 00000000000..03666c9a0c2 Binary files /dev/null and b/images/assets-services/6.manageServices1-v4.png differ diff --git a/images/assets-services/6.manageServices1.png b/images/assets-services/6.manageServices1.png new file mode 100644 index 00000000000..03666c9a0c2 Binary files /dev/null and b/images/assets-services/6.manageServices1.png differ diff --git a/images/assets-services/asset_create-v4.png b/images/assets-services/asset_create-v4.png new file mode 100644 index 00000000000..aa9ab0c1365 Binary files /dev/null and b/images/assets-services/asset_create-v4.png differ diff --git a/images/assets-services/asset_create.png b/images/assets-services/asset_create.png new file mode 100644 index 00000000000..aa9ab0c1365 Binary files /dev/null and b/images/assets-services/asset_create.png differ diff --git a/images/assets-services/asset_delete-v4.png b/images/assets-services/asset_delete-v4.png new file mode 100644 index 00000000000..68dd531c934 Binary files /dev/null and b/images/assets-services/asset_delete-v4.png differ diff --git a/images/assets-services/asset_delete.png b/images/assets-services/asset_delete.png new file mode 100644 index 00000000000..68dd531c934 Binary files /dev/null and b/images/assets-services/asset_delete.png differ diff --git a/images/assets-services/asset_edit-v4.png b/images/assets-services/asset_edit-v4.png new file mode 100644 index 00000000000..56d557ddedc Binary files /dev/null and b/images/assets-services/asset_edit-v4.png differ diff --git a/images/assets-services/asset_edit.png b/images/assets-services/asset_edit.png new file mode 100644 index 00000000000..56d557ddedc Binary files /dev/null and b/images/assets-services/asset_edit.png differ diff --git a/images/assets-services/asset_list-v4.png b/images/assets-services/asset_list-v4.png new file mode 100644 index 00000000000..f422ae84bf9 Binary files /dev/null and b/images/assets-services/asset_list-v4.png differ diff --git a/images/assets-services/asset_list.png b/images/assets-services/asset_list.png new file mode 100644 index 00000000000..f422ae84bf9 Binary files /dev/null and b/images/assets-services/asset_list.png differ diff --git a/images/assets-services/select_asset-v4.png b/images/assets-services/select_asset-v4.png new file mode 100644 index 00000000000..6b213791331 Binary files /dev/null and b/images/assets-services/select_asset-v4.png differ diff --git a/images/assets-services/select_asset.png b/images/assets-services/select_asset.png new file mode 100644 index 00000000000..6b213791331 Binary files /dev/null and b/images/assets-services/select_asset.png differ diff --git a/images/assets-services/service_edit-v4.png b/images/assets-services/service_edit-v4.png new file mode 100644 index 00000000000..816ddd2764f Binary files /dev/null and b/images/assets-services/service_edit-v4.png differ diff --git a/images/assets-services/service_edit.png b/images/assets-services/service_edit.png new file mode 100644 index 00000000000..816ddd2764f Binary files /dev/null and b/images/assets-services/service_edit.png differ diff --git a/images/assets-services/service_list-v4.png b/images/assets-services/service_list-v4.png new file mode 100644 index 00000000000..caf3696622e Binary files /dev/null and b/images/assets-services/service_list-v4.png differ diff --git a/images/assets-services/service_list.png b/images/assets-services/service_list.png new file mode 100644 index 00000000000..caf3696622e Binary files /dev/null and b/images/assets-services/service_list.png differ diff --git a/images/assets-services/service_new-v4.png b/images/assets-services/service_new-v4.png new file mode 100644 index 00000000000..19e947a27d3 Binary files /dev/null and b/images/assets-services/service_new-v4.png differ diff --git a/images/assets-services/service_new.png b/images/assets-services/service_new.png new file mode 100644 index 00000000000..19e947a27d3 Binary files /dev/null and b/images/assets-services/service_new.png differ diff --git a/images/backend/Option-view.png b/images/backend/Option-view.png new file mode 100644 index 00000000000..520e18d2b74 Binary files /dev/null and b/images/backend/Option-view.png differ diff --git a/images/beef/beef-plugin.png b/images/beef/beef-plugin.png new file mode 100644 index 00000000000..8950270ee78 Binary files /dev/null and b/images/beef/beef-plugin.png differ diff --git a/images/beef/starting.png b/images/beef/starting.png new file mode 100644 index 00000000000..7ee2713a498 Binary files /dev/null and b/images/beef/starting.png differ diff --git a/images/burp/burp_config.jpeg b/images/burp/burp_config.jpeg new file mode 100644 index 00000000000..1d3a8d8955e Binary files /dev/null and b/images/burp/burp_config.jpeg differ diff --git a/images/burp/burp_extensions.jpeg b/images/burp/burp_extensions.jpeg new file mode 100644 index 00000000000..739b351457c Binary files /dev/null and b/images/burp/burp_extensions.jpeg differ diff --git a/images/burp/burp_install.jpeg b/images/burp/burp_install.jpeg new file mode 100644 index 00000000000..4dbc47af58c Binary files /dev/null and b/images/burp/burp_install.jpeg differ diff --git a/images/burp/burp_login.jpeg b/images/burp/burp_login.jpeg new file mode 100644 index 00000000000..847c82213f1 Binary files /dev/null and b/images/burp/burp_login.jpeg differ diff --git a/images/burp/burp_login_ok.jpeg b/images/burp/burp_login_ok.jpeg new file mode 100644 index 00000000000..fd448e5cece Binary files /dev/null and b/images/burp/burp_login_ok.jpeg differ diff --git a/images/burp/burp_settings.jpeg b/images/burp/burp_settings.jpeg new file mode 100644 index 00000000000..6f9f012a8f0 Binary files /dev/null and b/images/burp/burp_settings.jpeg differ diff --git a/images/burp/burp_setup.jpeg b/images/burp/burp_setup.jpeg new file mode 100644 index 00000000000..1cc76fd0924 Binary files /dev/null and b/images/burp/burp_setup.jpeg differ diff --git a/images/burp/burp_store.jpeg b/images/burp/burp_store.jpeg new file mode 100644 index 00000000000..d16837e4a41 Binary files /dev/null and b/images/burp/burp_store.jpeg differ diff --git a/images/client/console_log_info.png b/images/client/console_log_info.png new file mode 100644 index 00000000000..ba989e418d4 Binary files /dev/null and b/images/client/console_log_info.png differ diff --git a/images/client/gtk_conflicts_dialog.png b/images/client/gtk_conflicts_dialog.png new file mode 100644 index 00000000000..21e65ec1f29 Binary files /dev/null and b/images/client/gtk_conflicts_dialog.png differ diff --git a/images/client/gtk_host_info_dialog.png b/images/client/gtk_host_info_dialog.png new file mode 100644 index 00000000000..032bf3a488c Binary files /dev/null and b/images/client/gtk_host_info_dialog.png differ diff --git a/images/client/gtk_main_window.png b/images/client/gtk_main_window.png new file mode 100644 index 00000000000..cb1288786cb Binary files /dev/null and b/images/client/gtk_main_window.png differ diff --git a/images/client/gtk_notifications_dialog.png b/images/client/gtk_notifications_dialog.png new file mode 100644 index 00000000000..dcd9301d030 Binary files /dev/null and b/images/client/gtk_notifications_dialog.png differ diff --git a/images/client/no_ui.png b/images/client/no_ui.png new file mode 100644 index 00000000000..bd3e69b6ea1 Binary files /dev/null and b/images/client/no_ui.png differ diff --git a/images/client/no_ui2.png b/images/client/no_ui2.png new file mode 100644 index 00000000000..40d7007344e Binary files /dev/null and b/images/client/no_ui2.png differ diff --git a/images/client/plugin_names.png b/images/client/plugin_names.png new file mode 100644 index 00000000000..6b5d03ee755 Binary files /dev/null and b/images/client/plugin_names.png differ diff --git a/images/client/plugins_list.png b/images/client/plugins_list.png new file mode 100644 index 00000000000..89877029a17 Binary files /dev/null and b/images/client/plugins_list.png differ diff --git a/images/client/report_button.png b/images/client/report_button.png new file mode 100644 index 00000000000..d5cf0ce5266 Binary files /dev/null and b/images/client/report_button.png differ diff --git a/images/client/server.ini.png b/images/client/server.ini.png new file mode 100644 index 00000000000..df4897138e3 Binary files /dev/null and b/images/client/server.ini.png differ diff --git a/images/client/visualize_icon.png b/images/client/visualize_icon.png new file mode 100644 index 00000000000..9fa11249aa6 Binary files /dev/null and b/images/client/visualize_icon.png differ diff --git a/images/client/webshell.png b/images/client/webshell.png new file mode 100644 index 00000000000..79b29fe5766 Binary files /dev/null and b/images/client/webshell.png differ diff --git a/images/comments/adding_comment.png b/images/comments/adding_comment.png new file mode 100644 index 00000000000..e398f8b7bb4 Binary files /dev/null and b/images/comments/adding_comment.png differ diff --git a/images/comments/comment_notification.png b/images/comments/comment_notification.png new file mode 100644 index 00000000000..f5bc93ef092 Binary files /dev/null and b/images/comments/comment_notification.png differ diff --git a/images/comments/comments.gif b/images/comments/comments.gif new file mode 100644 index 00000000000..9bb1b11f338 Binary files /dev/null and b/images/comments/comments.gif differ diff --git a/images/comments/comments_tab.png b/images/comments/comments_tab.png new file mode 100644 index 00000000000..14ce909d7da Binary files /dev/null and b/images/comments/comments_tab.png differ diff --git a/images/comments/notification_opened.png b/images/comments/notification_opened.png new file mode 100644 index 00000000000..a17c696ec35 Binary files /dev/null and b/images/comments/notification_opened.png differ diff --git a/images/comments/writing_comment.png b/images/comments/writing_comment.png new file mode 100644 index 00000000000..cb2589225de Binary files /dev/null and b/images/comments/writing_comment.png differ diff --git a/images/credentials/general_view.png b/images/credentials/general_view.png new file mode 100644 index 00000000000..dfc29661c53 Binary files /dev/null and b/images/credentials/general_view.png differ diff --git a/images/credentials/list_new_credential.png b/images/credentials/list_new_credential.png new file mode 100644 index 00000000000..817e6d6da60 Binary files /dev/null and b/images/credentials/list_new_credential.png differ diff --git a/images/credentials/new.png b/images/credentials/new.png new file mode 100644 index 00000000000..b0df5902562 Binary files /dev/null and b/images/credentials/new.png differ diff --git a/images/credentials/new_button.png b/images/credentials/new_button.png new file mode 100644 index 00000000000..b100797151c Binary files /dev/null and b/images/credentials/new_button.png differ diff --git a/images/credentials/new_credential_from_credential.png b/images/credentials/new_credential_from_credential.png new file mode 100644 index 00000000000..cabe4750faa Binary files /dev/null and b/images/credentials/new_credential_from_credential.png differ diff --git a/images/credentials/new_credential_list.png b/images/credentials/new_credential_list.png new file mode 100644 index 00000000000..7a238aaf4ea Binary files /dev/null and b/images/credentials/new_credential_list.png differ diff --git a/images/credentials/new_credential_modal.png b/images/credentials/new_credential_modal.png new file mode 100644 index 00000000000..61053c811a9 Binary files /dev/null and b/images/credentials/new_credential_modal.png differ diff --git a/images/credentials/select_service.png b/images/credentials/select_service.png new file mode 100644 index 00000000000..0db45e60afe Binary files /dev/null and b/images/credentials/select_service.png differ diff --git a/images/csv-exporter/csv_export.png b/images/csv-exporter/csv_export.png new file mode 100644 index 00000000000..9a3af6e37ce Binary files /dev/null and b/images/csv-exporter/csv_export.png differ diff --git a/images/csv-exporter/csv_file.png b/images/csv-exporter/csv_file.png new file mode 100644 index 00000000000..74f836e158f Binary files /dev/null and b/images/csv-exporter/csv_file.png differ diff --git a/images/csv-exporter/filter_by_field.png b/images/csv-exporter/filter_by_field.png new file mode 100644 index 00000000000..711d34012b3 Binary files /dev/null and b/images/csv-exporter/filter_by_field.png differ diff --git a/images/custom_fields/custom_attr_config.png b/images/custom_fields/custom_attr_config.png new file mode 100644 index 00000000000..6a6e5301026 Binary files /dev/null and b/images/custom_fields/custom_attr_config.png differ diff --git a/images/custom_fields/custom_attr_create.png b/images/custom_fields/custom_attr_create.png new file mode 100644 index 00000000000..86306615b6a Binary files /dev/null and b/images/custom_fields/custom_attr_create.png differ diff --git a/images/custom_fields/custom_attr_display_created.png b/images/custom_fields/custom_attr_display_created.png new file mode 100644 index 00000000000..c6c3bc36461 Binary files /dev/null and b/images/custom_fields/custom_attr_display_created.png differ diff --git a/images/custom_fields/custom_field_creating-v4.png b/images/custom_fields/custom_field_creating-v4.png new file mode 100644 index 00000000000..bcf692489f5 Binary files /dev/null and b/images/custom_fields/custom_field_creating-v4.png differ diff --git a/images/custom_fields/custom_field_creating.png b/images/custom_fields/custom_field_creating.png new file mode 100644 index 00000000000..312895b53ae Binary files /dev/null and b/images/custom_fields/custom_field_creating.png differ diff --git a/images/custom_fields/custom_field_in_vuln_form-v4.png b/images/custom_fields/custom_field_in_vuln_form-v4.png new file mode 100644 index 00000000000..31a79646b38 Binary files /dev/null and b/images/custom_fields/custom_field_in_vuln_form-v4.png differ diff --git a/images/custom_fields/custom_field_in_vuln_form.png b/images/custom_fields/custom_field_in_vuln_form.png new file mode 100644 index 00000000000..8e93f74091e Binary files /dev/null and b/images/custom_fields/custom_field_in_vuln_form.png differ diff --git a/images/custom_fields/custom_field_list.png b/images/custom_fields/custom_field_list.png new file mode 100644 index 00000000000..4755dc9a7b3 Binary files /dev/null and b/images/custom_fields/custom_field_list.png differ diff --git a/images/custom_fields/custom_field_new.png b/images/custom_fields/custom_field_new.png new file mode 100644 index 00000000000..254084cea0d Binary files /dev/null and b/images/custom_fields/custom_field_new.png differ diff --git a/images/custom_fields/custom_field_option-v4.png b/images/custom_fields/custom_field_option-v4.png new file mode 100644 index 00000000000..870836b2815 Binary files /dev/null and b/images/custom_fields/custom_field_option-v4.png differ diff --git a/images/custom_fields/vulnerability_custom_field.png b/images/custom_fields/vulnerability_custom_field.png new file mode 100644 index 00000000000..0536f88c2f9 Binary files /dev/null and b/images/custom_fields/vulnerability_custom_field.png differ diff --git a/images/dashboard.png b/images/dashboard.png new file mode 100644 index 00000000000..4f6c3436618 Binary files /dev/null and b/images/dashboard.png differ diff --git a/images/dashboard/dashboard-activity-v4.png b/images/dashboard/dashboard-activity-v4.png new file mode 100644 index 00000000000..5ef5d7bc6b6 Binary files /dev/null and b/images/dashboard/dashboard-activity-v4.png differ diff --git a/images/dashboard/dashboard-activity.png b/images/dashboard/dashboard-activity.png new file mode 100644 index 00000000000..a243a1ea29a Binary files /dev/null and b/images/dashboard/dashboard-activity.png differ diff --git a/images/dashboard/dashboard-assets-v4.png b/images/dashboard/dashboard-assets-v4.png new file mode 100644 index 00000000000..72badc63955 Binary files /dev/null and b/images/dashboard/dashboard-assets-v4.png differ diff --git a/images/dashboard/dashboard-command.png b/images/dashboard/dashboard-command.png new file mode 100644 index 00000000000..2ee66283fce Binary files /dev/null and b/images/dashboard/dashboard-command.png differ diff --git a/images/dashboard/dashboard-empty-v4.png b/images/dashboard/dashboard-empty-v4.png new file mode 100644 index 00000000000..e7cc2744ba4 Binary files /dev/null and b/images/dashboard/dashboard-empty-v4.png differ diff --git a/images/dashboard/dashboard-empty.png b/images/dashboard/dashboard-empty.png new file mode 100644 index 00000000000..e929ee56dfa Binary files /dev/null and b/images/dashboard/dashboard-empty.png differ diff --git a/images/dashboard/dashboard-full-v4.png b/images/dashboard/dashboard-full-v4.png new file mode 100644 index 00000000000..6bdd4d3c09c Binary files /dev/null and b/images/dashboard/dashboard-full-v4.png differ diff --git a/images/dashboard/dashboard-full.png b/images/dashboard/dashboard-full.png new file mode 100644 index 00000000000..666e57a24a8 Binary files /dev/null and b/images/dashboard/dashboard-full.png differ diff --git a/images/dashboard/dashboard-hosts.png b/images/dashboard/dashboard-hosts.png new file mode 100644 index 00000000000..4c54c356383 Binary files /dev/null and b/images/dashboard/dashboard-hosts.png differ diff --git a/images/dashboard/dashboard-last-vulns-v4.png b/images/dashboard/dashboard-last-vulns-v4.png new file mode 100644 index 00000000000..be72580e8c7 Binary files /dev/null and b/images/dashboard/dashboard-last-vulns-v4.png differ diff --git a/images/dashboard/dashboard-last-vulns.png b/images/dashboard/dashboard-last-vulns.png new file mode 100644 index 00000000000..d000d7c2f41 Binary files /dev/null and b/images/dashboard/dashboard-last-vulns.png differ diff --git a/images/dashboard/dashboard-progress-v4.png b/images/dashboard/dashboard-progress-v4.png new file mode 100644 index 00000000000..0c6e1265eb7 Binary files /dev/null and b/images/dashboard/dashboard-progress-v4.png differ diff --git a/images/dashboard/dashboard-progress.png b/images/dashboard/dashboard-progress.png new file mode 100644 index 00000000000..486075da6db Binary files /dev/null and b/images/dashboard/dashboard-progress.png differ diff --git a/images/dashboard/dashboard-service.png b/images/dashboard/dashboard-service.png new file mode 100644 index 00000000000..27377c9fbd3 Binary files /dev/null and b/images/dashboard/dashboard-service.png differ diff --git a/images/dashboard/dashboard-services-v4.png b/images/dashboard/dashboard-services-v4.png new file mode 100644 index 00000000000..9a2650c972d Binary files /dev/null and b/images/dashboard/dashboard-services-v4.png differ diff --git a/images/dashboard/dashboard-summary-v4.png b/images/dashboard/dashboard-summary-v4.png new file mode 100644 index 00000000000..2cf637063f4 Binary files /dev/null and b/images/dashboard/dashboard-summary-v4.png differ diff --git a/images/dashboard/dashboard-summary.png b/images/dashboard/dashboard-summary.png new file mode 100644 index 00000000000..3796280fd0e Binary files /dev/null and b/images/dashboard/dashboard-summary.png differ diff --git a/images/dashboard/dashboard-switch-ws-v4.png b/images/dashboard/dashboard-switch-ws-v4.png new file mode 100644 index 00000000000..d8b5d12ad50 Binary files /dev/null and b/images/dashboard/dashboard-switch-ws-v4.png differ diff --git a/images/dashboard/dashboard-switch-ws.png b/images/dashboard/dashboard-switch-ws.png new file mode 100644 index 00000000000..ffa6220f7ce Binary files /dev/null and b/images/dashboard/dashboard-switch-ws.png differ diff --git a/images/dashboard/dashboard-tags-v4.png b/images/dashboard/dashboard-tags-v4.png new file mode 100644 index 00000000000..a682bebbbb5 Binary files /dev/null and b/images/dashboard/dashboard-tags-v4.png differ diff --git a/images/dashboard/dashboard-tags.png b/images/dashboard/dashboard-tags.png new file mode 100644 index 00000000000..be42ddf5518 Binary files /dev/null and b/images/dashboard/dashboard-tags.png differ diff --git a/images/dashboard/dashboard-timeline.png b/images/dashboard/dashboard-timeline.png new file mode 100644 index 00000000000..fd771715618 Binary files /dev/null and b/images/dashboard/dashboard-timeline.png differ diff --git a/images/dashboard/dashboard-top-bar.png b/images/dashboard/dashboard-top-bar.png new file mode 100644 index 00000000000..1fddfff0d44 Binary files /dev/null and b/images/dashboard/dashboard-top-bar.png differ diff --git a/images/dashboard/dashboard-top-icon.png b/images/dashboard/dashboard-top-icon.png new file mode 100644 index 00000000000..915cc8468ce Binary files /dev/null and b/images/dashboard/dashboard-top-icon.png differ diff --git a/images/dashboard/dashboard-vulns-cnt.png b/images/dashboard/dashboard-vulns-cnt.png new file mode 100644 index 00000000000..49cd83ed1f4 Binary files /dev/null and b/images/dashboard/dashboard-vulns-cnt.png differ diff --git a/images/dashboard/dashboard.png b/images/dashboard/dashboard.png new file mode 100644 index 00000000000..fd3789cab57 Binary files /dev/null and b/images/dashboard/dashboard.png differ diff --git a/images/dashboard/dashboard_ws_worth.png b/images/dashboard/dashboard_ws_worth.png new file mode 100644 index 00000000000..6906216555d Binary files /dev/null and b/images/dashboard/dashboard_ws_worth.png differ diff --git a/images/data_analysis/graph1.png b/images/data_analysis/graph1.png new file mode 100644 index 00000000000..bd1fbd64e86 Binary files /dev/null and b/images/data_analysis/graph1.png differ diff --git a/images/data_analysis/graph2.png b/images/data_analysis/graph2.png new file mode 100644 index 00000000000..13578f9c9d6 Binary files /dev/null and b/images/data_analysis/graph2.png differ diff --git a/images/data_analysis/graph3.png b/images/data_analysis/graph3.png new file mode 100644 index 00000000000..e12fe156c2b Binary files /dev/null and b/images/data_analysis/graph3.png differ diff --git a/images/data_analysis/overview.png b/images/data_analysis/overview.png new file mode 100644 index 00000000000..aec59c169c4 Binary files /dev/null and b/images/data_analysis/overview.png differ diff --git a/images/demos/newytlogo.png b/images/demos/newytlogo.png new file mode 100644 index 00000000000..cc293820bad Binary files /dev/null and b/images/demos/newytlogo.png differ diff --git a/images/docs_auth.svg b/images/docs_auth.svg new file mode 100644 index 00000000000..bb4be1ab63f --- /dev/null +++ b/images/docs_auth.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ fara (faraday) ~ farad (faraday) ~ farada (faraday) ~ faraday (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli a (faraday) ~ faraday-cli au (faraday) ~ faraday-cli aut (faraday) ~ faraday-cli auth (faraday) ~ faraday-cli auth Faraday url: Faraday url: h Faraday url: ht Faraday url: htt Faraday url: http Faraday url: http: Faraday url: http:/ Faraday url: http:// Faraday url: http://l Faraday url: http://lo Faraday url: http://loc Faraday url: http://loca Faraday url: http://local Faraday url: http://localh Faraday url: http://localho Faraday url: http://localhos Faraday url: http://localhost Faraday url: http://localhost: Faraday url: http://localhost:5 Faraday url: http://localhost:59 Faraday url: http://localhost:598 Faraday url: http://localhost:5985 Faraday url: http://localhost:5985User: User: f User: fa User: far User: fara User: farad User: farada User: faraday User: faradayPassword: Password: Saving config(faraday) ~ + diff --git a/images/executive_reports/2.reportView-v4.png b/images/executive_reports/2.reportView-v4.png new file mode 100644 index 00000000000..7dcc243ce4d Binary files /dev/null and b/images/executive_reports/2.reportView-v4.png differ diff --git a/images/executive_reports/delete_button-v4.png b/images/executive_reports/delete_button-v4.png new file mode 100644 index 00000000000..136415755d7 Binary files /dev/null and b/images/executive_reports/delete_button-v4.png differ diff --git a/images/executive_reports/delete_button.png b/images/executive_reports/delete_button.png new file mode 100644 index 00000000000..ea0abcade0a Binary files /dev/null and b/images/executive_reports/delete_button.png differ diff --git a/images/executive_reports/edit_button.png b/images/executive_reports/edit_button.png new file mode 100644 index 00000000000..88b1d4e9940 Binary files /dev/null and b/images/executive_reports/edit_button.png differ diff --git a/images/executive_reports/executive_report_1-v4.png b/images/executive_reports/executive_report_1-v4.png new file mode 100644 index 00000000000..0a8664ee361 Binary files /dev/null and b/images/executive_reports/executive_report_1-v4.png differ diff --git a/images/executive_reports/executive_report_1.png b/images/executive_reports/executive_report_1.png new file mode 100644 index 00000000000..be5207b5fa2 Binary files /dev/null and b/images/executive_reports/executive_report_1.png differ diff --git a/images/executive_reports/executive_report_2-v4.png b/images/executive_reports/executive_report_2-v4.png new file mode 100644 index 00000000000..f6ec5bfc47e Binary files /dev/null and b/images/executive_reports/executive_report_2-v4.png differ diff --git a/images/executive_reports/executive_report_2.png b/images/executive_reports/executive_report_2.png new file mode 100644 index 00000000000..846f2ade655 Binary files /dev/null and b/images/executive_reports/executive_report_2.png differ diff --git a/images/executive_reports/icon.png b/images/executive_reports/icon.png new file mode 100644 index 00000000000..6435adb8181 Binary files /dev/null and b/images/executive_reports/icon.png differ diff --git a/images/executive_reports/icon2.png b/images/executive_reports/icon2.png new file mode 100644 index 00000000000..462cbc30ea3 Binary files /dev/null and b/images/executive_reports/icon2.png differ diff --git a/images/executive_reports/new.png b/images/executive_reports/new.png new file mode 100644 index 00000000000..7ec1e61155f Binary files /dev/null and b/images/executive_reports/new.png differ diff --git a/images/executive_reports/new_button.png b/images/executive_reports/new_button.png new file mode 100644 index 00000000000..b100797151c Binary files /dev/null and b/images/executive_reports/new_button.png differ diff --git a/images/executive_reports/regenerate_button.png b/images/executive_reports/regenerate_button.png new file mode 100644 index 00000000000..188a902c814 Binary files /dev/null and b/images/executive_reports/regenerate_button.png differ diff --git a/images/executive_reports/reportButton-v4.png b/images/executive_reports/reportButton-v4.png new file mode 100644 index 00000000000..00b980b7a20 Binary files /dev/null and b/images/executive_reports/reportButton-v4.png differ diff --git a/images/executive_reports/report_creation_bin-v4.png b/images/executive_reports/report_creation_bin-v4.png new file mode 100644 index 00000000000..4d0b53edb4b Binary files /dev/null and b/images/executive_reports/report_creation_bin-v4.png differ diff --git a/images/executive_reports/report_creation_fields-v4.png b/images/executive_reports/report_creation_fields-v4.png new file mode 100644 index 00000000000..4172a01ab91 Binary files /dev/null and b/images/executive_reports/report_creation_fields-v4.png differ diff --git a/images/executive_reports/report_creation_filters-v4.png b/images/executive_reports/report_creation_filters-v4.png new file mode 100644 index 00000000000..ecbce214b15 Binary files /dev/null and b/images/executive_reports/report_creation_filters-v4.png differ diff --git a/images/executive_reports/report_creation_image-v4.png b/images/executive_reports/report_creation_image-v4.png new file mode 100644 index 00000000000..75cb5597e1c Binary files /dev/null and b/images/executive_reports/report_creation_image-v4.png differ diff --git a/images/executive_reports/reports_created.png b/images/executive_reports/reports_created.png new file mode 100644 index 00000000000..48a484c635b Binary files /dev/null and b/images/executive_reports/reports_created.png differ diff --git a/images/executive_reports/template_example.png b/images/executive_reports/template_example.png new file mode 100644 index 00000000000..94a6d4f4af7 Binary files /dev/null and b/images/executive_reports/template_example.png differ diff --git a/images/executive_reports/template_faraday_word-v4.png b/images/executive_reports/template_faraday_word-v4.png new file mode 100644 index 00000000000..fd4c831ee84 Binary files /dev/null and b/images/executive_reports/template_faraday_word-v4.png differ diff --git a/images/executive_reports/template_faraday_word.png b/images/executive_reports/template_faraday_word.png new file mode 100644 index 00000000000..b26877b602a Binary files /dev/null and b/images/executive_reports/template_faraday_word.png differ diff --git a/images/executive_reports/using_grouped_vulns.png b/images/executive_reports/using_grouped_vulns.png new file mode 100644 index 00000000000..5dd434fe61f Binary files /dev/null and b/images/executive_reports/using_grouped_vulns.png differ diff --git a/images/executive_reports/using_tags.png b/images/executive_reports/using_tags.png new file mode 100644 index 00000000000..cef20e4beda Binary files /dev/null and b/images/executive_reports/using_tags.png differ diff --git a/images/executive_reports/word.png b/images/executive_reports/word.png new file mode 100644 index 00000000000..70cc84cab19 Binary files /dev/null and b/images/executive_reports/word.png differ diff --git a/images/extras/newytlogo.png b/images/extras/newytlogo.png new file mode 100644 index 00000000000..cc293820bad Binary files /dev/null and b/images/extras/newytlogo.png differ diff --git a/images/extras/security-email.png b/images/extras/security-email.png new file mode 100644 index 00000000000..06f930930ed Binary files /dev/null and b/images/extras/security-email.png differ diff --git a/images/extras/youtube.png b/images/extras/youtube.png new file mode 100644 index 00000000000..b6ef4e16a6a Binary files /dev/null and b/images/extras/youtube.png differ diff --git a/images/faraday-cli/agent.svg b/images/faraday-cli/agent.svg new file mode 100644 index 00000000000..af95f983a09 --- /dev/null +++ b/images/faraday-cli/agent.svg @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ fara (faraday) ~ farad (faraday) ~ farada (faraday) ~ faraday (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli a (faraday) ~ faraday-cli ag (faraday) ~ faraday-cli age (faraday) ~ faraday-cli agen (faraday) ~ faraday-cli agent (faraday) ~ faraday-cli agent id name active status executors---- ------ -------- -------- ----------- 1 agent True online nmap(faraday) ~ faraday-cli agent (faraday) ~ faraday-cli agent - (faraday) ~ faraday-cli agent -a (faraday) ~ faraday-cli agent -a (faraday) ~ faraday-cli agent -a g (faraday) ~ faraday-cli agent -a ge (faraday) ~ faraday-cli agent -a get (faraday) ~ faraday-cli agent -a get (faraday) ~ faraday-cli agent -a get - (faraday) ~ faraday-cli agent -a get -a (faraday) ~ faraday-cli agent -a get -aid (faraday) ~ faraday-cli agent -a get -aid (faraday) ~ faraday-cli agent -a get -aid 1 (faraday) ~ faraday-cli agent -a get -aid 1 id name active status---- ------ -------- -------- 1 agent True onlineExecutors: id name parameters---- ------ ----------------- 1 nmap target, port_list(faraday) ~ faraday-cli agent -a run -aid 1 -eid 1 -p '{"port_list": "1-9000", "target": "192.168.66.1"}' (faraday) ~ faraday-cli agent -a run -aid 1 -eid 1 -p '{"port_list": "1-9000", "target": "192.168.66.1"}' target": "192.168.66.1"}' Run executor: agent/nmap [{'successful': True}](faraday) ~ + diff --git a/images/faraday-cli/auth.svg b/images/faraday-cli/auth.svg new file mode 100644 index 00000000000..bb4be1ab63f --- /dev/null +++ b/images/faraday-cli/auth.svg @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ fara (faraday) ~ farad (faraday) ~ farada (faraday) ~ faraday (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli a (faraday) ~ faraday-cli au (faraday) ~ faraday-cli aut (faraday) ~ faraday-cli auth (faraday) ~ faraday-cli auth Faraday url: Faraday url: h Faraday url: ht Faraday url: htt Faraday url: http Faraday url: http: Faraday url: http:/ Faraday url: http:// Faraday url: http://l Faraday url: http://lo Faraday url: http://loc Faraday url: http://loca Faraday url: http://local Faraday url: http://localh Faraday url: http://localho Faraday url: http://localhos Faraday url: http://localhost Faraday url: http://localhost: Faraday url: http://localhost:5 Faraday url: http://localhost:59 Faraday url: http://localhost:598 Faraday url: http://localhost:5985 Faraday url: http://localhost:5985User: User: f User: fa User: far User: fara User: farad User: farada User: faraday User: faradayPassword: Password: Saving config(faraday) ~ + diff --git a/images/faraday-cli/create_host.svg b/images/faraday-cli/create_host.svg new file mode 100644 index 00000000000..5a5db67088e --- /dev/null +++ b/images/faraday-cli/create_host.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ echo '[{"ip": "stan.local", "description": "some server"}]' | faraday-cli host -a create --stdin (faraday) ~ echo '[{"ip": "stan.local", "description": "some server"}]' | faraday-cli host -a create --stdin (faraday) ~ echo '[{"ip": "stan.local", "description": "some server"}]' | faraday-cli host -a create --stdin Created host{ "os": "", "owned": false, "services": 0, "metadata": { "owner": "faraday", "create_time": "2020-07-31T20:39:14.765690+00:00", "update_controller_action": "", "command_id": null, "creator": "", "update_user": null, "update_action": 0, "update_time": "2020-07-31T20:39:14.789449+00:00" }, "credentials": 0, "name": "192.168.66.108", "mac": "", "versions": [], "tags": [], "description": "some server", "hostnames": [ "stan.local" ], "service_summaries": [], "type": "Host", "default_gateway": "", "_rev": "", "_id": 228, "owner": "faraday", "vulns": 0, "ip": "192.168.66.108", "id": 228}(faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli h (faraday) ~ faraday-cli ho (faraday) ~ faraday-cli hos (faraday) ~ faraday-cli host (faraday) ~ faraday-cli host id ip os hostnames services vulns---- -------------- ---- ----------- ---------- ------- 228 192.168.66.108 stan.local 0 0(faraday) ~ + diff --git a/images/faraday-cli/get_host.svg b/images/faraday-cli/get_host.svg new file mode 100644 index 00000000000..86e8dd41877 --- /dev/null +++ b/images/faraday-cli/get_host.svg @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ fara (faraday) ~ farad (faraday) ~ farada (faraday) ~ faraday (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli h (faraday) ~ faraday-cli ho (faraday) ~ faraday-cli hos (faraday) ~ faraday-cli host (faraday) ~ faraday-cli host (faraday) ~ faraday-cli host - (faraday) ~ faraday-cli host -a (faraday) ~ faraday-cli host -a (faraday) ~ faraday-cli host -a g (faraday) ~ faraday-cli host -a ge (faraday) ~ faraday-cli host -a get (faraday) ~ faraday-cli host -a get (faraday) ~ faraday-cli host -a get - (faraday) ~ faraday-cli host -a get -i (faraday) ~ faraday-cli host -a get -hid (faraday) ~ faraday-cli host -a get -hid (faraday) ~ faraday-cli host -a get -hid 1 (faraday) ~ faraday-cli host -a get -hid 19 (faraday) ~ faraday-cli host -a get -hid 199 (faraday) ~ faraday-cli host -a get -hid 199 id name ip os hostnames owner owned---- -------------- -------------- ------- ----------- ------- ------- 199 192.168.66.108 192.168.66.108 unknown stan.local faraday False id name description protocol port version status vulns---- ------------ ------------- ---------- ------ ------------------------ -------- ------- 196 ssh ssh tcp 22 OpenSSH 7.8 open 1 197 http http tcp 80 nginx 1.17.10 open 2 198 kerberos-sec kerberos-sec tcp 88 Heimdal Kerberos open 0 199 https https tcp 443 nginx 1.17.10 open 6 200 microsoft-ds microsoft-ds tcp 445 201 vnc vnc tcp 5900 Apple remote desktop vnc 202 cslistener cslistener tcp 9000 (faraday) ~ + diff --git a/images/faraday-cli/list_hosts.svg b/images/faraday-cli/list_hosts.svg new file mode 100644 index 00000000000..8fd99ac042f --- /dev/null +++ b/images/faraday-cli/list_hosts.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ fara (faraday) ~ farad (faraday) ~ farada (faraday) ~ faraday (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli h (faraday) ~ faraday-cli ho (faraday) ~ faraday-cli hos (faraday) ~ faraday-cli host (faraday) ~ faraday-cli host id name ip os hostnames services vulns---- -------------- -------------- ------- ----------- ---------- ------- 188 127.0.0.10 127.0.0.10 unknown 1 3 191 127.0.0.11 127.0.0.11 unknown 1 3 190 127.0.0.12 127.0.0.12 unknown 1 3 192 127.0.0.13 127.0.0.13 unknown 1 3 198 127.0.0.2 127.0.0.2 unknown 1 3 187 127.0.0.3 127.0.0.3 unknown 1 3 194 127.0.0.4 127.0.0.4 unknown 1 3 195 127.0.0.5 127.0.0.5 unknown 1 3 189 127.0.0.6 127.0.0.6 unknown 1 3 193 127.0.0.7 127.0.0.7 unknown 1 3 186 127.0.0.8 127.0.0.8 unknown 186 127.0.0.8 127.0.0.8 unknown 1 3 197 127.0.0.9 127.0.0.9 unknown 1 3 199 192.168.66.108 192.168.66.108 unknown stan.local 7 19(faraday) ~ + diff --git a/images/faraday-cli/list_workspace.svg b/images/faraday-cli/list_workspace.svg new file mode 100644 index 00000000000..da00ce51a1d --- /dev/null +++ b/images/faraday-cli/list_workspace.svg @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + (faraday) ~ (faraday) ~ f (faraday) ~ fa (faraday) ~ far (faraday) ~ fara (faraday) ~ farad (faraday) ~ farada (faraday) ~ faraday (faraday) ~ faraday- (faraday) ~ faraday-c (faraday) ~ faraday-cl (faraday) ~ faraday-cli (faraday) ~ faraday-cli (faraday) ~ faraday-cli w (faraday) ~ faraday-cli wo (faraday) ~ faraday-cli wor (faraday) ~ faraday-cli work (faraday) ~ faraday-cli works (faraday) ~ faraday-cli worksp (faraday) ~ faraday-cli workspa (faraday) ~ faraday-cli workspac (faraday) ~ faraday-cli workspace (faraday) ~ faraday-cli workspace name hosts services vulns------ ------- ---------- -------demo 13 19 55(faraday) ~ + diff --git a/images/faraday_addon/button_requests.png b/images/faraday_addon/button_requests.png new file mode 100644 index 00000000000..da8eb65d668 Binary files /dev/null and b/images/faraday_addon/button_requests.png differ diff --git a/images/faraday_addon/button_with_worksapce.png b/images/faraday_addon/button_with_worksapce.png new file mode 100644 index 00000000000..efd89768f27 Binary files /dev/null and b/images/faraday_addon/button_with_worksapce.png differ diff --git a/images/faraday_addon/button_with_workspace.png b/images/faraday_addon/button_with_workspace.png new file mode 100644 index 00000000000..efd89768f27 Binary files /dev/null and b/images/faraday_addon/button_with_workspace.png differ diff --git a/images/faraday_addon/button_without_workspace.png b/images/faraday_addon/button_without_workspace.png new file mode 100644 index 00000000000..ced950fc9f3 Binary files /dev/null and b/images/faraday_addon/button_without_workspace.png differ diff --git a/images/faraday_addon/configuration.png b/images/faraday_addon/configuration.png new file mode 100644 index 00000000000..eb3d8d6aac0 Binary files /dev/null and b/images/faraday_addon/configuration.png differ diff --git a/images/faraday_addon/creating_vuln.png b/images/faraday_addon/creating_vuln.png new file mode 100644 index 00000000000..5ea411c52e5 Binary files /dev/null and b/images/faraday_addon/creating_vuln.png differ diff --git a/images/faraday_addon/dashboard.png b/images/faraday_addon/dashboard.png new file mode 100644 index 00000000000..06a01854f41 Binary files /dev/null and b/images/faraday_addon/dashboard.png differ diff --git a/images/faraday_addon/dashboard_2.png b/images/faraday_addon/dashboard_2.png new file mode 100644 index 00000000000..22a2cd7d274 Binary files /dev/null and b/images/faraday_addon/dashboard_2.png differ diff --git a/images/faraday_addon/firefox-icon.png b/images/faraday_addon/firefox-icon.png new file mode 100644 index 00000000000..8c56c79c87b Binary files /dev/null and b/images/faraday_addon/firefox-icon.png differ diff --git a/images/faraday_addon/requests.png b/images/faraday_addon/requests.png new file mode 100644 index 00000000000..d5d335e1b15 Binary files /dev/null and b/images/faraday_addon/requests.png differ diff --git a/images/favicon.png b/images/favicon.png new file mode 100644 index 00000000000..646f413ca45 Binary files /dev/null and b/images/favicon.png differ diff --git a/images/filters/adv_filters_00.png b/images/filters/adv_filters_00.png new file mode 100644 index 00000000000..f3fad82e7f1 Binary files /dev/null and b/images/filters/adv_filters_00.png differ diff --git a/images/filters/assets_02.png b/images/filters/assets_02.png new file mode 100644 index 00000000000..aa4f44ac382 Binary files /dev/null and b/images/filters/assets_02.png differ diff --git a/images/filters/assets_03.png b/images/filters/assets_03.png new file mode 100644 index 00000000000..46fdcdd035d Binary files /dev/null and b/images/filters/assets_03.png differ diff --git a/images/filters/assets_04.png b/images/filters/assets_04.png new file mode 100644 index 00000000000..8896543e959 Binary files /dev/null and b/images/filters/assets_04.png differ diff --git a/images/filters/assets_05.png b/images/filters/assets_05.png new file mode 100644 index 00000000000..583e45a4d2f Binary files /dev/null and b/images/filters/assets_05.png differ diff --git a/images/filters/filters_0.png b/images/filters/filters_0.png new file mode 100644 index 00000000000..28bee387838 Binary files /dev/null and b/images/filters/filters_0.png differ diff --git a/images/filters/filters_01.png b/images/filters/filters_01.png new file mode 100644 index 00000000000..c865bb06d6e Binary files /dev/null and b/images/filters/filters_01.png differ diff --git a/images/filters/filters_02.png b/images/filters/filters_02.png new file mode 100644 index 00000000000..0e65d42390b Binary files /dev/null and b/images/filters/filters_02.png differ diff --git a/images/filters/filters_03.png b/images/filters/filters_03.png new file mode 100644 index 00000000000..2b36261c68f Binary files /dev/null and b/images/filters/filters_03.png differ diff --git a/images/filters/filters_04.png b/images/filters/filters_04.png new file mode 100644 index 00000000000..6b7b3286129 Binary files /dev/null and b/images/filters/filters_04.png differ diff --git a/images/filters/filters_05.png b/images/filters/filters_05.png new file mode 100644 index 00000000000..e6ba6b9e78b Binary files /dev/null and b/images/filters/filters_05.png differ diff --git a/images/first-step/login.png b/images/first-step/login.png new file mode 100644 index 00000000000..4eb2701f561 Binary files /dev/null and b/images/first-step/login.png differ diff --git a/images/first-step/workspace.png b/images/first-step/workspace.png new file mode 100644 index 00000000000..096d40d3d15 Binary files /dev/null and b/images/first-step/workspace.png differ diff --git a/images/flags/argentina.png b/images/flags/argentina.png new file mode 100644 index 00000000000..af79ba97880 Binary files /dev/null and b/images/flags/argentina.png differ diff --git a/images/flags/brazil.png b/images/flags/brazil.png new file mode 100644 index 00000000000..7da72fbfed4 Binary files /dev/null and b/images/flags/brazil.png differ diff --git a/images/flags/chile.png b/images/flags/chile.png new file mode 100644 index 00000000000..c3f6ead035f Binary files /dev/null and b/images/flags/chile.png differ diff --git a/images/flags/europe.png b/images/flags/europe.png new file mode 100644 index 00000000000..00e9ec919bc Binary files /dev/null and b/images/flags/europe.png differ diff --git a/images/flags/israel.png b/images/flags/israel.png new file mode 100644 index 00000000000..c6849b4e542 Binary files /dev/null and b/images/flags/israel.png differ diff --git a/images/flags/japan.png b/images/flags/japan.png new file mode 100644 index 00000000000..ab562613b53 Binary files /dev/null and b/images/flags/japan.png differ diff --git a/images/flags/russia.png b/images/flags/russia.png new file mode 100644 index 00000000000..81e15d950ce Binary files /dev/null and b/images/flags/russia.png differ diff --git a/images/flags/singapore.png b/images/flags/singapore.png new file mode 100644 index 00000000000..e86187a1606 Binary files /dev/null and b/images/flags/singapore.png differ diff --git a/images/flags/uae.png b/images/flags/uae.png new file mode 100644 index 00000000000..76d346c3b13 Binary files /dev/null and b/images/flags/uae.png differ diff --git a/images/flags/uruguay.png b/images/flags/uruguay.png new file mode 100644 index 00000000000..23ac9eb061c Binary files /dev/null and b/images/flags/uruguay.png differ diff --git a/images/flags/usa.png b/images/flags/usa.png new file mode 100644 index 00000000000..f05d7ba54fb Binary files /dev/null and b/images/flags/usa.png differ diff --git a/images/general.gif b/images/general.gif new file mode 100644 index 00000000000..611bbfa6845 Binary files /dev/null and b/images/general.gif differ diff --git a/images/history/GUI_Status_Report.png b/images/history/GUI_Status_Report.png new file mode 100644 index 00000000000..daa8bebd264 Binary files /dev/null and b/images/history/GUI_Status_Report.png differ diff --git a/images/history/Hostree filter.png b/images/history/Hostree filter.png new file mode 100644 index 00000000000..f5a3d2a85e5 Binary files /dev/null and b/images/history/Hostree filter.png differ diff --git a/images/history/Plugin settings - Faraday.png b/images/history/Plugin settings - Faraday.png new file mode 100644 index 00000000000..6989673e7b4 Binary files /dev/null and b/images/history/Plugin settings - Faraday.png differ diff --git a/images/history/faraday_qt.png b/images/history/faraday_qt.png new file mode 100644 index 00000000000..1abcc894457 Binary files /dev/null and b/images/history/faraday_qt.png differ diff --git a/images/history/filter_ip_port.png b/images/history/filter_ip_port.png new file mode 100644 index 00000000000..b753e546707 Binary files /dev/null and b/images/history/filter_ip_port.png differ diff --git a/images/history/logo.png b/images/history/logo.png new file mode 100644 index 00000000000..36ccf51fb7f Binary files /dev/null and b/images/history/logo.png differ diff --git a/images/history/prevedit.png b/images/history/prevedit.png new file mode 100644 index 00000000000..b9be2a42193 Binary files /dev/null and b/images/history/prevedit.png differ diff --git a/images/hosts-services/host_create.png b/images/hosts-services/host_create.png new file mode 100644 index 00000000000..8814989119a Binary files /dev/null and b/images/hosts-services/host_create.png differ diff --git a/images/hosts-services/host_delete.png b/images/hosts-services/host_delete.png new file mode 100644 index 00000000000..59264564196 Binary files /dev/null and b/images/hosts-services/host_delete.png differ diff --git a/images/hosts-services/host_edit.png b/images/hosts-services/host_edit.png new file mode 100644 index 00000000000..aec6fcd445a Binary files /dev/null and b/images/hosts-services/host_edit.png differ diff --git a/images/hosts-services/host_list.png b/images/hosts-services/host_list.png new file mode 100644 index 00000000000..8f9a99f4b90 Binary files /dev/null and b/images/hosts-services/host_list.png differ diff --git a/images/hosts-services/host_tools.png b/images/hosts-services/host_tools.png new file mode 100644 index 00000000000..98f9eb7e505 Binary files /dev/null and b/images/hosts-services/host_tools.png differ diff --git a/images/hosts-services/hosts_view.png b/images/hosts-services/hosts_view.png new file mode 100644 index 00000000000..7ae73b13f84 Binary files /dev/null and b/images/hosts-services/hosts_view.png differ diff --git a/images/hosts-services/icon.png b/images/hosts-services/icon.png new file mode 100644 index 00000000000..ded949b1097 Binary files /dev/null and b/images/hosts-services/icon.png differ diff --git a/images/hosts-services/select_host.png b/images/hosts-services/select_host.png new file mode 100644 index 00000000000..10ab593a274 Binary files /dev/null and b/images/hosts-services/select_host.png differ diff --git a/images/hosts-services/service_button.png b/images/hosts-services/service_button.png new file mode 100644 index 00000000000..e0af257eec3 Binary files /dev/null and b/images/hosts-services/service_button.png differ diff --git a/images/hosts-services/service_button2.png b/images/hosts-services/service_button2.png new file mode 100644 index 00000000000..09927470f1a Binary files /dev/null and b/images/hosts-services/service_button2.png differ diff --git a/images/hosts-services/service_delete.png b/images/hosts-services/service_delete.png new file mode 100644 index 00000000000..aa4bdec2e95 Binary files /dev/null and b/images/hosts-services/service_delete.png differ diff --git a/images/hosts-services/service_edit.png b/images/hosts-services/service_edit.png new file mode 100644 index 00000000000..7ede785c55b Binary files /dev/null and b/images/hosts-services/service_edit.png differ diff --git a/images/hosts-services/service_list.png b/images/hosts-services/service_list.png new file mode 100644 index 00000000000..2b0b3a5db49 Binary files /dev/null and b/images/hosts-services/service_list.png differ diff --git a/images/hosts-services/service_new.png b/images/hosts-services/service_new.png new file mode 100644 index 00000000000..8536c6d2980 Binary files /dev/null and b/images/hosts-services/service_new.png differ diff --git a/images/index/faraday_images-06.png b/images/index/faraday_images-06.png new file mode 100644 index 00000000000..3dbd55a085c Binary files /dev/null and b/images/index/faraday_images-06.png differ diff --git a/images/index/img_desktop_report.png b/images/index/img_desktop_report.png new file mode 100644 index 00000000000..bed9c1f138e Binary files /dev/null and b/images/index/img_desktop_report.png differ diff --git a/images/index/integrate-gitlab.png b/images/index/integrate-gitlab.png new file mode 100644 index 00000000000..ed3d8649d57 Binary files /dev/null and b/images/index/integrate-gitlab.png differ diff --git a/images/index/presentations.png b/images/index/presentations.png new file mode 100644 index 00000000000..421a74ee517 Binary files /dev/null and b/images/index/presentations.png differ diff --git a/images/index/supported-tools.png b/images/index/supported-tools.png new file mode 100644 index 00000000000..89859ec63c1 Binary files /dev/null and b/images/index/supported-tools.png differ diff --git a/images/installation/confirm.png b/images/installation/confirm.png new file mode 100644 index 00000000000..c66d8930c50 Binary files /dev/null and b/images/installation/confirm.png differ diff --git a/images/installation/gtk_preferences_dialog.png b/images/installation/gtk_preferences_dialog.png new file mode 100644 index 00000000000..9e0c7a66ab1 Binary files /dev/null and b/images/installation/gtk_preferences_dialog.png differ diff --git a/images/installation/gtk_preferences_icon.png b/images/installation/gtk_preferences_icon.png new file mode 100644 index 00000000000..7d4afa9a540 Binary files /dev/null and b/images/installation/gtk_preferences_icon.png differ diff --git a/images/installation/xcode.png b/images/installation/xcode.png new file mode 100644 index 00000000000..1d12b523798 Binary files /dev/null and b/images/installation/xcode.png differ diff --git a/images/integrations/Settings.png b/images/integrations/Settings.png new file mode 100644 index 00000000000..19d967683c5 Binary files /dev/null and b/images/integrations/Settings.png differ diff --git a/images/integrations/add-column.png b/images/integrations/add-column.png new file mode 100644 index 00000000000..452660ce51d Binary files /dev/null and b/images/integrations/add-column.png differ diff --git a/images/integrations/censys.png b/images/integrations/censys.png new file mode 100644 index 00000000000..0fd60fb9ff1 Binary files /dev/null and b/images/integrations/censys.png differ diff --git a/images/integrations/faraday-succeed.png b/images/integrations/faraday-succeed.png new file mode 100644 index 00000000000..b8d8a064f6c Binary files /dev/null and b/images/integrations/faraday-succeed.png differ diff --git a/images/integrations/gitlab/api-created.png b/images/integrations/gitlab/api-created.png new file mode 100644 index 00000000000..380f46bb348 Binary files /dev/null and b/images/integrations/gitlab/api-created.png differ diff --git a/images/integrations/gitlab/gitlab-access-api.png b/images/integrations/gitlab/gitlab-access-api.png new file mode 100644 index 00000000000..64776d0e97a Binary files /dev/null and b/images/integrations/gitlab/gitlab-access-api.png differ diff --git a/images/integrations/gitlab/gitlab-access-tokens.png b/images/integrations/gitlab/gitlab-access-tokens.png new file mode 100644 index 00000000000..24f837f9004 Binary files /dev/null and b/images/integrations/gitlab/gitlab-access-tokens.png differ diff --git a/images/integrations/gitlab/gitlab-issue.png b/images/integrations/gitlab/gitlab-issue.png new file mode 100644 index 00000000000..62c3436fede Binary files /dev/null and b/images/integrations/gitlab/gitlab-issue.png differ diff --git a/images/integrations/gitlab/gitlab-projects.png b/images/integrations/gitlab/gitlab-projects.png new file mode 100644 index 00000000000..5f54d7dba27 Binary files /dev/null and b/images/integrations/gitlab/gitlab-projects.png differ diff --git a/images/integrations/gitlab/gitlab-settings.png b/images/integrations/gitlab/gitlab-settings.png new file mode 100644 index 00000000000..89d7f5c1990 Binary files /dev/null and b/images/integrations/gitlab/gitlab-settings.png differ diff --git a/images/integrations/gitlab/send-to-gitlab.png b/images/integrations/gitlab/send-to-gitlab.png new file mode 100644 index 00000000000..445b8768298 Binary files /dev/null and b/images/integrations/gitlab/send-to-gitlab.png differ diff --git a/images/integrations/gitlab/ticketing-tools-gitlab.png b/images/integrations/gitlab/ticketing-tools-gitlab.png new file mode 100644 index 00000000000..ffca37a7b3b Binary files /dev/null and b/images/integrations/gitlab/ticketing-tools-gitlab.png differ diff --git a/images/integrations/gitlab/tools-gitlab.png b/images/integrations/gitlab/tools-gitlab.png new file mode 100644 index 00000000000..4e9bf4fff7a Binary files /dev/null and b/images/integrations/gitlab/tools-gitlab.png differ diff --git a/images/integrations/jira/Jira-Projects.png b/images/integrations/jira/Jira-Projects.png new file mode 100644 index 00000000000..d0407f9ecbe Binary files /dev/null and b/images/integrations/jira/Jira-Projects.png differ diff --git a/images/integrations/jira/Preferences-ticketing-tools.png b/images/integrations/jira/Preferences-ticketing-tools.png new file mode 100644 index 00000000000..48bce9c0ef2 Binary files /dev/null and b/images/integrations/jira/Preferences-ticketing-tools.png differ diff --git a/images/integrations/jira/all-applications-jira.png b/images/integrations/jira/all-applications-jira.png new file mode 100644 index 00000000000..6aa15389146 Binary files /dev/null and b/images/integrations/jira/all-applications-jira.png differ diff --git a/images/integrations/jira/application-fields-jira.png b/images/integrations/jira/application-fields-jira.png new file mode 100644 index 00000000000..7a82aa5a9ab Binary files /dev/null and b/images/integrations/jira/application-fields-jira.png differ diff --git a/images/integrations/jira/application-links-jira.png b/images/integrations/jira/application-links-jira.png new file mode 100644 index 00000000000..93de0445320 Binary files /dev/null and b/images/integrations/jira/application-links-jira.png differ diff --git a/images/integrations/jira/approved-message.png b/images/integrations/jira/approved-message.png new file mode 100644 index 00000000000..d3764164f34 Binary files /dev/null and b/images/integrations/jira/approved-message.png differ diff --git a/images/integrations/jira/authorize-faraday.png b/images/integrations/jira/authorize-faraday.png new file mode 100644 index 00000000000..63ee264e588 Binary files /dev/null and b/images/integrations/jira/authorize-faraday.png differ diff --git a/images/integrations/jira/button.png b/images/integrations/jira/button.png new file mode 100644 index 00000000000..92c6aa5f9ca Binary files /dev/null and b/images/integrations/jira/button.png differ diff --git a/images/integrations/jira/dialog_default_data.png b/images/integrations/jira/dialog_default_data.png new file mode 100644 index 00000000000..ed8dce64981 Binary files /dev/null and b/images/integrations/jira/dialog_default_data.png differ diff --git a/images/integrations/jira/dialog_overwrited_data.png b/images/integrations/jira/dialog_overwrited_data.png new file mode 100644 index 00000000000..41f56efeb06 Binary files /dev/null and b/images/integrations/jira/dialog_overwrited_data.png differ diff --git a/images/integrations/jira/issuetracker.png b/images/integrations/jira/issuetracker.png new file mode 100644 index 00000000000..ecebe83933e Binary files /dev/null and b/images/integrations/jira/issuetracker.png differ diff --git a/images/integrations/jira/jira-application-error.png b/images/integrations/jira/jira-application-error.png new file mode 100644 index 00000000000..398e7436a23 Binary files /dev/null and b/images/integrations/jira/jira-application-error.png differ diff --git a/images/integrations/jira/jira-issue.png b/images/integrations/jira/jira-issue.png new file mode 100644 index 00000000000..68f05f01883 Binary files /dev/null and b/images/integrations/jira/jira-issue.png differ diff --git a/images/integrations/jira/jira-software-projects.png b/images/integrations/jira/jira-software-projects.png new file mode 100644 index 00000000000..f875ce50ffd Binary files /dev/null and b/images/integrations/jira/jira-software-projects.png differ diff --git a/images/integrations/jira/jira-website.png b/images/integrations/jira/jira-website.png new file mode 100644 index 00000000000..e30366a5c3d Binary files /dev/null and b/images/integrations/jira/jira-website.png differ diff --git a/images/integrations/jira/link-applications-jira.png b/images/integrations/jira/link-applications-jira.png new file mode 100644 index 00000000000..ea6e9a628c1 Binary files /dev/null and b/images/integrations/jira/link-applications-jira.png differ diff --git a/images/integrations/jira/oauth-succeed.png b/images/integrations/jira/oauth-succeed.png new file mode 100644 index 00000000000..533669d1847 Binary files /dev/null and b/images/integrations/jira/oauth-succeed.png differ diff --git a/images/integrations/jira/products-jira.png b/images/integrations/jira/products-jira.png new file mode 100644 index 00000000000..2ef5d86ac1a Binary files /dev/null and b/images/integrations/jira/products-jira.png differ diff --git a/images/integrations/jira/search_jira_users.png b/images/integrations/jira/search_jira_users.png new file mode 100644 index 00000000000..b9d5bd59eef Binary files /dev/null and b/images/integrations/jira/search_jira_users.png differ diff --git a/images/integrations/jira/send-to-jira.png b/images/integrations/jira/send-to-jira.png new file mode 100644 index 00000000000..2b4cc0936e6 Binary files /dev/null and b/images/integrations/jira/send-to-jira.png differ diff --git a/images/integrations/jira/succeed_jira_user.png b/images/integrations/jira/succeed_jira_user.png new file mode 100644 index 00000000000..c29c784fe59 Binary files /dev/null and b/images/integrations/jira/succeed_jira_user.png differ diff --git a/images/integrations/jira/ticketing-tool-jira.png b/images/integrations/jira/ticketing-tool-jira.png new file mode 100644 index 00000000000..6bd1c627c90 Binary files /dev/null and b/images/integrations/jira/ticketing-tool-jira.png differ diff --git a/images/integrations/jira/tools-jira.png b/images/integrations/jira/tools-jira.png new file mode 100644 index 00000000000..4042e2611e4 Binary files /dev/null and b/images/integrations/jira/tools-jira.png differ diff --git a/images/integrations/jira/vuln-with-jira.png b/images/integrations/jira/vuln-with-jira.png new file mode 100644 index 00000000000..6a0016d98a6 Binary files /dev/null and b/images/integrations/jira/vuln-with-jira.png differ diff --git a/images/integrations/netdb.png b/images/integrations/netdb.png new file mode 100644 index 00000000000..64cb714caf6 Binary files /dev/null and b/images/integrations/netdb.png differ diff --git a/images/integrations/shodan.png b/images/integrations/shodan.png new file mode 100644 index 00000000000..4d5002717d8 Binary files /dev/null and b/images/integrations/shodan.png differ diff --git a/images/integrations/with-tracker.png b/images/integrations/with-tracker.png new file mode 100644 index 00000000000..f0bcb88cf76 Binary files /dev/null and b/images/integrations/with-tracker.png differ diff --git a/images/integrations/without-tracker.png b/images/integrations/without-tracker.png new file mode 100644 index 00000000000..747ede98580 Binary files /dev/null and b/images/integrations/without-tracker.png differ diff --git a/images/ldap/domain_view.png b/images/ldap/domain_view.png new file mode 100644 index 00000000000..bd40c223130 Binary files /dev/null and b/images/ldap/domain_view.png differ diff --git a/images/ldap/okta-add-interface.png b/images/ldap/okta-add-interface.png new file mode 100644 index 00000000000..853455c8668 Binary files /dev/null and b/images/ldap/okta-add-interface.png differ diff --git a/images/ldap/preferences-ldap.png b/images/ldap/preferences-ldap.png new file mode 100644 index 00000000000..8326bcd688d Binary files /dev/null and b/images/ldap/preferences-ldap.png differ diff --git a/images/ldap/user_view.png b/images/ldap/user_view.png new file mode 100644 index 00000000000..1dee2576e06 Binary files /dev/null and b/images/ldap/user_view.png differ diff --git a/images/logo.svg b/images/logo.svg new file mode 100644 index 00000000000..c8a0ac20f26 --- /dev/null +++ b/images/logo.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/images/manage.png b/images/manage.png new file mode 100644 index 00000000000..1e581de432b Binary files /dev/null and b/images/manage.png differ diff --git a/images/manage/manage-v4.png b/images/manage/manage-v4.png new file mode 100644 index 00000000000..d4cd7a2e73b Binary files /dev/null and b/images/manage/manage-v4.png differ diff --git a/images/manage/manage.png b/images/manage/manage.png new file mode 100644 index 00000000000..e7482cdc374 Binary files /dev/null and b/images/manage/manage.png differ diff --git a/images/notifications/Notification_Center-config-slack-save.png b/images/notifications/Notification_Center-config-slack-save.png new file mode 100644 index 00000000000..e6c20a92b8e Binary files /dev/null and b/images/notifications/Notification_Center-config-slack-save.png differ diff --git a/images/notifications/Notifications_Center_Settings.png b/images/notifications/Notifications_Center_Settings.png new file mode 100644 index 00000000000..9f33833615c Binary files /dev/null and b/images/notifications/Notifications_Center_Settings.png differ diff --git a/images/notifications/activity_dashboard.png b/images/notifications/activity_dashboard.png new file mode 100644 index 00000000000..3e7279916f1 Binary files /dev/null and b/images/notifications/activity_dashboard.png differ diff --git a/images/notifications/notification-settings-2.png b/images/notifications/notification-settings-2.png new file mode 100644 index 00000000000..50bcde76a4e Binary files /dev/null and b/images/notifications/notification-settings-2.png differ diff --git a/images/notifications/notifications-bell.png b/images/notifications/notifications-bell.png new file mode 100644 index 00000000000..42a8e83d219 Binary files /dev/null and b/images/notifications/notifications-bell.png differ diff --git a/images/notifications/notifications-logs.png b/images/notifications/notifications-logs.png new file mode 100644 index 00000000000..322547d4ff2 Binary files /dev/null and b/images/notifications/notifications-logs.png differ diff --git a/images/notifications/notifications-slack-create-new-app.png b/images/notifications/notifications-slack-create-new-app.png new file mode 100644 index 00000000000..281ea58cb49 Binary files /dev/null and b/images/notifications/notifications-slack-create-new-app.png differ diff --git a/images/notifications/notifications-slack-from-app-manifest.png b/images/notifications/notifications-slack-from-app-manifest.png new file mode 100644 index 00000000000..5c086b6f207 Binary files /dev/null and b/images/notifications/notifications-slack-from-app-manifest.png differ diff --git a/images/notifications/notifications-slack-oauth-token-install-orgwide.png b/images/notifications/notifications-slack-oauth-token-install-orgwide.png new file mode 100644 index 00000000000..fae9a41a413 Binary files /dev/null and b/images/notifications/notifications-slack-oauth-token-install-orgwide.png differ diff --git a/images/notifications/notifications-slack-oauth.png b/images/notifications/notifications-slack-oauth.png new file mode 100644 index 00000000000..7250b03d002 Binary files /dev/null and b/images/notifications/notifications-slack-oauth.png differ diff --git a/images/notifications/notifications-slack-pick-a-workspace.png b/images/notifications/notifications-slack-pick-a-workspace.png new file mode 100644 index 00000000000..9e840e6d5ef Binary files /dev/null and b/images/notifications/notifications-slack-pick-a-workspace.png differ diff --git a/images/pipelines/jobs-attributes.png b/images/pipelines/jobs-attributes.png new file mode 100644 index 00000000000..c3a18b182e3 Binary files /dev/null and b/images/pipelines/jobs-attributes.png differ diff --git a/images/pipelines/jobs-overview.png b/images/pipelines/jobs-overview.png new file mode 100644 index 00000000000..57e01adacbd Binary files /dev/null and b/images/pipelines/jobs-overview.png differ diff --git a/images/pipelines/jobs-tasks.png b/images/pipelines/jobs-tasks.png new file mode 100644 index 00000000000..0757584d836 Binary files /dev/null and b/images/pipelines/jobs-tasks.png differ diff --git a/images/pipelines/pipeline-target.png b/images/pipelines/pipeline-target.png new file mode 100644 index 00000000000..677575fa9c1 Binary files /dev/null and b/images/pipelines/pipeline-target.png differ diff --git a/images/pipelines/pipelines-overview.png b/images/pipelines/pipelines-overview.png new file mode 100644 index 00000000000..a52688aa46a Binary files /dev/null and b/images/pipelines/pipelines-overview.png differ diff --git a/images/planner/create-task-1.png b/images/planner/create-task-1.png new file mode 100644 index 00000000000..6a52aa7843a Binary files /dev/null and b/images/planner/create-task-1.png differ diff --git a/images/planner/planner-create-task.png b/images/planner/planner-create-task.png new file mode 100644 index 00000000000..a01d7afb77b Binary files /dev/null and b/images/planner/planner-create-task.png differ diff --git a/images/planner/planner-icon.png b/images/planner/planner-icon.png new file mode 100644 index 00000000000..ddef6f06acc Binary files /dev/null and b/images/planner/planner-icon.png differ diff --git a/images/planner/planner-overview.png b/images/planner/planner-overview.png new file mode 100644 index 00000000000..8f67b4772ad Binary files /dev/null and b/images/planner/planner-overview.png differ diff --git a/images/platform/redhat.jpeg b/images/platform/redhat.jpeg new file mode 100644 index 00000000000..2dc7ad4c553 Binary files /dev/null and b/images/platform/redhat.jpeg differ diff --git a/images/platform/supported.png b/images/platform/supported.png new file mode 100644 index 00000000000..4d5e34fe15d Binary files /dev/null and b/images/platform/supported.png differ diff --git a/images/plugins.jpeg b/images/plugins.jpeg new file mode 100644 index 00000000000..1d84b32990c Binary files /dev/null and b/images/plugins.jpeg differ diff --git a/images/plugins/Plugins.png b/images/plugins/Plugins.png new file mode 100644 index 00000000000..d4be14d4ba2 Binary files /dev/null and b/images/plugins/Plugins.png differ diff --git a/images/plugins/beef/plugin.png b/images/plugins/beef/plugin.png new file mode 100644 index 00000000000..8950270ee78 Binary files /dev/null and b/images/plugins/beef/plugin.png differ diff --git a/images/plugins/beef/starting.png b/images/plugins/beef/starting.png new file mode 100644 index 00000000000..7ee2713a498 Binary files /dev/null and b/images/plugins/beef/starting.png differ diff --git a/images/plugins/burp/add_extension.png b/images/plugins/burp/add_extension.png new file mode 100644 index 00000000000..5afbe4f918b Binary files /dev/null and b/images/plugins/burp/add_extension.png differ diff --git a/images/plugins/burp/configuration.png b/images/plugins/burp/configuration.png new file mode 100644 index 00000000000..22518d40939 Binary files /dev/null and b/images/plugins/burp/configuration.png differ diff --git a/images/plugins/burp/configuration_connected.png b/images/plugins/burp/configuration_connected.png new file mode 100644 index 00000000000..7730198cc77 Binary files /dev/null and b/images/plugins/burp/configuration_connected.png differ diff --git a/images/plugins/burp/configuration_logged_in.png b/images/plugins/burp/configuration_logged_in.png new file mode 100644 index 00000000000..254c8d4c9b9 Binary files /dev/null and b/images/plugins/burp/configuration_logged_in.png differ diff --git a/images/plugins/burp/configuration_login.png b/images/plugins/burp/configuration_login.png new file mode 100644 index 00000000000..a27c31b5954 Binary files /dev/null and b/images/plugins/burp/configuration_login.png differ diff --git a/images/plugins/burp/configuration_login_success.png b/images/plugins/burp/configuration_login_success.png new file mode 100644 index 00000000000..2a0b7132329 Binary files /dev/null and b/images/plugins/burp/configuration_login_success.png differ diff --git a/images/plugins/burp/extension_settings.png b/images/plugins/burp/extension_settings.png new file mode 100644 index 00000000000..1f3abc93a98 Binary files /dev/null and b/images/plugins/burp/extension_settings.png differ diff --git a/images/plugins/burp/loaded.png b/images/plugins/burp/loaded.png new file mode 100644 index 00000000000..048724d9f25 Binary files /dev/null and b/images/plugins/burp/loaded.png differ diff --git a/images/plugins/burp/other_settings.png b/images/plugins/burp/other_settings.png new file mode 100644 index 00000000000..3bbdf006f8a Binary files /dev/null and b/images/plugins/burp/other_settings.png differ diff --git a/images/plugins/burp/ruby_path.png b/images/plugins/burp/ruby_path.png new file mode 100644 index 00000000000..5b98c83ce79 Binary files /dev/null and b/images/plugins/burp/ruby_path.png differ diff --git a/images/plugins/burp/send_to.png b/images/plugins/burp/send_to.png new file mode 100644 index 00000000000..6c97295a7f2 Binary files /dev/null and b/images/plugins/burp/send_to.png differ diff --git a/images/plugins/burp/store.png b/images/plugins/burp/store.png new file mode 100644 index 00000000000..af4fd0bf7f4 Binary files /dev/null and b/images/plugins/burp/store.png differ diff --git a/images/plugins/metasploit/Metasploit-Plugin.png b/images/plugins/metasploit/Metasploit-Plugin.png new file mode 100644 index 00000000000..a6e03b5113e Binary files /dev/null and b/images/plugins/metasploit/Metasploit-Plugin.png differ diff --git a/images/plugins/nessus/plugin1.png b/images/plugins/nessus/plugin1.png new file mode 100644 index 00000000000..55ed1ab3ff8 Binary files /dev/null and b/images/plugins/nessus/plugin1.png differ diff --git a/images/plugins/nessus/plugin2.png b/images/plugins/nessus/plugin2.png new file mode 100644 index 00000000000..8b20266148b Binary files /dev/null and b/images/plugins/nessus/plugin2.png differ diff --git a/images/plugins/zap/auth-panel.png b/images/plugins/zap/auth-panel.png new file mode 100644 index 00000000000..3eb13a44a91 Binary files /dev/null and b/images/plugins/zap/auth-panel.png differ diff --git a/images/plugins/zap/config-panel.png b/images/plugins/zap/config-panel.png new file mode 100644 index 00000000000..ed826a0fc72 Binary files /dev/null and b/images/plugins/zap/config-panel.png differ diff --git a/images/plugins/zap/faraday-conf-menu-item.png b/images/plugins/zap/faraday-conf-menu-item.png new file mode 100644 index 00000000000..7f28808ae72 Binary files /dev/null and b/images/plugins/zap/faraday-conf-menu-item.png differ diff --git a/images/plugins/zap/load-add-on.png b/images/plugins/zap/load-add-on.png new file mode 100644 index 00000000000..d75f5d630eb Binary files /dev/null and b/images/plugins/zap/load-add-on.png differ diff --git a/images/plugins/zap/restore-configuration.png b/images/plugins/zap/restore-configuration.png new file mode 100644 index 00000000000..63d344997a1 Binary files /dev/null and b/images/plugins/zap/restore-configuration.png differ diff --git a/images/plugins/zap/send-alert.png b/images/plugins/zap/send-alert.png new file mode 100644 index 00000000000..b35e026e224 Binary files /dev/null and b/images/plugins/zap/send-alert.png differ diff --git a/images/plugins/zap/send-request.png b/images/plugins/zap/send-request.png new file mode 100644 index 00000000000..391ccf5b567 Binary files /dev/null and b/images/plugins/zap/send-request.png differ diff --git a/images/plugins/zap/uninstall-plugin.png b/images/plugins/zap/uninstall-plugin.png new file mode 100644 index 00000000000..9a175021cc9 Binary files /dev/null and b/images/plugins/zap/uninstall-plugin.png differ diff --git a/images/scheduling/scheduling_1.png b/images/scheduling/scheduling_1.png new file mode 100644 index 00000000000..8082c84c930 Binary files /dev/null and b/images/scheduling/scheduling_1.png differ diff --git a/images/scheduling/scheduling_2.png b/images/scheduling/scheduling_2.png new file mode 100644 index 00000000000..d7e22eeb1f4 Binary files /dev/null and b/images/scheduling/scheduling_2.png differ diff --git a/images/searcher/searcher_structure.png b/images/searcher/searcher_structure.png new file mode 100644 index 00000000000..3bb6d92d04b Binary files /dev/null and b/images/searcher/searcher_structure.png differ diff --git a/images/searcher/severity_report.png b/images/searcher/severity_report.png new file mode 100644 index 00000000000..33a71a9109f Binary files /dev/null and b/images/searcher/severity_report.png differ diff --git a/images/searcher/severity_report_changed.png b/images/searcher/severity_report_changed.png new file mode 100644 index 00000000000..05992cee9af Binary files /dev/null and b/images/searcher/severity_report_changed.png differ diff --git a/images/searcher/status_report_low.png b/images/searcher/status_report_low.png new file mode 100644 index 00000000000..0b00cdd170a Binary files /dev/null and b/images/searcher/status_report_low.png differ diff --git a/images/servicenow/button.png b/images/servicenow/button.png new file mode 100644 index 00000000000..93010d33384 Binary files /dev/null and b/images/servicenow/button.png differ diff --git a/images/servicenow/dialog_default_data.png b/images/servicenow/dialog_default_data.png new file mode 100644 index 00000000000..4e347f63760 Binary files /dev/null and b/images/servicenow/dialog_default_data.png differ diff --git a/images/servicenow/dialog_overwrited_data.png b/images/servicenow/dialog_overwrited_data.png new file mode 100644 index 00000000000..d41d512f888 Binary files /dev/null and b/images/servicenow/dialog_overwrited_data.png differ diff --git a/images/servicenow/issuetracker.png b/images/servicenow/issuetracker.png new file mode 100644 index 00000000000..1cbcc78ff1f Binary files /dev/null and b/images/servicenow/issuetracker.png differ diff --git a/images/settings/custom_field_creating.png b/images/settings/custom_field_creating.png new file mode 100644 index 00000000000..1fe8710c024 Binary files /dev/null and b/images/settings/custom_field_creating.png differ diff --git a/images/settings/custom_field_list.png b/images/settings/custom_field_list.png new file mode 100644 index 00000000000..8fbfbdba2a8 Binary files /dev/null and b/images/settings/custom_field_list.png differ diff --git a/images/settings/custom_field_new-v4.png b/images/settings/custom_field_new-v4.png new file mode 100644 index 00000000000..9e826afe6b2 Binary files /dev/null and b/images/settings/custom_field_new-v4.png differ diff --git a/images/settings/custom_field_new.png b/images/settings/custom_field_new.png new file mode 100644 index 00000000000..abcf51bdd3d Binary files /dev/null and b/images/settings/custom_field_new.png differ diff --git a/images/settings/preferences_menu-v4.png b/images/settings/preferences_menu-v4.png new file mode 100644 index 00000000000..4f24caa9b17 Binary files /dev/null and b/images/settings/preferences_menu-v4.png differ diff --git a/images/settings/preferences_small_menu-v4.png b/images/settings/preferences_small_menu-v4.png new file mode 100644 index 00000000000..97cef31d346 Binary files /dev/null and b/images/settings/preferences_small_menu-v4.png differ diff --git a/images/settings/report_tab-v4.png b/images/settings/report_tab-v4.png new file mode 100644 index 00000000000..c63e223cc6b Binary files /dev/null and b/images/settings/report_tab-v4.png differ diff --git a/images/settings/settings-servicenow.png b/images/settings/settings-servicenow.png new file mode 100644 index 00000000000..495176f7a48 Binary files /dev/null and b/images/settings/settings-servicenow.png differ diff --git a/images/settings/settings_in_menu-v4.png b/images/settings/settings_in_menu-v4.png new file mode 100644 index 00000000000..f8cd88e43a3 Binary files /dev/null and b/images/settings/settings_in_menu-v4.png differ diff --git a/images/settings/settings_in_menu.png b/images/settings/settings_in_menu.png new file mode 100644 index 00000000000..b10302a0f7b Binary files /dev/null and b/images/settings/settings_in_menu.png differ diff --git a/images/settings/settings_overview.png b/images/settings/settings_overview.png new file mode 100644 index 00000000000..0b14114707b Binary files /dev/null and b/images/settings/settings_overview.png differ diff --git a/images/settings/ticketing_tools-new-3.19-v3.png b/images/settings/ticketing_tools-new-3.19-v3.png new file mode 100644 index 00000000000..603c6f80736 Binary files /dev/null and b/images/settings/ticketing_tools-new-3.19-v3.png differ diff --git a/images/settings/ticketing_tools_JIRA.png b/images/settings/ticketing_tools_JIRA.png new file mode 100644 index 00000000000..cfbc51604f7 Binary files /dev/null and b/images/settings/ticketing_tools_JIRA.png differ diff --git a/images/settings/ticketing_tools_ServiceNow.png b/images/settings/ticketing_tools_ServiceNow.png new file mode 100644 index 00000000000..943fcc60dc8 Binary files /dev/null and b/images/settings/ticketing_tools_ServiceNow.png differ diff --git a/images/settings/tkt_tool-v4.png b/images/settings/tkt_tool-v4.png new file mode 100644 index 00000000000..1ecdf59f19a Binary files /dev/null and b/images/settings/tkt_tool-v4.png differ diff --git a/images/status_report/Unconfirmed.gif b/images/status_report/Unconfirmed.gif new file mode 100644 index 00000000000..399703052f7 Binary files /dev/null and b/images/status_report/Unconfirmed.gif differ diff --git a/images/status_report/add_tags.png b/images/status_report/add_tags.png new file mode 100644 index 00000000000..8e3365e2833 Binary files /dev/null and b/images/status_report/add_tags.png differ diff --git a/images/status_report/columns-v4.png b/images/status_report/columns-v4.png new file mode 100644 index 00000000000..c6b83be2eec Binary files /dev/null and b/images/status_report/columns-v4.png differ diff --git a/images/status_report/columns.png b/images/status_report/columns.png new file mode 100644 index 00000000000..822a6898ec6 Binary files /dev/null and b/images/status_report/columns.png differ diff --git a/images/status_report/confirmed_vulns-v4.png b/images/status_report/confirmed_vulns-v4.png new file mode 100644 index 00000000000..da5340960a6 Binary files /dev/null and b/images/status_report/confirmed_vulns-v4.png differ diff --git a/images/status_report/confirmed_vulns.png b/images/status_report/confirmed_vulns.png new file mode 100644 index 00000000000..4996cb8c928 Binary files /dev/null and b/images/status_report/confirmed_vulns.png differ diff --git a/images/status_report/create_tag-v4.png b/images/status_report/create_tag-v4.png new file mode 100644 index 00000000000..f091a62d91e Binary files /dev/null and b/images/status_report/create_tag-v4.png differ diff --git a/images/status_report/csv_export.png b/images/status_report/csv_export.png new file mode 100644 index 00000000000..9a3af6e37ce Binary files /dev/null and b/images/status_report/csv_export.png differ diff --git a/images/status_report/csv_file.png b/images/status_report/csv_file.png new file mode 100644 index 00000000000..74f836e158f Binary files /dev/null and b/images/status_report/csv_file.png differ diff --git a/images/status_report/csv_filtering.png b/images/status_report/csv_filtering.png new file mode 100644 index 00000000000..44882739281 Binary files /dev/null and b/images/status_report/csv_filtering.png differ diff --git a/images/status_report/delete_vuln-v4.png b/images/status_report/delete_vuln-v4.png new file mode 100644 index 00000000000..6850cbcbaaa Binary files /dev/null and b/images/status_report/delete_vuln-v4.png differ diff --git a/images/status_report/delete_vulns.png b/images/status_report/delete_vulns.png new file mode 100644 index 00000000000..bfa3b8398d8 Binary files /dev/null and b/images/status_report/delete_vulns.png differ diff --git a/images/status_report/download_button.png b/images/status_report/download_button.png new file mode 100644 index 00000000000..46914fb8c76 Binary files /dev/null and b/images/status_report/download_button.png differ diff --git a/images/status_report/edit_button.png b/images/status_report/edit_button.png new file mode 100644 index 00000000000..9adcddfa5a7 Binary files /dev/null and b/images/status_report/edit_button.png differ diff --git a/images/status_report/edit_button_enable.png b/images/status_report/edit_button_enable.png new file mode 100644 index 00000000000..c23dfd7eab1 Binary files /dev/null and b/images/status_report/edit_button_enable.png differ diff --git a/images/status_report/edit_column_button.png b/images/status_report/edit_column_button.png new file mode 100644 index 00000000000..9c2f6c3642c Binary files /dev/null and b/images/status_report/edit_column_button.png differ diff --git a/images/status_report/edit_multiple_vulns.png b/images/status_report/edit_multiple_vulns.png new file mode 100644 index 00000000000..be2b2916cdd Binary files /dev/null and b/images/status_report/edit_multiple_vulns.png differ diff --git a/images/status_report/edit_vuln-v4.png b/images/status_report/edit_vuln-v4.png new file mode 100644 index 00000000000..a1ce2eb69c4 Binary files /dev/null and b/images/status_report/edit_vuln-v4.png differ diff --git a/images/status_report/edit_vuln.png b/images/status_report/edit_vuln.png new file mode 100644 index 00000000000..a4bf7ad0da6 Binary files /dev/null and b/images/status_report/edit_vuln.png differ diff --git a/images/status_report/filter_by_field.png b/images/status_report/filter_by_field.png new file mode 100644 index 00000000000..711d34012b3 Binary files /dev/null and b/images/status_report/filter_by_field.png differ diff --git a/images/status_report/filters_button.png b/images/status_report/filters_button.png new file mode 100644 index 00000000000..a38d5d5be5d Binary files /dev/null and b/images/status_report/filters_button.png differ diff --git a/images/status_report/filters_dialog.png b/images/status_report/filters_dialog.png new file mode 100644 index 00000000000..c176444f156 Binary files /dev/null and b/images/status_report/filters_dialog.png differ diff --git a/images/status_report/icon.png b/images/status_report/icon.png new file mode 100644 index 00000000000..6454c7ee370 Binary files /dev/null and b/images/status_report/icon.png differ diff --git a/images/status_report/import_report.gif b/images/status_report/import_report.gif new file mode 100644 index 00000000000..a0974c3aebf Binary files /dev/null and b/images/status_report/import_report.gif differ diff --git a/images/status_report/multiple-search.gif b/images/status_report/multiple-search.gif new file mode 100644 index 00000000000..55264a64442 Binary files /dev/null and b/images/status_report/multiple-search.gif differ diff --git a/images/status_report/multiple_context_menu.png b/images/status_report/multiple_context_menu.png new file mode 100644 index 00000000000..524d0dee161 Binary files /dev/null and b/images/status_report/multiple_context_menu.png differ diff --git a/images/status_report/new_vuln-v4.png b/images/status_report/new_vuln-v4.png new file mode 100644 index 00000000000..d1d3def8d62 Binary files /dev/null and b/images/status_report/new_vuln-v4.png differ diff --git a/images/status_report/new_vuln.png b/images/status_report/new_vuln.png new file mode 100644 index 00000000000..857d2b05052 Binary files /dev/null and b/images/status_report/new_vuln.png differ diff --git a/images/status_report/new_vuln_general.png b/images/status_report/new_vuln_general.png new file mode 100644 index 00000000000..4b2742c2b48 Binary files /dev/null and b/images/status_report/new_vuln_general.png differ diff --git a/images/status_report/search-v4.png b/images/status_report/search-v4.png new file mode 100644 index 00000000000..4ddd2acffd7 Binary files /dev/null and b/images/status_report/search-v4.png differ diff --git a/images/status_report/search.png b/images/status_report/search.png new file mode 100644 index 00000000000..e3f59f58fef Binary files /dev/null and b/images/status_report/search.png differ diff --git a/images/status_report/search_by_many_fields.png b/images/status_report/search_by_many_fields.png new file mode 100644 index 00000000000..5db9774a5c5 Binary files /dev/null and b/images/status_report/search_by_many_fields.png differ diff --git a/images/status_report/search_many-v4.png b/images/status_report/search_many-v4.png new file mode 100644 index 00000000000..29b1ecd6d5a Binary files /dev/null and b/images/status_report/search_many-v4.png differ diff --git a/images/status_report/search_many.png b/images/status_report/search_many.png new file mode 100644 index 00000000000..2123eed2ee7 Binary files /dev/null and b/images/status_report/search_many.png differ diff --git a/images/status_report/search_or_many.png b/images/status_report/search_or_many.png new file mode 100644 index 00000000000..06eee1a0293 Binary files /dev/null and b/images/status_report/search_or_many.png differ diff --git a/images/status_report/search_tags-v4.png b/images/status_report/search_tags-v4.png new file mode 100644 index 00000000000..6d0e929c565 Binary files /dev/null and b/images/status_report/search_tags-v4.png differ diff --git a/images/status_report/search_tags.png b/images/status_report/search_tags.png new file mode 100644 index 00000000000..8b065c37bc5 Binary files /dev/null and b/images/status_report/search_tags.png differ diff --git a/images/status_report/select_report.png b/images/status_report/select_report.png new file mode 100644 index 00000000000..85086aeb6df Binary files /dev/null and b/images/status_report/select_report.png differ diff --git a/images/status_report/select_tag-v4.png b/images/status_report/select_tag-v4.png new file mode 100644 index 00000000000..34ff66eac3f Binary files /dev/null and b/images/status_report/select_tag-v4.png differ diff --git a/images/status_report/single_context_menu.png b/images/status_report/single_context_menu.png new file mode 100644 index 00000000000..da7b986cbdc Binary files /dev/null and b/images/status_report/single_context_menu.png differ diff --git a/images/status_report/status_closed.png b/images/status_report/status_closed.png new file mode 100644 index 00000000000..1bc49302ff6 Binary files /dev/null and b/images/status_report/status_closed.png differ diff --git a/images/status_report/status_re-opened.png b/images/status_report/status_re-opened.png new file mode 100644 index 00000000000..916ad5ceff0 Binary files /dev/null and b/images/status_report/status_re-opened.png differ diff --git a/images/status_report/status_report-v4.png b/images/status_report/status_report-v4.png new file mode 100644 index 00000000000..48c7e9a9593 Binary files /dev/null and b/images/status_report/status_report-v4.png differ diff --git a/images/status_report/status_report.png b/images/status_report/status_report.png new file mode 100644 index 00000000000..0f89f1215fb Binary files /dev/null and b/images/status_report/status_report.png differ diff --git a/images/status_report/status_report_menu_new_style.png b/images/status_report/status_report_menu_new_style.png new file mode 100644 index 00000000000..88bb047b6df Binary files /dev/null and b/images/status_report/status_report_menu_new_style.png differ diff --git a/images/status_report/tags_icon.png b/images/status_report/tags_icon.png new file mode 100644 index 00000000000..576d6e45924 Binary files /dev/null and b/images/status_report/tags_icon.png differ diff --git a/images/status_report/upload_options-v4.png b/images/status_report/upload_options-v4.png new file mode 100644 index 00000000000..7fc199fcb90 Binary files /dev/null and b/images/status_report/upload_options-v4.png differ diff --git a/images/status_report/upload_report.png b/images/status_report/upload_report.png new file mode 100644 index 00000000000..232ae005580 Binary files /dev/null and b/images/status_report/upload_report.png differ diff --git a/images/status_report/upload_report_GTK.gif b/images/status_report/upload_report_GTK.gif new file mode 100644 index 00000000000..a0974c3aebf Binary files /dev/null and b/images/status_report/upload_report_GTK.gif differ diff --git a/images/status_report/upload_report_buttom.png b/images/status_report/upload_report_buttom.png new file mode 100644 index 00000000000..2d67a637117 Binary files /dev/null and b/images/status_report/upload_report_buttom.png differ diff --git a/images/status_report/vuln_creation_templates_list.png b/images/status_report/vuln_creation_templates_list.png new file mode 100644 index 00000000000..bfb7a39496e Binary files /dev/null and b/images/status_report/vuln_creation_templates_list.png differ diff --git a/images/status_report/vuln_preview-v4.png b/images/status_report/vuln_preview-v4.png new file mode 100644 index 00000000000..1b53e3975d1 Binary files /dev/null and b/images/status_report/vuln_preview-v4.png differ diff --git a/images/status_report/vuln_preview.png b/images/status_report/vuln_preview.png new file mode 100644 index 00000000000..ac0d2d31c2a Binary files /dev/null and b/images/status_report/vuln_preview.png differ diff --git a/images/status_report/vuln_tagged.png b/images/status_report/vuln_tagged.png new file mode 100644 index 00000000000..5ad8b324d9b Binary files /dev/null and b/images/status_report/vuln_tagged.png differ diff --git a/images/status_report/vulns_button.png b/images/status_report/vulns_button.png new file mode 100644 index 00000000000..804cd3d2203 Binary files /dev/null and b/images/status_report/vulns_button.png differ diff --git a/images/status_report/vulns_group_by.png b/images/status_report/vulns_group_by.png new file mode 100644 index 00000000000..341b396f638 Binary files /dev/null and b/images/status_report/vulns_group_by.png differ diff --git a/images/status_report/vulns_list.png b/images/status_report/vulns_list.png new file mode 100644 index 00000000000..d4dfa5efce9 Binary files /dev/null and b/images/status_report/vulns_list.png differ diff --git a/images/status_report/vulns_selected-v4.png b/images/status_report/vulns_selected-v4.png new file mode 100644 index 00000000000..65bf54b655b Binary files /dev/null and b/images/status_report/vulns_selected-v4.png differ diff --git a/images/status_report/vulns_selected.png b/images/status_report/vulns_selected.png new file mode 100644 index 00000000000..a29ee8a23cf Binary files /dev/null and b/images/status_report/vulns_selected.png differ diff --git a/images/status_report/vulns_tagged-v4.png b/images/status_report/vulns_tagged-v4.png new file mode 100644 index 00000000000..53a3d990342 Binary files /dev/null and b/images/status_report/vulns_tagged-v4.png differ diff --git a/images/tasks/edit_task.png b/images/tasks/edit_task.png new file mode 100644 index 00000000000..7c27287722a Binary files /dev/null and b/images/tasks/edit_task.png differ diff --git a/images/tasks/kanban_methodologies.png b/images/tasks/kanban_methodologies.png new file mode 100644 index 00000000000..eff9fd12628 Binary files /dev/null and b/images/tasks/kanban_methodologies.png differ diff --git a/images/tasks/methodologies_list.png b/images/tasks/methodologies_list.png new file mode 100644 index 00000000000..6543d6d80a7 Binary files /dev/null and b/images/tasks/methodologies_list.png differ diff --git a/images/tasks/new_methodology.png b/images/tasks/new_methodology.png new file mode 100644 index 00000000000..3f9d759ec42 Binary files /dev/null and b/images/tasks/new_methodology.png differ diff --git a/images/tasks/sidebar_icon.png b/images/tasks/sidebar_icon.png new file mode 100644 index 00000000000..7fe7f411d23 Binary files /dev/null and b/images/tasks/sidebar_icon.png differ diff --git a/images/users/delete.png b/images/users/delete.png new file mode 100644 index 00000000000..3a207e6f72b Binary files /dev/null and b/images/users/delete.png differ diff --git a/images/users/edit.png b/images/users/edit.png new file mode 100644 index 00000000000..f3e238d3dcb Binary files /dev/null and b/images/users/edit.png differ diff --git a/images/users/icon.png b/images/users/icon.png new file mode 100644 index 00000000000..f43c25e27b1 Binary files /dev/null and b/images/users/icon.png differ diff --git a/images/users/list.png b/images/users/list.png new file mode 100644 index 00000000000..562e6f66819 Binary files /dev/null and b/images/users/list.png differ diff --git a/images/users/login.png b/images/users/login.png new file mode 100644 index 00000000000..a23619ff41a Binary files /dev/null and b/images/users/login.png differ diff --git a/images/users/logout.png b/images/users/logout.png new file mode 100644 index 00000000000..543e139ebaf Binary files /dev/null and b/images/users/logout.png differ diff --git a/images/users/menu.png b/images/users/menu.png new file mode 100644 index 00000000000..514c8fe53db Binary files /dev/null and b/images/users/menu.png differ diff --git a/images/users/new.png b/images/users/new.png new file mode 100644 index 00000000000..aa849846089 Binary files /dev/null and b/images/users/new.png differ diff --git a/images/users/user.xml.png b/images/users/user.xml.png new file mode 100644 index 00000000000..bf63e15f98a Binary files /dev/null and b/images/users/user.xml.png differ diff --git a/images/users/users.gif b/images/users/users.gif new file mode 100644 index 00000000000..df7f4868b87 Binary files /dev/null and b/images/users/users.gif differ diff --git a/images/vulnerability_database/create.png b/images/vulnerability_database/create.png new file mode 100644 index 00000000000..87dd7831337 Binary files /dev/null and b/images/vulnerability_database/create.png differ diff --git a/images/vulnerability_database/icon.png b/images/vulnerability_database/icon.png new file mode 100644 index 00000000000..6d6c2947d2b Binary files /dev/null and b/images/vulnerability_database/icon.png differ diff --git a/images/vulnerability_database/import.png b/images/vulnerability_database/import.png new file mode 100644 index 00000000000..ff18229e343 Binary files /dev/null and b/images/vulnerability_database/import.png differ diff --git a/images/vulnerability_database/import_icon.png b/images/vulnerability_database/import_icon.png new file mode 100644 index 00000000000..10b4571f242 Binary files /dev/null and b/images/vulnerability_database/import_icon.png differ diff --git a/images/vulnerability_database/list.png b/images/vulnerability_database/list.png new file mode 100644 index 00000000000..bbd089796f5 Binary files /dev/null and b/images/vulnerability_database/list.png differ diff --git a/images/vulnerability_database/vuln_creation_templates_list.png b/images/vulnerability_database/vuln_creation_templates_list.png new file mode 100644 index 00000000000..bfb7a39496e Binary files /dev/null and b/images/vulnerability_database/vuln_creation_templates_list.png differ diff --git a/images/workspace-comparison/graph1.png b/images/workspace-comparison/graph1.png new file mode 100644 index 00000000000..ccd00de28a7 Binary files /dev/null and b/images/workspace-comparison/graph1.png differ diff --git a/images/workspace-comparison/graph2.png b/images/workspace-comparison/graph2.png new file mode 100644 index 00000000000..528433429d6 Binary files /dev/null and b/images/workspace-comparison/graph2.png differ diff --git a/images/workspace-comparison/graph3.png b/images/workspace-comparison/graph3.png new file mode 100644 index 00000000000..0db9eb963ec Binary files /dev/null and b/images/workspace-comparison/graph3.png differ diff --git a/images/workspace-comparison/graph4.png b/images/workspace-comparison/graph4.png new file mode 100644 index 00000000000..47affbd4096 Binary files /dev/null and b/images/workspace-comparison/graph4.png differ diff --git a/images/workspaces/3.CreateWorkspace2-v4.png b/images/workspaces/3.CreateWorkspace2-v4.png new file mode 100644 index 00000000000..1c879a0e331 Binary files /dev/null and b/images/workspaces/3.CreateWorkspace2-v4.png differ diff --git a/images/workspaces/6.ReadOnlyWork2-v4.png b/images/workspaces/6.ReadOnlyWork2-v4.png new file mode 100644 index 00000000000..682e32ae6fc Binary files /dev/null and b/images/workspaces/6.ReadOnlyWork2-v4.png differ diff --git a/images/workspaces/activation-v4.png b/images/workspaces/activation-v4.png new file mode 100644 index 00000000000..475252e010c Binary files /dev/null and b/images/workspaces/activation-v4.png differ diff --git a/images/workspaces/activation.png b/images/workspaces/activation.png new file mode 100644 index 00000000000..6de74409c8a Binary files /dev/null and b/images/workspaces/activation.png differ diff --git a/images/workspaces/archived.png b/images/workspaces/archived.png new file mode 100644 index 00000000000..885e328ea01 Binary files /dev/null and b/images/workspaces/archived.png differ diff --git a/images/workspaces/delete-v4-2.png b/images/workspaces/delete-v4-2.png new file mode 100644 index 00000000000..16075f89edc Binary files /dev/null and b/images/workspaces/delete-v4-2.png differ diff --git a/images/workspaces/delete-v4.png b/images/workspaces/delete-v4.png new file mode 100644 index 00000000000..49174f60d87 Binary files /dev/null and b/images/workspaces/delete-v4.png differ diff --git a/images/workspaces/delete.png b/images/workspaces/delete.png new file mode 100644 index 00000000000..c4ec2097f88 Binary files /dev/null and b/images/workspaces/delete.png differ diff --git a/images/workspaces/edit-v4.png b/images/workspaces/edit-v4.png new file mode 100644 index 00000000000..5dc544657f1 Binary files /dev/null and b/images/workspaces/edit-v4.png differ diff --git a/images/workspaces/edit.png b/images/workspaces/edit.png new file mode 100644 index 00000000000..e97ed8dc979 Binary files /dev/null and b/images/workspaces/edit.png differ diff --git a/images/workspaces/inactiveWS-v4-2.png b/images/workspaces/inactiveWS-v4-2.png new file mode 100644 index 00000000000..ffbb3fe6f0b Binary files /dev/null and b/images/workspaces/inactiveWS-v4-2.png differ diff --git a/images/workspaces/inactiveWS-v4.png b/images/workspaces/inactiveWS-v4.png new file mode 100644 index 00000000000..350028fff6e Binary files /dev/null and b/images/workspaces/inactiveWS-v4.png differ diff --git a/images/workspaces/list-v4.png b/images/workspaces/list-v4.png new file mode 100644 index 00000000000..1751e9eec84 Binary files /dev/null and b/images/workspaces/list-v4.png differ diff --git a/images/workspaces/list.png b/images/workspaces/list.png new file mode 100644 index 00000000000..d606c26ff4e Binary files /dev/null and b/images/workspaces/list.png differ diff --git a/images/workspaces/menu-v4.png b/images/workspaces/menu-v4.png new file mode 100644 index 00000000000..ba314706a6d Binary files /dev/null and b/images/workspaces/menu-v4.png differ diff --git a/images/workspaces/menu.png b/images/workspaces/menu.png new file mode 100644 index 00000000000..331614040cf Binary files /dev/null and b/images/workspaces/menu.png differ diff --git a/images/workspaces/new-v4.png b/images/workspaces/new-v4.png new file mode 100644 index 00000000000..46672474a1e Binary files /dev/null and b/images/workspaces/new-v4.png differ diff --git a/images/workspaces/new.png b/images/workspaces/new.png new file mode 100644 index 00000000000..4d69dc5ceff Binary files /dev/null and b/images/workspaces/new.png differ diff --git a/images/workspaces/workspace_menu.png b/images/workspaces/workspace_menu.png new file mode 100644 index 00000000000..3d6575796dc Binary files /dev/null and b/images/workspaces/workspace_menu.png differ diff --git a/import/index.html b/import/index.html new file mode 100644 index 00000000000..385d781d510 --- /dev/null +++ b/import/index.html @@ -0,0 +1,1672 @@ + + + + + + + + + + + + + + +Importing - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+

Importing

+

There are many ways to add vulnerabilities into Faraday, create them manually, import scan reports, with supported tools, Faraday Agents or using Faraday API.

+

Import your tool Reports

+

You can upload a scan report of your favorite tool to Faraday and have a nice look at your findings through the Vulns View. You can see a list of the tools that Faraday supports by clicking on this link

+

+

In order to upload a report to Faraday, follow these instructions:

+
    +
  • Click on the button + Add Vulnerability.
  • +
  • Click on the button Import from file and a prompt will be displayed.
  • +
  • Click on Browse in order to select the report that you are going to upload, or just drag and drop the file into the box.
  • +
  • Once you have selected the report, click on Upload and your file will be uploaded.
  • +
  • Refresh the view with the top bar refresh icon.
  • +
+

Supported File formats

+

There is a variety of tools and they all have multiple export formats, to make it more simple we list the tool in order + the filetype

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameIDCommandReport
Acunetix XML Output PluginAcunetixNoYes
Acunetix360 Output PluginAcunetix360NoYes
Acunetix JSON Output PluginAcunetix_JsonNoYes
Amap Output PluginAmapYesNo
Appscan XML PluginAppscanNoYes
Appscan CSV Output PluginAppscan_CSVNoYes
AppSpider XML Output PluginAppSpiderNoYes
Arachni XML Output PluginArachniYesYes
arp-scan network scannerarp-scanYesNo
Bandit XML Output PluginBanditNoYes
BeEF Online Service PluginBeefYesNo
brutexssbrutexssYesNo
Burp XML Output PluginBurpNoYes
Checkmarx XML Output PluginCheckmarxNoYes
CIS XML Output PluginCISNoYes
Cobalt CSV Output PluginCobaltNoYes
Crowdstrike JSON Output PluginCrowdstrike_JsonNoYes
DiGdigYesNo
DirbdirbYesNo
dirsearchdirsearchYesNo
Dnsenum XML Output PluginDnsenumYesNo
Dnsmap Output PluginDnsmapYesNo
Dnsrecon XML Output PluginDnsreconYesNo
Dnswalk XML Output PluginDnswalkYesNo
Faraday CSV Pluginfaraday_csvNoYes
Fierce Output PluginFierceYesNo
Fortify XML Output PluginFortifyNoYes
FtpftpYesNo
Goohost XML Output PluginGoohostYesNo
Grype JSON PlugingrypeYesYes
hping3Hping3YesNo
Hydra XML Output PluginHydraYesNo
Core Impact XML Output PluginCoreImpactNoYes
Invicti XML Output PluginInvictiNoYes
Ip360 CSV Output PluginIp360NoNo
Junit XML Output PluginJunitNoYes
Lynis DAT Output PluginLynisYesYes
Maltego MTGX & MTGL Output PluginMaltegoNoYes
Microsoft Baseline Security AnalyzerMBSANoYes
Medusa Output PluginMedusaYesNo
Metasploit XML Output PluginMetasploitNoYes
NaabunaabuYesYes
ncrack XML PluginncrackNoYes
ndiffNdiffYesNo
Nessus XML Output PluginNessusNoYes
Nessus Sc Output PluginNessus_scNoYes
netdiscoverNetdiscoverYesNo
Netsparker XML Output PluginNetsparkerNoYes
NetsparkerCloud XML Output PluginNetsparkerCloudNoYes
Nexpose XML 2.0 Report PluginNexposeFullNoYes
nextnetnextnetYesNo
Nikto XML Output PluginNiktoYesYes
Nipper XML Output PluginNipperNoYes
Nmap XML Output PluginNmapYesYes
NucleinucleiYesYes
Nucleinuclei_legacyYesYes
OpenScap XML Output PluginOpenScapNoYes
Openvas XML Output PluginOpenvasNoYes
pasteAnalyzer JSON Output PluginpasteAnalyzerYesNo
PeepingTompeepingtomYesNo
Pentera Json Output PluginPentera_JsonNoYes
PingpingYesNo
Ping Castle XML Output PluginPingCastleNoYes
Popeye JSON Output PluginPopeye_JsonNoYes
propecia port scannerpropeciaYesNo
ProwlerprowlerNoYes
Qualysguard XML Output PluginQualysguardNoYes
QualysWebapp XML Output PluginQualysWebappNoYes
rdpscanrdpscanYesNo
Reconng XML Output PluginReconngNoYes
Retina XML Output PluginRetinaNoYes
Reverseraider XML Output PluginReverseraiderYesNo
Sarif PluginSarifNoYes
Semgrep JsonSemgrep_JSONNoYes
ShodanshodanYesYes
Skipfish Output PluginSkipfishYesNo
SonarQube API PluginsonarqubeAPINoYes
SourceclearsourceclearNoYes
sshdefaultscansshdefaultscanYesNo
SSL LabsssllabsNoYes
Sslyze PluginSslyze_XMLNoYes
Sslyze JsonSslyze_JSONYesYes
Syhunt XML PluginSyhuntNoYes
TelnetTelnetYesNo
Terraform Plugin JSON Output PluginTerraformPluginJsonNoYes
Theharvester XML Output PluginTheharvesterYesNo
TracerouteTracerouteYesNo
Trivy JSON Output PluginTrivy_JsonNoYes
W3af XML Output PluginW3afYesYes
Wapiti XML Output PluginWapitiYesYes
Wcscan XML Output PluginWcscanYesNo
Webfuzzer Output PluginWebfuzzerYesNo
WebinspectWebinspectNoYes
Wfuzz PluginWfuzzYesNo
WhatWebPluginwhatwebNoYes
whitesourcewhitesourceNoYes
WhoiswhoisYesNo
Windows Defender JsonlWindowsDefender_JSONLNoYes
WPscanwpscanYesYes
Onapsis X1 XML Output PluginX1YesYes
xsssniperxsssniperYesNo
Zap XML Output PluginZapNoYes
Zap Json Output PluginZap_JsonNoYes
+ +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 00000000000..29b9405c153 --- /dev/null +++ b/index.html @@ -0,0 +1,1358 @@ + + + + + + + + + + + + + +Home - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Home

+

+

+
+

Rethink Vulnerability Management for your Network Security

+

Security faces two challenging objectives: developing intelligent methods for obtaining new information and effectively managing and enhancing remediation efforts. With the utilization of Faraday, you can prioritize vulnerability discovery while we assist you with the remaining tasks. Simply access Faraday through your terminal and effortlessly organize your work on the go.

+

Faraday was specifically designed to enable you to leverage the diverse range of tools within the security community, fostering a truly collaborative multiuser environment.

+

By consolidating and standardizing the data you input, Faraday empowers you to explore it through various visualizations that prove valuable to both managers and analysts.

+

Faraday is meticulously crafted to optimize the process of Vulnerability Management. It excels at normalizing, tracking, and identifying assets and vulnerability data from over 90 different security tools.

+

manage

+

dashboard

+

To read about the latest features check out the release notes!

+

Getting Started

+
+

Learn about Faraday holistic approach and rethink vulnerability management.

+ +

Integrating faraday in your CI/CD

+

Setup Bandit and OWASP ZAP in your pipeline

+ +

Setup Bandit, OWASP ZAP and SonarQube in your pipeline

+ +

Faraday Cli

+
+

Faraday-cli is our command line client, providing easy access to the console tools, work in faraday directly from the terminal!

+

This is a great way to automate scans, integrate it to CI/CD pipeline or just get metrics from a workspace

+
$ pip3 install faraday-cli
+
+

Check our faraday-cli repo

+

Check out the documentation here.

+

Example

+

Faraday Agents

+
+

Faraday Agents Dispatcher is a tool that gives Faraday the ability to run scanners or tools remotely from the platform and get the results.

+

Actionable reporting and Vulnerability templates

+

Every company has a different approach to reporting. Faraday provides a way for companies to export their data into their own compliance-ready formats.

+

Plugins

+
+

Connect you favorite tools through our plugins. Right now there are more than 80+ supported tools, among which you will find:

+

+

Missing your favorite one? Create a Pull Request!

+

There are two Plugin types:

+

Console plugins which interpret the output of the tools you execute.

+
$ faraday-cli tool run \"nmap www.exampledomain.com\"
+💻 Processing Nmap command
+Starting Nmap 7.80 ( https://nmap.org ) at 2021-02-22 14:13 -03
+Nmap scan report for www.exampledomain.com (10.196.205.130)
+Host is up (0.17s latency).
+rDNS record for 10.196.205.130: 10.196.205.130.bc.example.com
+Not shown: 996 filtered ports
+PORT     STATE  SERVICE
+80/tcp   open   http
+443/tcp  open   https
+2222/tcp open   EtherNetIP-1
+3306/tcp closed mysql
+Nmap done: 1 IP address (1 host up) scanned in 11.12 seconds
+⬆ Sending data to workspace: test
+✔ Done
+
+

Report plugins which allows you to import previously generated artifacts like XMLs, JSONs.

+
faraday-cli tool report burp.xml
+
+

Creating custom plugins is super easy, Read more about Plugins. +Vulnerability Templates

+

Quickly fill out the gaps in your vulnerability data with Templates from your personalized Knowledge Base.

+

Reduce and Prioritize

+

An interface built around collaboration and simplicity: manage, tag, prioritize with ease.

+

Faraday Client

+

Our Shell allows you to upload results while pentesting actively.

+

Custom Workflows and seamless Deduplication

+

Trigger any action with custom events built to avoid repetitive tasks. Import all your data and never worry about duplicates, as Faraday automatically identifies and merges duplicated issues.

+

Easily schedule scanners and jobs with Agents

+

Agents are a lightweight, highly-scalable way to automate repetitive scheduled scans or triggered jobs that unnecessarily take up team resources.

+

Jira, GitLab, ServiceNow, SolarWinds, 2nd Factor Authentication (2FA) and LDAP

+

Synchronize your favorite ticketing systems (JIRA, GitLab, ServiceNow, SolarWinds) and integrate with your existing Direct Access Protocol (LDAP).

+

We are continuously adding new integrations based on customer requests.

+

+

Easy-to-use REST API

+

Leverage our REST API to scale your own strategy by directly accessing integrations, analytics capabilities, and reporting depending on your needs.

+

+

Presentations

+ + + + + + + + + + + +
space-1.jpg
Some of the leading Security Conferences we present Faraday
+ + + +
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/integration-gitlab/index.html b/integration-gitlab/index.html new file mode 100644 index 00000000000..f69210e7336 --- /dev/null +++ b/integration-gitlab/index.html @@ -0,0 +1,1118 @@ + + + + + + + + + + + + + + +GitLab - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

GitLab

+

This is a feature that allows you to send vulnerabilities from Faraday to GitLab.

+

Initial Configuration

+

GitLab's Configuration

+

Login into GitLab and navigate to Settings > Access Tokens

+

+

+

Create a Personal Access Token with the API Scope active:

+

+

+

Copy and keep your generated personal access token

+

Now, select a Project from GitLab to connect with Faraday

+

+
+

Faraday's Configuration

+

Login into Faraday's Web UI and go to Setting clicking on your username at the top-rigth corner:

+

+

Inside Settings, navigate to Ticketing Tools and Select GitLab from the dropdown menu:

+

+

Now, complete those fields with your GitLab Project information.

+

Access Token (example): 4WRurWXnftGRbqCbJVUG

+

Project (example): TEST-PROJECT

+

template : choose a template from the dropdown menu (templates should be inside Faraday's Server at /home/faraday/.faraday/integrations_templates/)

+
{# This is a Template for Faraday Gitlab Integration #}
+{# Pre-Flight Adjustments #}
+{% set issuetracker_config = 'gitlab' %}
+{% set http_size_config = 4096 %}
+{% if 'med' in vuln.severity %}
+{% set corrected_severity = 'Medium' %}
+{% else %}
+{% set corrected_severity = vuln.severity %}
+{% endif %}
+{# Issue template structure should go under this comment #}
+{% if 'VulnerabilityWeb' in vuln.type %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})
+{% else %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}}
+{% endif %}
+## Description
+{{ vuln.desc }}
+#### This issue has been rated as: `{{ corrected_severity | capitalize }}`
+Affected Asset: {{vuln.target}}
+{%  if vuln.website %}
+Affected URL: {{ vuln.website }}{{ vuln.path }}
+{% endif %}
+{% if vuln.hostnames %}
+#### Hostnames
+{% for hostname in vuln.hostnames %}
+- {{hostname}}
+{% endfor %}
+{% endif %}
+## Recommendations
+{{ vuln.resolution }}
+{%for ref in vuln.refs%}
+- {{ref}}
+{%endfor%}
+{%if vuln.easeofresolution%}
+#### Estimated ease of resolution
+{{ vuln.easeofresolution | capitalize }}
+{%endif%}
+### Technical Details
+{%if vuln.data%}
+#### Proof of Concept
+{{vuln.data}}
+{%endif%}
+{%if vuln.request%}
+#### Request
+
+{{vuln.request|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+{% if vuln.response %}
+#### Response
+
+{{ vuln.response|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]
+{# A vulnerability might be associated with more tha one issuetracker id #}
+{% for key, value in vuln.issuetracker_json.items() %}
+{% if issuetracker_config in key%}
+This issue has already been reported in this platform:
+- {{ key | capitalize}}
+{% for line in value %}
+- Issue: {{line.url}}
+{% endfor %}
+{% endif %}
+source: created by {{vuln.owner or "faraday"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}
+{% endfor %}
+{# end of file #}
+
+

If everything is Ok, click on the green Save button and you should see a pop-up like this:

+

+
+

Send vulnerability to GitLab

+

Access your Faraday's Web UI and go to Manage > Vulns.

+

+

Click on the dropdown menu Add columns and add the issuetracker column.

+

+

+

Now, select the vulnerability you want to export and click on Tools > Gitlab

+

+

+

Click Ok.

+

You should see the word Gitlab appearing on the issuetracker column at your vuln, you can click on it to see the issue that has been created on gitlab!

+

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/integration-jira/index.html b/integration-jira/index.html new file mode 100644 index 00000000000..232ef05da8d --- /dev/null +++ b/integration-jira/index.html @@ -0,0 +1,1270 @@ + + + + + + + + + + + + + + +Jira - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Jira

+

This is a feature that allows you to send vulnerabilities from Faraday to JIRA. Through this process you will see how to

+

JIRA's Configuration

+
1. Follow the instructions based on you JIRA Instance (On-prem or Cloud)
+
+

Copy your instance URL and Project Key from your JIRA instance information:

+

+

URL (example): https://localhost:8080/

+

Project Key (example): FARADAYPRO

+
+
+

Copy your JIRA Instance URL and Project Key information:

+

+

URL (example): https://example.atlassian.net/

+

Project Key (example): FARADAYPRO

+

Now, we need to activate OAuth Authentication:

+

Inside your JIRA Cloud click on the gear icon at the top-right corner (left side of your profile icon) and click on Products, then, on the left-side bar, click on Application links

+

+

+

On the input bar at JIRA, enter your Faraday's URL (example: http://localhost:5985)

+
+

If this message appears and the URL is correct, just click Continue

+

+
+

Fill the application fields, in this case, Faraday as the Application Name, you must select the option Generic Application as the Application Type and Mark the option Create incoming link. Then, click Continue.

+

+

Now, you will need to create a:

+
    +
  • +

    Consumer Key: you should copy and save this for after configuration at Faraday.

    +
  • +
  • +

    Consumer Name: In this case, we use Faraday.

    +
  • +
  • +

    Public Key: To create this Public Key, you will need to execute the following command on your Faraday Server: faraday-manage generate-rsa-keys --integration jira you will receive something like this:

    +

    -----BEGIN PUBLIC KEY-----
    +9YxXl4D/aL/iE94MsUc9t3FFoNCP97Sfel7o+1q5YOF79qlKGbP3mXgbel/LUaSj
    +Vd91dnpg1OS1PH0p6YMDsCQfXSVBpC2OUY2hDkEwPUT/OKeAq+XE5sqEqoUeDdrS
    +OOWVuEYlWZl6ghS2TABFN5VXPgWg30Ne4L0nlDqJh2BD7RACa+Wpzbr2b/HmIxSf
    +WOj6mu7eK7Vx38CyrnOci8u59Mv/IXsEppU6nGgMZ7/Hw1ojaeSn0W6wF0Wsk3EG
    +RY/wYngdCYQEQx0rDnannBnP6EuYaqwBtNjcPpp9zvsZt+d1qmOWbii4rbqfY4BR
    +n42R05zamkSNqbwdoQ1JDyv90D6lrG+JLq/BjHaIJlAhnDIWfX6DtqgUOD3VUQfC
    +GQvvguRA
    +-----END PUBLIC KEY-----
    +
    +Just copy and paste it inside your Publick Key field at JIRA.

    +
  • +
+

+

Then, click Continue to generate the application.

+

If everything is Ok, you should see this screen:

+

+
+
+
+
+

Faraday authenticates to Jira using OAuth 1.0 A

+
+

3. Faraday's Configuration

+

Login into Faraday's Web UI and go to Setting clicking on your username in the top right corner:

+

+

Inside Settings, navigate to Ticketing Tools and Select JIRA from the dropdown menu:

+

+

JIRA On-Premise

+
1
+2
+3
+4
+5
Paste your JIRA instance information inside configuration and paste it on the correct fields.
+
+Save the instance url, project key, and generate the key to use it in the Oauth configuration.
+
+If everything is Ok, click on the blue Save button.
+
+

JIRA Cloud

+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
Inside the ticketing tool at Faraday, paste your instance URL and Project Key, then, add your **Consumer Key** into the OAuth Authentication field, after this, click the round button to authenticate!
+
+![](./images/integrations/jira/authorize-faraday.png)
+
+You should see this, **click on Redirect to JIRA**, once on JIRA website, **click on Allow** and wait until receive an Access Approved message, once received, close the tab.
+
+![](./images/integrations/jira/jira-website.png)
+
+![](./images/integrations/jira/approved-message.png)
+
+Once in Faraday, click on Authorized.
+
+![](./images/integrations/jira/oauth-succeed.png
+
+

Configure jira users in faraday

+

Inside Preferences, navigate to Ticketing Tools and Select JIRA:

+

+

Search Jira users from the Assign Users box and hit enter:

+

+

If the user is added correctly, then the user will be allowed to be reporter in the "reporters" field.

+

User added correctly!

+

+
+

4. Send vulnerability to JIRA

+

Navigate to the Manage > Vulns view inside Faraday's Web UI

+

To send vulnerabilities to JIRA, select the desired vulnerabilities, click on the Tools button at the top-right corner and then click on JIRA.

+

+

Click on the dropdown menu Add columns and add the issuetracker column.

+

+

+

Now, select the vulnerability you want to export and click on Tools > JIRA

+
+

Keep in mind that only confirmed vulnerabilities can be sent.

+
+

+
+

Once the JIRA dialog opens, you have two options:

+

You can use the default data saved in the Ticketing Tools section of Settings (see Save JIRA's Configuration for more information):

+

You can overwrite JIRA default data by clicking on the checkbox button and then manually input your JIRA credentials. Then click OK:

+

If you overwrite only one field, Faraday will fill the others fields with the default data. E.g: if you overwrite Project Key, Faraday will fill URL field with the information you have saved in Settings.

+
+

With Basic auth. +

+

Click Done.

+

You should see the word JIRA appearing on the issuetracker column at your vuln, you can click on it to see the issue that has been created on JIRA!

+

+

In Jira

+

+

Template +The template is preloaded in description but you can use the fields described in our jinja2 context doc Link +The template's name where you'll define the issue's description. You can call any attribute of the vulnerability object using Jinja2 syntax. E.g., if you want your issue in JIRA to have as description the target, the hostnames, and the severity of the vulnerability, the template would be as follows:

+
{# This is a Template for Faraday Jira Integration #}
+{# Pre-Flight Adjustments #}
+{% set issuetracker_config = 'jira' %}
+{% set http_size_config = 4096 %}
+{% if 'med' in vuln.severity %}
+{% set corrected_severity = 'Medium' %}
+{% else %}
+{% set corrected_severity = vuln.severity %}
+{% endif %}
+{# Issue template structure should go under this comment #}
+{% if 'VulnerabilityWeb' in vuln.type %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})
+{% else %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}}
+{% endif %}
+## Description
+{{ vuln.desc }}
+#### This issue has been rated as: `{{ corrected_severity | capitalize }}`
+Affected Asset: {{vuln.target}}
+{%  if vuln.website %}
+Affected URL: {{ vuln.website }}{{ vuln.path }}
+{% endif %}
+{% if vuln.hostnames %}
+#### Hostnames
+{% for hostname in vuln.hostnames %}
+- {{hostname}}
+{% endfor %}
+{% endif %}
+## Recommendations
+{{ vuln.resolution }}
+{%for ref in vuln.refs%}
+- {{ref}}
+{%endfor%}
+{%if vuln.easeofresolution%}
+#### Estimated ease of resolution
+{{ vuln.easeofresolution | capitalize }}
+{%endif%}
+### Technical Details
+{%if vuln.data%}
+#### Proof of Concept
+{{vuln.data}}
+{%endif%}
+{%if vuln.request%}
+#### Request
+
+{{vuln.request|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+{% if vuln.response %}
+#### Response
+
+{{ vuln.response|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]
+{# A vulnerability might be associated with more tha one issuetracker id #}
+{% for key, value in vuln.issuetracker_json.items() %}
+{% if issuetracker_config in key%}
+This issue has already been reported in this platform:
+- {{ key | capitalize}}
+{% for line in value %}
+- Issue: {{line.url}}
+{% endfor %}
+{% endif %}
+source: created by {{vuln.owner or "faraday"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}
+{% endfor %}
+{# end of file #}
+
+

You can also link an issue to an Epic. To do so, look after the custom field Epic Link of your instance and add it to your issue’s configuration (just as the example above). Once you add it, you need to type in the input field the issue keys of the epic.

+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/integration-servicenow/index.html b/integration-servicenow/index.html new file mode 100644 index 00000000000..7605bb7fa27 --- /dev/null +++ b/integration-servicenow/index.html @@ -0,0 +1,1262 @@ + + + + + + + + + + + + + + +ServiceNow - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

ServiceNow

+
+

This feature allows you to send vulnerabilities from Faraday to ServiceNow as an incident (using ServiceNow's Incident table).

+

Send vulnerabilities to ServiceNow

+

To send vulnerabilities to ServiceNow, go into our Status Report, select the desired vulnerabilities, click on the Tools button and then click on the ServiceNow option.

+
+

Info

+

Keep in mind that only confirmed vulnerabilities can be sent.

+
+

+

Sending To ServiceNow

+

Once the ServiceNow dialog opens, you have two options:

+

1: You can use the default data saved in the Ticketing Tools section of Settings (see Save ServiceNow's Configuration for more information):

+

+

2: You can overwrite ServiceNow default data by clicking on the checkbox button and then manually input your ServiceNow credentials. Then click OK:

+

+

Issuetracker

+

Once the vulnerability has been sent to ServiceNow, add the column issuetracker, so you can see a link that will lead you to the incident in ServiceNow.

+

+

Issuetracker's JSON

+

We added the issuetracker_json field which, if you’re using our ServiceNow integration, will give you details about the issue you created from Faraday to your ticketing instance. You can also use this field on your Executive Reports, and can render either the URL of your issue or just the ID for it.

+

Sending vulnerability’s evidence

+

You can send the vulnerability’s evidence to ServiceNow. The evidence will be sent as an incident’s attachments. Keep in mind the following considerations:

+
    +
  • You should have the right permissions to add attachments to an incident.
  • +
  • The attachment size allowed by your ServiceNow\'s instance must be greater than the size of the attachment that you want to send.
  • +
+

Save ServiceNow's Configuration

+

To save ServiceNow's configuration, go to Settings:

+

+

Then go to the Ticketing Tools section:

+

+

URL

+

Use this field to save the URL of the ServiceNow's instance where you want the vulnerability to be sent.

+

Incident's configuration

+

In the Incident's Configuration section, you can set the way you want the vulnerabilities to be parsed as ServiceNow’s incident. You can set the incident’s category and subcategory in which the vulnerabilities will be sent or you can even use Jinja2 syntax to create your own templates to parse the vulnerabilities’ information and use these templates as the incident’s description in ServiceNow.

+

Incident’s category and subcategory

+

In these dropdown menus, you can set the category and the subcategory of the incident. Once you send the vulnerability to ServiceNow, you’ll see the same category and subcategory that you defined in Faraday. To check which category and subcategory you can choose, take a look at the following ServiceNow’s link.

+

Template

+

The template's name where you'll define the incident’s description. You can call any attribute of the vulnerability object using Jinja2 syntax. E.g., if you want your incident in ServiceNow to have as description the target, the hostnames, and the severity of the vulnerability, the template would be as follows:

+

Simple template

+
{# Service now integration #}
+Name: {{ vuln.name }}
+Target: {{target}}
+Hostnames:
+{%for hostname in hostnames%}
+    - {{hostname}}
+{%endfor%}
+Severity: {{severity}}
+
+

Complex template

+
{# This is a Template for Faraday service now Integration #}
+{# Pre-Flight Adjustments #}
+{% set issuetracker_config = 'service now' %}
+{% set http_size_config = 4096 %}
+{% if 'med' in vuln.severity %}
+{% set corrected_severity = 'Medium' %}
+{% else %}
+{% set corrected_severity = vuln.severity %}
+{% endif %}
+{# Issue template structure should go under this comment #}
+{% if 'VulnerabilityWeb' in vuln.type %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})
+{% else %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}}
+{% endif %}
+## Description
+{{ vuln.desc }}
+#### This issue has been rated as: `{{ corrected_severity | capitalize }}`
+Affected Asset: {{vuln.target}}
+{%  if vuln.website %}
+Affected URL: {{ vuln.website }}{{ vuln.path }}
+{% endif %}
+{% if vuln.hostnames %}
+#### Hostnames
+{% for hostname in vuln.hostnames %}
+- {{hostname}}
+{% endfor %}
+{% endif %}
+## Recommendations
+{{ vuln.resolution }}
+{%for ref in vuln.refs%}
+- {{ref}}
+{%endfor%}
+{%if vuln.easeofresolution%}
+#### Estimated ease of resolution
+{{ vuln.easeofresolution | capitalize }}
+{%endif%}
+### Technical Details
+{%if vuln.data%}
+#### Proof of Concept
+{{vuln.data}}
+{%endif%}
+{%if vuln.request%}
+#### Request
+
+{{vuln.request|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+{% if vuln.response %}
+#### Response
+
+{{ vuln.response|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]
+{# A vulnerability might be associated with more tha one issuetracker id #}
+{% for key, value in vuln.issuetracker_json.items() %}
+{% if issuetracker_config in key%}
+This issue has already been reported in this platform:
+- {{ key | capitalize}}
+{% for line in value %}
+- Issue: {{line.url}}
+{% endfor %}
+{% endif %}
+source: created by {{vuln.owner or "faraday"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}
+{% endfor %}
+{# end of file #}
+
+

This template must be located inside the folder

+
/home/faraday/.faraday/integrations_templates/*
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/integration-solarwinds/index.html b/integration-solarwinds/index.html new file mode 100644 index 00000000000..fe99f2f6035 --- /dev/null +++ b/integration-solarwinds/index.html @@ -0,0 +1,1176 @@ + + + + + + + + + + + + + + +SolarWinds - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

WHD - SolarWinds

+
+

This feature allows you to send vulnerabilities from Faraday to Web Help Desk from Solar Winds as an incident (using Web Help Desk from Solar Winds's Incident table).

+

Send vulnerabilities to Web Help Desk from Solar Winds

+

To send vulnerabilities to Web Help Desk from Solar Winds, go into our Vulnerability View, select the desired vulnerabilities, click on the Tools button and then click on the Web Help Desk from Solar Winds option.

+
+

Info

+

Keep in mind that only confirmed vulnerabilities can be sent.

+
+

+

Sending To Web Help Desk from Solar Winds

+

Once the Web Help Desk from Solar Winds dialog opens, you have two options:

+

1: You can use the default data saved in the Ticketing Tools section of Settings (see Save Web Help Desk from Solar Winds's Configuration for more information):

+

+

2: You can overwrite Web Help Desk from Solar Winds default data by clicking on the checkbox button and then manually input your Web Help Desk from Solar Winds credentials. Then click OK:

+

+

Issuetracker

+

Once the vulnerability has been sent to Web Help Desk from Solar Winds, add the column issuetracker, so you can see a link that will lead you to the incident in Web Help Desk.

+

+

Issuetracker's JSON

+

We added the issuetracker_json field which, if you’re using our Web Help Desk from Solar Winds integration, will give you details about the issue you created from Faraday to your ticketing instance. You can also use this field on your Executive Reports, and can render either the URL of your issue or just the ID for it.

+

Save Web Help Desk from Solar Winds's Configuration

+

To save Web Help Desk from Solar Winds's configuration, go to Settings:

+

+

Then go to the Ticketing Tools section:

+

+

URL

+

Use this field to save the URL of the Web Help Desk from Solar Winds's instance where you want the vulnerability to be sent.

+

API Key

+

Use the field to fill the Api key created in Solar Winds instance.

+

Template

+

Select The first Template, there is a default template already loaded in your faraday instance.

+
{# This is a Template for Faraday solar winds Integration #}
+{# Pre-Flight Adjustments #}
+{% set issuetracker_config = 'solar winds' %}
+{% set http_size_config = 4096 %}
+{% if 'med' in vuln.severity %}
+{% set corrected_severity = 'Medium' %}
+{% else %}
+{% set corrected_severity = vuln.severity %}
+{% endif %}
+{# Issue template structure should go under this comment #}
+{% if 'VulnerabilityWeb' in vuln.type %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})
+{% else %}
+# [{{ corrected_severity | capitalize}}] {{vuln.name}}
+{% endif %}
+## Description
+{{ vuln.desc }}
+#### This issue has been rated as: `{{ corrected_severity | capitalize }}`
+Affected Asset: {{vuln.target}}
+{%  if vuln.website %}
+Affected URL: {{ vuln.website }}{{ vuln.path }}
+{% endif %}
+{% if vuln.hostnames %}
+#### Hostnames
+{% for hostname in vuln.hostnames %}
+- {{hostname}}
+{% endfor %}
+{% endif %}
+## Recommendations
+{{ vuln.resolution }}
+{%for ref in vuln.refs%}
+- {{ref}}
+{%endfor%}
+{%if vuln.easeofresolution%}
+#### Estimated ease of resolution
+{{ vuln.easeofresolution | capitalize }}
+{%endif%}
+### Technical Details
+{%if vuln.data%}
+#### Proof of Concept
+{{vuln.data}}
+{%endif%}
+{%if vuln.request%}
+#### Request
+
+{{vuln.request|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+{% if vuln.response %}
+#### Response
+
+{{ vuln.response|truncate(http_size_config, False, '...', 0) }}
+
+{%endif%}
+## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]
+{# A vulnerability might be associated with more tha one issuetracker id #}
+{% for key, value in vuln.issuetracker_json.items() %}
+{% if issuetracker_config in key%}
+This issue has already been reported in this platform:
+- {{ key | capitalize}}
+{% for line in value %}
+- Issue: {{line.url}}
+{% endfor %}
+{% endif %}
+source: created by {{vuln.owner or "faraday"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}
+{% endfor %}
+{# end of file #}
+
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/old/APIs.pdf b/old/APIs.pdf new file mode 100644 index 00000000000..bef3adb7594 Binary files /dev/null and b/old/APIs.pdf differ diff --git a/old/Architecture.pdf b/old/Architecture.pdf new file mode 100644 index 00000000000..51db858d1e0 Binary files /dev/null and b/old/Architecture.pdf differ diff --git a/old/Backup-Workspaces.pdf b/old/Backup-Workspaces.pdf new file mode 100644 index 00000000000..1b4e8dd4b0c Binary files /dev/null and b/old/Backup-Workspaces.pdf differ diff --git a/old/Basic-plugin-development.pdf b/old/Basic-plugin-development.pdf new file mode 100644 index 00000000000..c709a15bb47 Binary files /dev/null and b/old/Basic-plugin-development.pdf differ diff --git a/old/BeEF.pdf b/old/BeEF.pdf new file mode 100644 index 00000000000..f6e3887cc4f Binary files /dev/null and b/old/BeEF.pdf differ diff --git a/old/Bug-bounties.pdf b/old/Bug-bounties.pdf new file mode 100644 index 00000000000..10fefa2a0c6 Binary files /dev/null and b/old/Bug-bounties.pdf differ diff --git a/old/Burp-proxy-extender.pdf b/old/Burp-proxy-extender.pdf new file mode 100644 index 00000000000..e957df8ad28 Binary files /dev/null and b/old/Burp-proxy-extender.pdf differ diff --git a/old/Chat-and-Communication.pdf b/old/Chat-and-Communication.pdf new file mode 100644 index 00000000000..f0eef21676b Binary files /dev/null and b/old/Chat-and-Communication.pdf differ diff --git a/old/Contact-us.pdf b/old/Contact-us.pdf new file mode 100644 index 00000000000..b3bc96cef50 Binary files /dev/null and b/old/Contact-us.pdf differ diff --git a/old/Continuous-Scanning.pdf b/old/Continuous-Scanning.pdf new file mode 100644 index 00000000000..39d2ae390c7 Binary files /dev/null and b/old/Continuous-Scanning.pdf differ diff --git a/old/Credentials.pdf b/old/Credentials.pdf new file mode 100644 index 00000000000..85e42b64814 Binary files /dev/null and b/old/Credentials.pdf differ diff --git a/old/Cybersecurity-Program.pdf b/old/Cybersecurity-Program.pdf new file mode 100644 index 00000000000..05d28b48d0e Binary files /dev/null and b/old/Cybersecurity-Program.pdf differ diff --git a/old/Data-analysis-tools.pdf b/old/Data-analysis-tools.pdf new file mode 100644 index 00000000000..649b389492f Binary files /dev/null and b/old/Data-analysis-tools.pdf differ diff --git a/old/Demos.pdf b/old/Demos.pdf new file mode 100644 index 00000000000..f26db71bc11 Binary files /dev/null and b/old/Demos.pdf differ diff --git a/old/Evilgrade.pdf b/old/Evilgrade.pdf new file mode 100644 index 00000000000..237e89174c5 Binary files /dev/null and b/old/Evilgrade.pdf differ diff --git a/old/Executive-Report.pdf b/old/Executive-Report.pdf new file mode 100644 index 00000000000..a7a986b3131 Binary files /dev/null and b/old/Executive-Report.pdf differ diff --git a/old/Exporting-the-information.pdf b/old/Exporting-the-information.pdf new file mode 100644 index 00000000000..3067ea7d1a4 Binary files /dev/null and b/old/Exporting-the-information.pdf differ diff --git a/old/FAQ.pdf b/old/FAQ.pdf new file mode 100644 index 00000000000..9d91e7d7924 Binary files /dev/null and b/old/FAQ.pdf differ diff --git a/old/Faraday-Awards.pdf b/old/Faraday-Awards.pdf new file mode 100644 index 00000000000..7d753ee5134 Binary files /dev/null and b/old/Faraday-Awards.pdf differ diff --git a/old/Faraday-CSV-importer.pdf b/old/Faraday-CSV-importer.pdf new file mode 100644 index 00000000000..91f4ae862f0 Binary files /dev/null and b/old/Faraday-CSV-importer.pdf differ diff --git a/old/Faraday-Plugin.pdf b/old/Faraday-Plugin.pdf new file mode 100644 index 00000000000..9d646a57649 Binary files /dev/null and b/old/Faraday-Plugin.pdf differ diff --git a/old/Filter-GUI-WEB.pdf b/old/Filter-GUI-WEB.pdf new file mode 100644 index 00000000000..5f8dc9a6ca0 Binary files /dev/null and b/old/Filter-GUI-WEB.pdf differ diff --git a/old/First-steps.pdf b/old/First-steps.pdf new file mode 100644 index 00000000000..e48ac72f332 Binary files /dev/null and b/old/First-steps.pdf differ diff --git a/old/Helpers.pdf b/old/Helpers.pdf new file mode 100644 index 00000000000..f723956f93a Binary files /dev/null and b/old/Helpers.pdf differ diff --git a/old/Home.pdf b/old/Home.pdf new file mode 100644 index 00000000000..926fceb0247 Binary files /dev/null and b/old/Home.pdf differ diff --git a/old/Immunitys-CANVAS.pdf b/old/Immunitys-CANVAS.pdf new file mode 100644 index 00000000000..5d6d4d54205 Binary files /dev/null and b/old/Immunitys-CANVAS.pdf differ diff --git a/old/Installation-Community.pdf b/old/Installation-Community.pdf new file mode 100644 index 00000000000..f6b884db6a8 Binary files /dev/null and b/old/Installation-Community.pdf differ diff --git a/old/Installation-Corp.pdf b/old/Installation-Corp.pdf new file mode 100644 index 00000000000..623adba3da0 Binary files /dev/null and b/old/Installation-Corp.pdf differ diff --git a/old/Installation-CouchDB.pdf b/old/Installation-CouchDB.pdf new file mode 100644 index 00000000000..ff1b2a1be90 Binary files /dev/null and b/old/Installation-CouchDB.pdf differ diff --git a/old/Installation-Debian.pdf b/old/Installation-Debian.pdf new file mode 100644 index 00000000000..09c067550f7 Binary files /dev/null and b/old/Installation-Debian.pdf differ diff --git a/old/Installation-Docker.pdf b/old/Installation-Docker.pdf new file mode 100644 index 00000000000..6bcf649c27b Binary files /dev/null and b/old/Installation-Docker.pdf differ diff --git a/old/Installation-OSX.pdf b/old/Installation-OSX.pdf new file mode 100644 index 00000000000..f3339e4453d Binary files /dev/null and b/old/Installation-OSX.pdf differ diff --git a/old/Installation-Pro.pdf b/old/Installation-Pro.pdf new file mode 100644 index 00000000000..533353541d9 Binary files /dev/null and b/old/Installation-Pro.pdf differ diff --git a/old/Installation-RedHat.pdf b/old/Installation-RedHat.pdf new file mode 100644 index 00000000000..77a82b2e7dc Binary files /dev/null and b/old/Installation-RedHat.pdf differ diff --git a/old/JIRA-integration.pdf b/old/JIRA-integration.pdf new file mode 100644 index 00000000000..0b2e54b3a5e Binary files /dev/null and b/old/JIRA-integration.pdf differ diff --git a/old/LDAP.pdf b/old/LDAP.pdf new file mode 100644 index 00000000000..0ec0dee7d92 Binary files /dev/null and b/old/LDAP.pdf differ diff --git a/old/Manage-Hosts-and-Services-GUI-WEB.pdf b/old/Manage-Hosts-and-Services-GUI-WEB.pdf new file mode 100644 index 00000000000..a6973e0c287 Binary files /dev/null and b/old/Manage-Hosts-and-Services-GUI-WEB.pdf differ diff --git a/old/Manage-Users.pdf b/old/Manage-Users.pdf new file mode 100644 index 00000000000..232ae63bfc1 Binary files /dev/null and b/old/Manage-Users.pdf differ diff --git a/old/Manage-Workspaces.pdf b/old/Manage-Workspaces.pdf new file mode 100644 index 00000000000..a795a0727f6 Binary files /dev/null and b/old/Manage-Workspaces.pdf differ diff --git a/old/Metasploit.pdf b/old/Metasploit.pdf new file mode 100644 index 00000000000..bdf0b933997 Binary files /dev/null and b/old/Metasploit.pdf differ diff --git a/old/Nessus.pdf b/old/Nessus.pdf new file mode 100644 index 00000000000..df792cf93d9 Binary files /dev/null and b/old/Nessus.pdf differ diff --git a/old/OSINT-provider.pdf b/old/OSINT-provider.pdf new file mode 100644 index 00000000000..6281edc9605 Binary files /dev/null and b/old/OSINT-provider.pdf differ diff --git a/old/Plugin-List.pdf b/old/Plugin-List.pdf new file mode 100644 index 00000000000..4d9abed34b0 Binary files /dev/null and b/old/Plugin-List.pdf differ diff --git a/old/Proxy.pdf b/old/Proxy.pdf new file mode 100644 index 00000000000..9e497ac2d4c Binary files /dev/null and b/old/Proxy.pdf differ diff --git a/old/SSL.pdf b/old/SSL.pdf new file mode 100644 index 00000000000..e45d97ba8a4 Binary files /dev/null and b/old/SSL.pdf differ diff --git a/old/Scripts.pdf b/old/Scripts.pdf new file mode 100644 index 00000000000..5c37e897ecd Binary files /dev/null and b/old/Scripts.pdf differ diff --git a/old/Security.pdf b/old/Security.pdf new file mode 100644 index 00000000000..8c2aaa66a4b Binary files /dev/null and b/old/Security.pdf differ diff --git a/old/Tag-Use.pdf b/old/Tag-Use.pdf new file mode 100644 index 00000000000..e6ef438ea7c Binary files /dev/null and b/old/Tag-Use.pdf differ diff --git a/old/Tasks.pdf b/old/Tasks.pdf new file mode 100644 index 00000000000..88f62305177 Binary files /dev/null and b/old/Tasks.pdf differ diff --git a/old/Troubleshooting.pdf b/old/Troubleshooting.pdf new file mode 100644 index 00000000000..f1d3900a70a Binary files /dev/null and b/old/Troubleshooting.pdf differ diff --git a/old/Updates.pdf b/old/Updates.pdf new file mode 100644 index 00000000000..089fe36ff68 Binary files /dev/null and b/old/Updates.pdf differ diff --git a/old/Usage.pdf b/old/Usage.pdf new file mode 100644 index 00000000000..5c699b279c8 Binary files /dev/null and b/old/Usage.pdf differ diff --git a/old/Vulnerabilities-Database.pdf b/old/Vulnerabilities-Database.pdf new file mode 100644 index 00000000000..0136f494500 Binary files /dev/null and b/old/Vulnerabilities-Database.pdf differ diff --git a/old/Vulnerability-Life-Cycle.pdf b/old/Vulnerability-Life-Cycle.pdf new file mode 100644 index 00000000000..8cfca161c33 Binary files /dev/null and b/old/Vulnerability-Life-Cycle.pdf differ diff --git a/old/Workspace-Diff.pdf b/old/Workspace-Diff.pdf new file mode 100644 index 00000000000..e0edd1515dd Binary files /dev/null and b/old/Workspace-Diff.pdf differ diff --git a/old/Workspace-replication.pdf b/old/Workspace-replication.pdf new file mode 100644 index 00000000000..afe5ab4c558 Binary files /dev/null and b/old/Workspace-replication.pdf differ diff --git a/requirements/index.html b/requirements/index.html new file mode 100644 index 00000000000..65a12ef00af --- /dev/null +++ b/requirements/index.html @@ -0,0 +1,1129 @@ + + + + + + + + + + + + +Hardware Requirements for Faraday - Faraday + + + + + + + + + + + + + + + + +
+
+
+ +
+
+
+
+
+
+
+ +
+
+
+ +
+
+

Hardware Requirements for Faraday

+

Faraday is a powerful vulnerability management tool that allows you to easily identify, track, and manage vulnerabilities in your network. To get the most out of Faraday, it's important to have the right hardware in place. In this article, we'll take a look at the hardware requirements for Faraday and how to ensure that your system is set up to run Faraday smoothly and efficiently.

+

Operating System

+

Faraday requires a 64-bit operating system. This can be Linux, Ubuntu-based, or Red Hat-based. The operating system should also be up-to-date and have the latest security patches installed.

+ + + + + + + + + + + + + + + + + + + + + +
RequirementRecommended
Operating System64-bit
Operating System TypeLinux, Ubuntu-based, or Red Hat-based
Operating System VersionUp-to-date with latest security patches
+

Processor and Memory

+

Faraday requires at least a 2GHz quad-core processor and 8GB of RAM. However, for larger networks and more complex environments, it is recommended to have an octa-core processor and 16GB of RAM. This will ensure that Faraday runs smoothly and can handle large amounts of data without any performance issues.

+ + + + + + + + + + + + + + + + + + + + + + + + + +
RequirementRecommended
Processor2GHz quad-core
Memory8GB RAM
Processor (for larger networks)Octa-core
Memory (for larger networks)16GB RAM
+

Disk Space

+

Faraday also requires a minimum of 10GB of free disk space. This includes space for the Faraday server, the database, and any other files that Faraday may need to store. For larger networks and more complex environments, it is recommended to have at least 20GB of free disk space.

+ + + + + + + + + + + + + + + + + +
RequirementRecommended
Disk Space10GB
Disk Space (for larger networks)20GB
+

Network Connectivity

+

Faraday requires a stable internet connection. This is necessary for Faraday to communicate with the Faraday server and to access any necessary updates or patches. Faraday also requires a stable and fast connection to the network that it is scanning. This will ensure that Faraday can quickly and efficiently scan the network and identify any vulnerabilities.

+ + + + + + + + + + + + + + + + + +
RequirementDescription
Internet ConnectionStable
Network ConnectivityStable and fast connection to the network being scanned
+

Database

+

For the database, it is required PostgreSQL 9.6 or higher.

+ + + + + + + + + + + + + +
RequirementDescription
DatabasePostgreSQL 9.6 or higher
+

Python

+

Faraday requires Python 3.7 or higher to be installed. Python is a programming language that Faraday uses to communicate with the Faraday server and to run various scripts and plugins. It is important to ensure that the correct version of Python is installed and that it is up-to-date.

+ + + + + + + + + + + + + +
RequirementDescription
Python3.7 or higher
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 Minimum Requirements
Processorquadcore 2Ghz Intel/AMD CPU
Operating SystemWe recommend using Ubuntu Server 18.04 (LTS)
RAM4 GB or more (8 GB recommended)
Hard Disk Space40 GB (depends on usage, PostgreSQL could consume up to 80 GB)
InternetInternet connection is necessary for installation and license (Commercial)
+
+
+ +
+
+ +
+
+
+
+ + + + + \ No newline at end of file diff --git a/search/search_index.json b/search/search_index.json new file mode 100644 index 00000000000..56d82c879d4 --- /dev/null +++ b/search/search_index.json @@ -0,0 +1 @@ +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"Home","text":""},{"location":"#rethink-vulnerability-management-for-your-network-security","title":"Rethink Vulnerability Management for your Network Security","text":"

Security faces two challenging objectives: developing intelligent methods for obtaining new information and effectively managing and enhancing remediation efforts. With the utilization of Faraday, you can prioritize vulnerability discovery while we assist you with the remaining tasks. Simply access Faraday through your terminal and effortlessly organize your work on the go.

Faraday was specifically designed to enable you to leverage the diverse range of tools within the security community, fostering a truly collaborative multiuser environment.

By consolidating and standardizing the data you input, Faraday empowers you to explore it through various visualizations that prove valuable to both managers and analysts.

Faraday is meticulously crafted to optimize the process of Vulnerability Management. It excels at normalizing, tracking, and identifying assets and vulnerability data from over 90 different security tools.

To read about the latest features check out the release notes!

"},{"location":"#getting-started","title":"Getting Started","text":"

Learn about Faraday holistic approach and rethink vulnerability management.

  • Centralize your vulnerability data

  • Automate the scanners you need

"},{"location":"#integrating-faraday-in-your-cicd","title":"Integrating faraday in your CI/CD","text":"

Setup Bandit and OWASP ZAP in your pipeline

  • GitHub [PDF]

  • Jenkins [PDF]

  • TravisCI [PDF]

Setup Bandit, OWASP ZAP and SonarQube in your pipeline

  • Gitlab [PDF]
"},{"location":"#faraday-cli","title":"Faraday Cli","text":"

Faraday-cli is our command line client, providing easy access to the console tools, work in faraday directly from the terminal!

This is a great way to automate scans, integrate it to CI/CD pipeline or just get metrics from a workspace

$ pip3 install faraday-cli\n

Check our faraday-cli repo

Check out the documentation here.

"},{"location":"#faraday-agents","title":"Faraday Agents","text":"

Faraday Agents Dispatcher is a tool that gives Faraday the ability to run scanners or tools remotely from the platform and get the results.

"},{"location":"#actionable-reporting-and-vulnerability-templates","title":"Actionable reporting and Vulnerability templates","text":"

Every company has a different approach to reporting. Faraday provides a way for companies to export their data into their own compliance-ready formats.

"},{"location":"#plugins","title":"Plugins","text":"

Connect you favorite tools through our plugins. Right now there are more than 80+ supported tools, among which you will find:

Missing your favorite one? Create a Pull Request!

There are two Plugin types:

Console plugins which interpret the output of the tools you execute.

$ faraday-cli tool run \\\"nmap www.exampledomain.com\\\"\n\ud83d\udcbb Processing Nmap command\nStarting Nmap 7.80 ( https://nmap.org ) at 2021-02-22 14:13 -03\nNmap scan report for www.exampledomain.com (10.196.205.130)\nHost is up (0.17s latency).\nrDNS record for 10.196.205.130: 10.196.205.130.bc.example.com\nNot shown: 996 filtered ports\nPORT     STATE  SERVICE\n80/tcp   open   http\n443/tcp  open   https\n2222/tcp open   EtherNetIP-1\n3306/tcp closed mysql\nNmap done: 1 IP address (1 host up) scanned in 11.12 seconds\n\u2b06 Sending data to workspace: test\n\u2714 Done\n

Report plugins which allows you to import previously generated artifacts like XMLs, JSONs.

faraday-cli tool report burp.xml\n

Creating custom plugins is super easy, Read more about Plugins. Vulnerability Templates

Quickly fill out the gaps in your vulnerability data with Templates from your personalized Knowledge Base.

Reduce and Prioritize

An interface built around collaboration and simplicity: manage, tag, prioritize with ease.

Faraday Client

Our Shell allows you to upload results while pentesting actively.

"},{"location":"#custom-workflows-and-seamless-deduplication","title":"Custom Workflows and seamless Deduplication","text":"

Trigger any action with custom events built to avoid repetitive tasks. Import all your data and never worry about duplicates, as Faraday automatically identifies and merges duplicated issues.

"},{"location":"#easily-schedule-scanners-and-jobs-with-agents","title":"Easily schedule scanners and jobs with Agents","text":"

Agents are a lightweight, highly-scalable way to automate repetitive scheduled scans or triggered jobs that unnecessarily take up team resources.

"},{"location":"#jira-gitlab-servicenow-solarwinds-2nd-factor-authentication-2fa-and-ldap","title":"Jira, GitLab, ServiceNow, SolarWinds, 2nd Factor Authentication (2FA) and LDAP","text":"

Synchronize your favorite ticketing systems (JIRA, GitLab, ServiceNow, SolarWinds) and integrate with your existing Direct Access Protocol (LDAP).

We are continuously adding new integrations based on customer requests.

"},{"location":"#easy-to-use-rest-api","title":"Easy-to-use REST API","text":"

Leverage our REST API to scale your own strategy by directly accessing integrations, analytics capabilities, and reporting depending on your needs.

"},{"location":"#presentations","title":"Presentations","text":"Some of the leading Security Conferences we present Faraday
  • Ekoparty : 2010 - 2014 - 2017 - 2018

  • Black Hat:

    • USA : 2011 - 2015 - 2016 - 2017 - 2018

    • Asia : 2016 - 2017 - 2018

    • Europe : 2015 - 2016

  • RSA USA : 2015

  • HITBSecConf Dubai : 2018

  • SecurityWeekly : 2016

  • Zero Nights : 2016

  • AVTokyo : 2016 - 2018

  • Tel Aviv-Yafo : 2018

  • SECCON : 2018

  • PyConAr : 2018

  • 8.8 Chile : 2018

  • CharruaCon : 2018

  • NotPinkCon : 2018

  • plusCODE : 2018

  • BSides LATAM : 2016

"},{"location":"#links","title":"Links","text":"
  • Homepage: faradaysec.com

  • Documentation: Faraday Docs

  • Download: Download .deb/.rpm from releases page

  • Issue tracker and feedback: Github issue tracker

  • Frequently Asked Questions: FaradaySEC FAQ

  • Twitter: @faradaysec

  • Try one of our Demos

"},{"location":"2-Factor-Authentication/","title":"Faraday supports 2nd Factor Authentication. We support any apps, e.g:","text":"
  1. Google Authenticator Android
  2. Google Authenticator iOS
  3. Authy Android
  4. Authy iOS
  5. OTP Authenticator Android, Open Source
"},{"location":"2-Factor-Authentication/#activate-2fa","title":"Activate 2FA","text":"
  • Click on the Faraday slider menu on the top right of the screen, select Account and go to the Two Factor Authentication tab.

* Once you enable 2FA, Faraday will show you a QR code and thus you can scan it with your chosen app.

As with every app using 2FA, the time on your phone and on your machine must be synchronized.

"},{"location":"API-Server/","title":"API Server","text":""},{"location":"API-Server/#faraday-server-api","title":"Faraday Server API","text":"

Faraday has a RESTful API under _api url prefix where the server is configured (example: https://server.faradaysec.com:5985/_api/v3/)

The Faraday REST API enables you to interact with our server. Use this API to interact or integrate with Faraday server. [This page] documents the REST API, with HTTP response codes and example requests and responses.

We have a Swagger page to explore the api here:

"},{"location":"API-Server/#faraday-server-api-description","title":"Faraday Server API Description","text":"

Faraday has a Server RESTful API by default running on 127.0.0.1:5985.

INFO: On cloud, you have to replace this with \"https://yourdomain.faradaysec.com/\"

You can check all API endpoints with the command:

$ faraday-manage show-urls\n
"},{"location":"API-Server/#methods","title":"Methods","text":"

POST: creates objects

GET: get a list of objects or get one object given its object_id

PUT: update object

DELETE: delete object

"},{"location":"API-Server/#headers","title":"Headers","text":"

Our API endpoints support JSON and you must always include the header:

Content-Type: application/json\n
"},{"location":"API-Server/#authentication","title":"Authentication","text":"

The server API requires authentication. Currently, we support cookie authentication.

The endpoint for login is /_api/login and the json payload is:

{\"email\": \"USERNAME\", \"password\": \"SECRET_PASSWORD\"}\n

Endpoints Faraday Config: Here are the list of API endpoints for license, users, workspace and authentication:

(HEAD, POST, OPTIONS, GET) -> '/login' \n(HEAD, OPTIONS, GET) -> '/logout' \n(HEAD, OPTIONS, GET) -> '/session'\n(HEAD, POST, OPTIONS, GET) -> '/change' \n(HEAD, OPTIONS, GET) -> '/config' \n(HEAD, OPTIONS, GET) -> '/_api/v3/licenses/'\n(POST, OPTIONS) -> '/_api/v3/licenses/'\n(OPTIONS, DELETE) -> '/_api/v3/licenses/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/licenses/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/licenses/<object_id>/'\n(OPTIONS, DELETE) -> '/_api/v3/users/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/users/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/users/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/users/'\n(POST, OPTIONS) -> '/_api/v3/users/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/in'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/'\n(POST, OPTIONS) -> '/_api/v3/ws/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<object_id>/'\n
"},{"location":"API-Server/#host","title":"Host","text":"

This API endpoint allows you to change the Host objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/hosts/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/count/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/countVulns/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/hosts/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/hosts/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/hosts/<host_id>/services/'\n(DELETE, OPTIONS) -> '/_api/v3/ws/<workspace_name>/hosts/bulk_delete/'\n
JSON Body of the Host object:

{\n    \"ip\":\"test\",\n    \"hostnames\": [],\n    \"mac\":\"00:00:00:00:00:00\",\n    \"description\":\"\",\n    \"default_gateway\":\"None\",\n    \"os\":\"\",\n    \"owned\":false,\n    \"owner\":\"\"\n}\n

Services

This API endpoint allows you to change the Service objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/services/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/services/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/services/count/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/services/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/services/<object_id>/'  \n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/services/<object_id>/'\n

JSON Body of the Service object:

{\n    \"name\":\"test\",\n    \"description\":\"\",\n    \"owned\":false,\n    \"owner\":\"\",\n    \"ports\":[8080],\n    \"protocol\":\"tcp\",\n    \"parent\":1156,\n    \"status\":\"open\",\n    \"version\":\"\",\n    \"type\":\"Service\" \n}\n

Vulnerability This API endpoint allows you to change the Vulnerability objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/vulns/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/count/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/timeline/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/vulns/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/vulns/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/vulns/<vuln_id>/attachment/<attachment_filename>/' \n(POST, OPTIONS) -> '/_api/v3/ws/<workspace>/upload_report'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tags/'\n

JSON Body of the Vulnerability object:

"},{"location":"API-Server/#info-key-named-type-can-be","title":"INFO: key named type can be:","text":"

vulnerability: Normal vulnerability, the parent could be a service or a host. vulnerability_web: Web vulnerability, the parent can only be a service.

{\n    \"owner\":\"faraday\",\n    \"parent\":1156,\n    \"parent_type\":\"Host\",\n    \"type\":\"Vulnerability\",\n    \"ws\":\"api\",\n    \"confirmed\":true,\n    \"data\":\"\",\n    \"desc\":\"Testing API\",\n    \"impact\": \n    {\n        \"accountability\":false,\n        \"availability\":false,\n        \"confidentiality\":false,\n        \"integrity\":false\n    },\n    \"name\":\"test\",\n    \"owned\":false,\n    \"policyviolations\":[],\n    \"refs\":[],\n    \"resolution\":\"\",\n    \"severity\":\"high\",\n    \"issuetracker\":\"\",\n    \"status\":\"opened\",\n    \"_attachments\":{},\n    \"description\":\"\",\n    \"protocol\":\"\",\n    \"version\":\"\"\n}\n

"},{"location":"API-Server/#tasks","title":"Tasks","text":"

This API endpoint allows you to change the Task objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tasks/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/tasks/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tasks/count/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/tasks/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/tasks/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/tasks/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/taskGroups/manualimport/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/import/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/count/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/taskGroups/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/taskGroups/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/taskGroups/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/taskGroups/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/task_template/'\n(POST, OPTIONS) -> '/_api/v3/task_template/'\n(OPTIONS, DELETE) -> '/_api/v3/task_template/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/task_template/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/task_template/<object_id>/'\n(OPTIONS, DELETE) -> '/_api/v3/methodology_template/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/methodology_template/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/methodology_template/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/methodology_template/'\n(POST, OPTIONS) -> '/_api/v3/methodology_template/'\n
JSON Body of the Task object:

{\n    \"name\":\"test\", \n    \"type\":\"TaskGroup\", \n    \"group_type\":\"instance\", \n    \"instance_of\":\"\", \n    \"tCompletedtasks\":0, \n    \"totaltasks\":0\n}\n

Reports This API endpoint allows you to create reports from the API and download them:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/reports/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/count/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/countVulns/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/listTemplates/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/reports/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/reports/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/reports/<report_id>/download/'\n
JSON Body of the Reports object:

{\n    \"name\":\"Testing-API\",\n    \"tags\":[],\n    \"title\":\"Network XYZ\",\n    \"enterprise\":\"ACMEINC\",\n    \"scope\":\"Scope\",\n    \"objectives\":\"Objetives\",\n    \"summary\":\"Summ\",\n    \"confirmed\":false,\n    \"conclusions\":\"Conclusions\",\n    \"recommendations\":\"Recommendations\",\n    \"vuln_count\":4,\n    \"template_name\":\"generic_default.docx\",\n    \"grouped\":false\n}\n
"},{"location":"API-Server/#vulnerability-template","title":"Vulnerability Template","text":"

This API endpoint allows you to change the Vulnerability Template (VulnDB) objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/vulnerability_template/'\n(POST, OPTIONS) -> '/_api/v3/vulnerability_template/'\n(OPTIONS, DELETE) -> '/_api/v3/vulnerability_template/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/vulnerability_template/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/vulnerability_template/<object_id>/'\n

JSON Body of the Vulnerability Template object:

{\n    \"cwe\":\"\",\n    \"description\":\"Test\",\n    \"desc\":\"\",\n    \"exploitation\":\"high\",\n    \"name\":\"Testing API\",\n    \"references\":[],\n    \"refs\":[],\n    \"resolution\":\"\",\n    \"type\":\"vulnerability_template\"\n}\n

Credentials This API endpoint allows you to change the Credential objects:

(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/credential/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/credential/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/credential/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/credential/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/credential/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/credential/count/'\n
JSON Body of the Credentials object:

{\n    \"name\":\"Test\",\n    \"username\":\"faraday\",\n    \"password\":\"changeme\",\n    \"type\":\"Cred\",\n    \"parent_type\":\"Host\",\n    \"parent\":\"1147\",\n    \"owner\":\"\",\n    \"description\":\"\"\n}\n
"},{"location":"API-Server/#activity-feed","title":"Activity Feed","text":"

This API endpoint allows you to change the Activity Feed (from Dashboard) objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/activities/count/'\n(HEAD, OPTIONS, GET) ->  '/_api/v3/ws/<workspace_name>/commands/activity_feed/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/activities/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/activities/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/activities/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/activities/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/activities/'\n
"},{"location":"API-Server/#comments","title":"Comments","text":"

This API endpoint allows you to change the Comment objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/comment/count/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/comment/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/comment/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/comment/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/comment/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/comment/'\n
"},{"location":"API-Server/#commands","title":"Commands","text":"

This API endpoint allows you to change the Commands objects:

(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/commands/count/'\n(OPTIONS, DELETE) -> '/_api/v3/ws/<workspace_name>/commands/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/commands/<object_id>/'\n(PUT, OPTIONS) -> '/_api/v3/ws/<workspace_name>/commands/<object_id>/'\n(HEAD, OPTIONS, GET) -> '/_api/v3/ws/<workspace_name>/commands/'\n(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/commands/'\n

"},{"location":"API-Server/#others","title":"Others:","text":"
(POST, OPTIONS) -> '/_api/v3/ws/<workspace_name>/comment_unique/'\n
"},{"location":"API-Server/#examples","title":"Examples","text":"

Assuming that our credentials are:

username: faraday\n\npassword: changeme\n

Login: in order to be able to login through the API, you must supply your credentials and store them in a cookie file just as the following example:

    curl -s 'http://127.0.0.1:5985/_api/login' \\\n        -H 'Origin: http://127.0.0.1:5985/' -H 'Accept-Encoding: gzip, deflate, br' \\\n        -H 'Accept-Language: en-US,en;q=0.9' \\\n        -H 'Content-Type: application/json' \\\n        -H 'Accept: application/json, text/javascript, */*; q=0.01' \\\n        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \\\n        -H 'Connection: keep-alive' \\\n        --data-binary '{\"email\":\"faraday\",\"password\": \"changeme\"}' \\\n        --compressed -c cookie.txt > /dev/null\n

"},{"location":"API-Server/#creating-a-host-assuming-our-workspace-name-is-test","title":"Creating a host: assuming our workspace name is test:","text":"
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/hosts/ \\\n        -d '{\"ip\":\"127.0.0.1\",\"hostnames\":[\"testing\"], \"mac\":\"00:00:00:00:00:00\",\"description\":\"Testing API\", \"default_gateway\":\"None\", \"os\":\"Linux\", \"owned\":true, \"owner\":\"\"}' \\\n        -b cookie.txt \\\n        -H 'Content-Type: application/json'\n
"},{"location":"API-Server/#getting-a-list-of-hosts","title":"Getting a list of hosts:","text":"
curl -X GET http://127.0.0.1:5985/_api/v3/ws/test/hosts/ -b cookie.txt\n
"},{"location":"API-Server/#creating-a-service","title":"Creating a service:","text":"
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/services/ \\\n        -d '{\"name\":\"Test\",\"description\":\"Testing API\", \"owned\":true, \"owner\":\"\",\"ports\":[8080],\"protocol\":\"tcp\",\"parent\":1157,\"status\":\"open\",\"version\":\"\",\"metadata\":{\"update_time\":1533152663.994,\"update_user\":\"\",\"update_action\":0,\"creator\":\"\",\"create_time\":1533152663.994,\"update_controller_action\":\"UI Web New\",\"owner\":\"\"},\"type\":\"Service\"}' \\\n        -b cookie.txt \\\n        -H 'Content-Type: application/json'\n
"},{"location":"API-Server/#creating-a-vuln","title":"Creating a vuln:","text":"
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/vulns/ \\\n        -d '{\"metadata\":{\"update_time\":1533152883.927, \"update_user\":\"\", \"update_action\":0,\"creator\":\"UI Web\", \"create_time\":1533152883.927, \"update_controller_action\":\"UI Web New\", \"owner\":\"faraday\"}, \"obj_id\":\"\", \"owner\":\"faraday\", \"parent\":1157, \"parent_type\":\"Host\",\"type\":\"Vulnerability\",\"ws\":\"test\",\"confirmed\":true,\"data\":\"\",\"desc\":\"New vulnerability created for API purposes\",\"easeofresolution\":\"simple\",\"impact\":{\"accountability\":false, \"availability\":false, \"confidentiality\":false, \"integrity\":false},\"name\":\"New Vuln - Testing API\",\"owned\":false,\"policyviolations\":[],\"refs\":[], \"resolution\":\"\", \"severity\":\"critical\", \"issuetracker\":\"\", \"status\":\"opened\",\"_attachments\":{},\"description\":\"\",\"protocol\":\"\",\"version\":\"\"}' \\\n        -b cookie.txt \\\n        -H 'Content-Type: application/json'\n
"},{"location":"API-Server/#creating-a-user","title":"Creating a user:","text":"
    curl -X POST http://127.0.0.1:5985/_api/v3/users/ \\\n        -d '{\"name\":\"faraday\", \"password\":\"changeme\", \"roles\":[\"admin\"], \"type\":\"user\", \"role\":\"admin\"}' \\\n        -b cookie.txt \\\n        -H 'Content-Type: application/json'\n
"},{"location":"API-Server/#generating-a-report","title":"Generating a report:","text":"
    curl -X POST http://127.0.0.1:5985/_api/v3/ws/test/reports/ \\\n        -d '{\"name\":\"Testing-API\",\"tags\":[], \"title\":\"\", \"enterprise\":\"\", \"scope\":\"\", \"objectives\":\"\", \"summary\":\"\", \"confirmed\":false, \"conclusions\":\"\", \"recommendations\":\"\", \"vuln_count\":2, \"template_name\":\"generic_default.docx\", \"grouped\":false}' \\\n        -b cookie.txt \\\n        -H 'Content-Type: application/json'\n
"},{"location":"API-Server/#uploading-a-report","title":"Uploading a report:","text":"

In order to be able to upload a report, you need the CSRF token and session's cookies. To get session's cookie, go to the Status Report and take it from RequestHeaders section of the console. And to get the CSRF token, in the same console, go to the tab Response.

On the first --form parameter,put the path of the file that you want to upload.

    curl -X POST http://127.0.0.1:5985/_api/v3/ws/api/upload_report \\\n       -H 'Content-Type: multipart/form-data' \\\n       --cookie \"session=.eJw90M2KwjAQB_BXWXL2YGu9CB6UlGJhpgSCZeZS2FpNJ2YXqkI24rtv18O-wO__8VTdeRpuTm3u02NYqG48qc1TfXyqjWK9SyyUYVsWmMrUWDei9Etsj4FaDKydw-Qj5KZo9CWSNUu2uzXktQM5XSnxyJVZgTaRrYkk-xEt5ZQfVmT3DmcfKvrhcBQUKMgeIoQysb0knjMh-QIEliyQQzJZ0-IV_kx7DWDZY1WPmNCD9Fv1Wqj-Np27-7cfvv4noNTSVCZjXSaYK2KgiLqMTTtX1H7daMpmPnLFgtpHSk7YbN_c4zZM7ztUoV6_3rRiDA.DkoypQ.q7eGzh1oof8dKnbF4q6xD_n1d6o\" \\\n       --form \"file=@PATH/TO/FILE\" \\\n       --form \"csrf_token=IjYyYzhkNWQxMzA4MTZmMTQxMTliYTA5OTg2NWYzMWRmYzQ5MWM4Y2Ui.Dko4Zw.sZ-LLdGoxaNFUaySFFQMvyLecxc\" \\\n       --compressed\n
"},{"location":"API-Server/#using-the-api-to-create-a-workspace","title":"Using the API to create a workspace","text":"

Here we provide a Python script using requests to create a new workspace:

# -*- coding: utf-8 -*-\nimport click\nfrom requests import Session\n\n@click.command()\n@click.option('--username', prompt=True)\n@click.option('--password', prompt=True)\n@click.option('--server_address', prompt=True, help='Faraday server url', default='http://localhost:5985/')\n@click.option('--workspace_name', prompt=True)\ndef create_workspace(username, password, server_address, workspace_name):\n    print('Authentication to server {0}'.format(server_address))\n    session = Session()\n    # authentication to faraday server\n    session.post(server_address + '/_api/login', json={'email': 'faraday', 'password': 'Password123'})\n    # create new workspace\n    ws_payload = {\n            \"customer\":\"\",\n            \"name\":workspace_name,\n            \"type\":\"Workspace\",\n            \"users\":[\"faraday\"],\n            \"public\":False,\n            \"children\":[],\n            \"duration\":{\"start_date\":\"\",\"end_date\":\"\"},\n            \"scope\":[],\n            \"description\":\"\"\n            }\n\n    res = session.post(server_address + '/_api/v3/ws/', json=ws_payload)\n    assert res.status_code == 201\n    print('Workspace {0} created'.format(workspace_name))\n\n\ncreate_workspace()\n
"},{"location":"API-Server/#using-the-api-to-create-users-in-bulk","title":"Using the API to create users in bulk","text":"
curl -s  'http://127.0.0.1:5985/_api/login' \\\n        -H 'Origin: http://127.0.0.1:5985/' -H 'Accept-Encoding: gzip, deflate, br' \\\n        -H 'Accept-Language: en-US,en;q=0.9' \\\n        -H 'Content-Type: application/json' \\\n        -H 'Accept: application/json, text/javascript, */*; q=0.01' \\\n        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \\\n        -H 'Connection: keep-alive' \\\n        --data-binary '{\"email\":\"faraday\",\"password\": \"changeme\"}' \\\n        --compressed -c cookie.txt \n\n\nwhile read -r line; do\n    curl -X POST http://127.0.0.1:5985/_api/v3/users/ \\\n        -d '{\"name\":\"'$line'\",\"password\":\"Password123\",\"roles\":[\"client\"],\"type\":\"user\",\"role\":\"client\"}' \\\n        -H 'Content-Type: application/json' \\\n        -b cookie.txt\ndone < \"users.txt\"\n
"},{"location":"API-Server/#using-the-api-to-delete-hosts-in-bulk","title":"Using the API to delete hosts in bulk","text":"
curl -X DELETE http://127.0.0.1:5985/_api/v3/ws/test/hosts/bulk_delete/ \\\n-d '{\"hosts_ids\": [ 1, 2, 3, 4]}' \\\n-b cookie.txt \\\n-H 'Content-Type: application/json'\n
"},{"location":"API-Server/#upload-evidence-to-a-vulnerability","title":"Upload evidence to a Vulnerability","text":"

Remember to change the workspace name in the urls and vuln id to attach evidence.

curl -s  'http://127.0.0.1:5985/_api/login' \\\n        -H 'Content-Type: application/json' \\\n        -H 'Accept: application/json, text/javascript, */*; q=0.01' \\\n        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \\\n        -H 'Connection: keep-alive' \\\n        --data-binary '{\"email\":\"faraday\",\"password\": \"changeme\"}' \\\n        --compressed -c cookie.txt \n
"},{"location":"API-Server/#obtain-csrf-token-to-upload-files","title":"obtain csrf token to upload files","text":"

csrf_token=$(curl -s -X GET http://127.0.0.1:5985/_api/session -b cookie.txt -c csrf_cookie.txt| python -c \"import sys, json; print json.load(sys.stdin)['csrf_token']\")

"},{"location":"API-Server/#upload-the-file-evidencepng","title":"Upload the file evidence.png","text":"
curl 'http://localhost:5985/_api/v3/ws/demo_workspace/vulns/251/attachment/' \\\n          -H 'Connection: keep-alive' --data-binary $'------WebKitFormBoundary4RCsZGBu1aaCqyxT\\r\\nContent-Disposition: form-data;name=\"csrf_token\"\\r\\n\\r\\$csrf_token\\r\\n------WebKitFormBoundary4RCsZGBu1aaCqyxT\\r\\nContent-Disposition: form-data; name=\"file\"; filename=\"evidence.png\"\\r\\nContent-Type: image/png\\r\\n\\r\\n\\r\\n------WebKitFormBoundary4RCsZGBu1aaCqyxT--\\r\\n' \\ \n          --compressed -c csrf_cookie.txt\n
"},{"location":"API-Server/#upload-reports-xml-results-from-tools-using-curl","title":"Upload reports (XML results from tools) using curl","text":"

Please check the URLs and use the correct workspace name!

curl -s  'http://127.0.0.1:5985/_api/login' \\\n        -H 'Origin: http://127.0.0.1:5985/' -H 'Accept-Encoding: gzip, deflate, br' \\\n        -H 'Accept-Language: en-US,en;q=0.9' \\\n        -H 'Content-Type: application/json' \\\n        -H 'Accept: application/json, text/javascript, */*; q=0.01' \\\n        -H 'Referer: http://127.0.0.1:5985/' -H 'X-Requested-With: XMLHttpRequest' \\\n        -H 'Connection: keep-alive' \\\n        --data-binary '{\"email\":\"faraday\",\"password\": \"changeme\"}' \\\n        --compressed -c cookie.txt \n\ncsrf_token=$(curl -s -X GET http://127.0.0.1:5985/_api/session -b cookie.txt -c csrf_cookie.txt | python -c \"import sys, json; print json.load(sys.stdin)['csrf_token']\")\necho $csrf_token\n\necho \";currentUrl=%2Fstatus%2Fws%2Ftest1; currentComponent=status\" >> cookie.txt\ncurl -i -v http://127.0.0.1:5985/_api/v3/ws/test1/upload_report \\\n        -H \"Connection: keep-alive\" \\\n        -H \"Pragma: no-cache\" \\\n        -H \"Cache-Control: no-cache\" \\\n        -H \"Accept: application/json, text/plain, */*\" \\\n        -H \"Origin: http://127.0.0.1:5985/\" \\\n        -H \"User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36\" \\\n        -H \"Content-Type: multipart/form-data\" \\\n        -H \"Referer: http://127.0.0.1:5985/\" \\\n        -H \"Accept-Encoding: gzip, deflate, br\" \\\n        -H \"Accept-Language:  en-US,en;q=0.9,es;q=0.8\" \\\n        --form \"csrf_token=$csrf_token\" \\\n        --form \"file=@/PATH/TO/FILE\" \\\n        -b csrf_cookie.txt \n
"},{"location":"API-Token/","title":"API Token","text":"

Upon faraday v3.9 we included an API Token for our api. The token for the API will expire when the user changes the password.

You can configure token expiration in the [server] section of the configuration with the option api_token_expiration expressed in seconds.

Token expires by timeout or when the user changes the password. Each token is associated to the user who requests the token.

This is a example request of how to obtain a token

curl --user USER:PASSWORD http://localhost:5985/_api/v3/token/\n\"eyJhbGciOiJIUzUxMiIsImlhdCI6MTYxOTAzMTU3OCwiZXhwIjoxNjIxNjIxNzc4fQ.eyJ1c2VyX2lkIjoiZjNjYTUyNjYtOWU2ZS00NzQwLWI0NWItN2Y2M2JkZWMzN2UwIiwidmFsaWRhdGlvbl9jaGVjayI6IiQ1JHJvdW5kcz01MzUwMDAkVDZ3cy9ZMGFHUW10UnEzSSRpRS5OSG1oaDNWR0h4VXIudVpRNGRnaEVVUXFiS09pWGg5VGdrTURtQXIwIn0.gu6AgQ-iIvdnrHBphBfzWopn5B21D_RvTFvltcoMnksAj0eHhfh7dkJW4GfjhZPQd02RBAsb3vvUUCA0fORvfw\"\n

Now that you got the auth token you can start using it on every request to the api:

curl 'http://localhost:5985/_api/v3/ws/' -H 'Authorization:Token AUTH_TOKEN' -H 'Content-Type: application/json' \n
import requests\nsession = requests.Session()\nuser = 'faraday'\npassword = 'yourpassword'\nsession.auth = (user, password)\nauth = session.post('https://localhost:5985/_api/v3/token')\nresponse = session.get('https://localhost5985/_api/v3/token')\nprint(response.text) ## now the token is in response\n
"},{"location":"Activity-Dashboard/","title":"Activity Dashboard","text":"

Activity dashboard provides a quick view with graphics and an Activity Feed that will display in an effective view all the changes and stats for the workspace.

The Central view Vulnerabilities by Severities provides a New Filter that will allow to display confirmed or not closed Vulnerabilities, to show an overall but modifying the scope.

There are new Latest tags also linked to the vuln view to quickly access to some tag from the activity dashboard.

Comments will show all the latest comments in a selected Workspace

"},{"location":"Architecture/","title":"Technical introduction","text":"

Faraday is a web application, the Server is made with python using Flask and the frontend is made with AngularJS (we are moving to ReactJS). It is deployed as a standard WSGI application. Its possible to interact with the Server using Faraday CLI and you can automatize tool usage with Faraday agent.

The data is persisted within a PostgreSQL database, processed with python libraries as SQLAlchemy and Marshmallow.

The server has other main components as the Report Processor, or the Websocket Server. The latter provides information to the CLI and the Agents.

"},{"location":"Architecture/#faraday-cli","title":"Faraday CLI","text":"

Faraday CLI provides an interface for interacting with a terminal that allows the user to execute commands which results will be loaded inside Faraday Server. The CLI also allows the user to upload tool reports, create workspaces and configure your instance.

"},{"location":"Architecture/#faraday-agent","title":"Faraday Agent","text":"

The Faraday Agents allows to automate the upload of different data to the server, such as integration with other applications or services; or execute some tools that the Faraday plugins can process. Moreover, the Agents can be executed on any remote computer and its Executors can be written in any language.

"},{"location":"Architecture/#burp-zap-addons","title":"Burp / Zap Addons","text":"

Faraday has Burp/Zap Extensions that run inside the third party application. Using Faraday addons provides flexibility to ingress information inside Faraday Server from other applications.

"},{"location":"Architecture/#appendix","title":"Appendix","text":""},{"location":"Architecture/#database-schema","title":"Database schema","text":"

Faraday manage command can generate the current database schema with:

faraday-manage database-schema\n
  • frontend
  • server
  • faraday_client
  • faraday_agent_dispatcher
  • faraday_agent_parameters_types
  • api_docs
  • faraday_plugins
  • burp_addon
  • zap_addon
"},{"location":"Assets-and-Services-v4/","title":"Assets and Services","text":"

You can manage your Assets and their associated Services by accessing the Hosts View in the Manage section through the Faraday Web UI.

"},{"location":"Assets-and-Services-v4/#how-to-manage-assets","title":"How to Manage Assets","text":""},{"location":"Assets-and-Services-v4/#create-an-asset","title":"Create an Asset","text":"

From the Assets View, click Add Asset and fill out the form The only mandatory field is IP v4 or v6

"},{"location":"Assets-and-Services-v4/#edit-an-asset","title":"Edit an Asset","text":"

From the Assets View, click on the Asset IP field

The services list will be displayed and on the left side you click on Edit button to add or modify details (hostnames, MAC address, owned, OS, description)

"},{"location":"Assets-and-Services-v4/#delete-an-asset","title":"Delete an Asset","text":"

From the Assets View, select one or more assets and click Delete

"},{"location":"Assets-and-Services-v4/#how-to-manage-services","title":"How to Manage Services","text":"

To manage services for an specific asset, click on the asset IP field you would like to make changes

The services associated to the asset will be displayed, you can also see how many vulnerabilites again each service

"},{"location":"Assets-and-Services-v4/#create-a-service","title":"Create a Service","text":"

From the Services window, click New and fill out the form Name, Port and Protocol fields are mandatory

"},{"location":"Assets-and-Services-v4/#edit-a-service","title":"Edit a Service","text":"

From the Services window, select the service and click Edit

"},{"location":"Backup-v4/","title":"Backup","text":"

Saving backups is always a good choice, whether it is to keep data safe or to share with others.

"},{"location":"Backup-v4/#faraday-configuration-and-evidence-backup","title":"Faraday configuration and evidence backup","text":"

Faraday server stores configuration, processed reports and saves evidence in the directory /home/faraday/.faraday. Remember to do a backup of this directory of the user running faraday-server.

"},{"location":"Backup-v4/#database-backup","title":"Database backup","text":"

In order to create a backup for your database, follow these steps:

  1. Stop Faraday Server.

    sudo service faraday-service stop\n

  2. In order to backup your Faraday database, execute the PostgreSQL tool:

    sudo pg_dump faraday > backup_file\n

  3. Where faraday is the default name of Faraday's database and backup_file is the file where the pg_dump will save your data.

  4. Start the Faraday Server

    sudo service faraday-service start\n

"},{"location":"Backup-v4/#database-restore","title":"Database restore","text":"

To restore a previously created backup turn again Faraday Server off and execute:

sudo service faraday-service stop\nsudo psql faraday < backup_file\nsudo service faraday-service start\n

Remember To restore the backup you need to have the database empty.

For more information about PostgreSQL Backup follow this link

"},{"location":"Basic-plugin-development/","title":"Plugin Development","text":"

In this guide we are going to learn how to develop a new plugin for Faraday.

"},{"location":"Basic-plugin-development/#configure-custom-plugins","title":"Configure Custom Plugins","text":"

To add custom plugins in faraday, you first need to run this command:

faraday-manage settings -a update reports\n
"},{"location":"Basic-plugin-development/#create-plugin-structure","title":"Create Plugin structure","text":"

Create the folder new_plugin inside the custom_plugins folder and add the following files inside the new_plugin folder:

Plugin Structure:

new_plugin/\n    __init__.py # leave this file empty\n    plugin.py\n

Warning

Please respect both file names: __init__.py and plugin.py

"},{"location":"Basic-plugin-development/#plugin-code","title":"Plugin code","text":"

There are two types of plugins:

  • File plugins (plugins that process the contents of a file)
  • Command plugins (plugins that process the execution of a command)

A faraday plugin can be either or both of these types. For example the ping plugin only process the execution of the command, but the nmap command supports both the xml generated by nmap or process the execution of nmap.

In your plugin.py file you must provide a function called createPlugin for the plugin manager to instantiate the plugin

def createPlugin(ignore_info=False, hostname_resolution=True):\n    return YourPluginClass(ignore_info=ignore_info)\n
"},{"location":"Basic-plugin-development/#plugin-classes","title":"Plugin classes","text":"

PluginBase is the base class.

For File plugins we provide all this classes. But you can add other by creating a subclass of PluginByExtension

  • PluginBase
  • PluginByExtension
    • PluginXMLFormat
    • PluginJsonFormat
    • PluginMultiLineJsonFormat
    • PluginCSVFormat
    • PluginZipFormat

For Command plugins only you must inherit from PluginBase

Your plugin class __init__ method must define the id, that will be the identifier of your plugin.

Here's an example of the Ping tool plugin:

class CmdPingPlugin(PluginBase):\n    def __init__(self, *arg, **kwargs):\n        super().__init__(*arg, **kwargs)\n            self.id = \"ping\"\n            self.name = \"Ping\"\n            self.plugin_version = \"0.0.1\"\n            self.version = \"1.0.0\"\n            self._command_regex = re.compile(r'^(sudo ping|ping|sudo ping6|ping6)\\s+.*?')\n

Beware that it must be unique, you can list all the plugins identifiers with this command: faraday-plugins list-plugins

"},{"location":"Basic-plugin-development/#file-plugins","title":"File Plugins","text":"

Each of the subclasses for File plugins provide a different way for the plugin to detect if it can process the file

"},{"location":"Basic-plugin-development/#pluginbyextension","title":"PluginByExtension:","text":"

This class adds the functionality for identify a file by its extension by setting the attribute extension.

It can be one extension (\".xml\") or a list (['.xml', '.xxx']) if your file can have multiple extensions.

You never inherit directly from this class in a plugin but from some of its subclasses that are more specific.

class ExampleXMLTool(PluginByExtension):\n\n        def __init__(self):\n            super().__init__()\n            self.extension = \".xml\"\n
"},{"location":"Basic-plugin-development/#pluginxmlformat","title":"PluginXMLFormat:","text":"

Use this class if the plugin generates vulnerabilities from a xml file.

If your report has xml format but a different extension (like nessus), remember to define the extension attribute

To identify the file set in the identifier_tag attribute the main tag of the xml (ScanGroup in the example), it also can be one tag or a list of tags.

You can also set the identifier_tag_attributes attribute, it is a set of attributes that the main tag must have.

This is used to be more specific for example if the main tag is too generic and the xml of other plugin has the same one.

Example XML

<?xml version=\"1.0\"?>\n<ScanGroup ExportedOn=\"2021-11-05T11:18:57.673843\">\n    <Scan>\n    </Scan>\n</ScanGroup>\n

from urllib.parse import urlparse\nfrom faraday_plugins.plugins.plugin import PluginXMLFormat\nimport xml.etree.ElementTree as ET\n\nclass ExampleToolXmlParser:\n\n    def __init__(self, xml_output):\n        self.vulns = self.parse_xml(xml_output)\n\n    def parse_xml(self, xml_output):\n        vulns = []\n        tree = ET.fromstring(xml_output)\n        items = tree.iterfind('details/item')\n        for item in items:\n            ip = item.get('ip')\n            os = item.get('os')\n            uri = item.find('uri').text\n            url = urlparse(uri)\n            hostname = [url.netloc]\n            path = url.path\n            if url.scheme == 'https':\n                port = 443\n            else:\n                port = 80\n            issue = item.find('issue')\n            severity = issue.get('severity')\n            issue_text = issue.text\n            vuln = {'ip': ip, 'uri': uri, 'os': os,\n                    'hostname': hostname, 'port': port, 'path': path,\n                    'issue_text': issue_text, 'severity': severity}\n            vulns.append(vuln)\n        return vulns\n\n\nclass ExampleToolPlugin(PluginXMLFormat):\n    def __init__(self, *arg, **kwargs):\n        super().__init__(*arg, **kwargs)\n        self.identifier_tag = \"example_tool\"\n        self.id = \"example_tool\"\n        self.name = \"Name of the tool\"\n        self.plugin_version = \"0.0.1\"\n\n    def parseOutputString(self, output, debug=False):\n        parser = ExampleToolXmlParser(output)\n        for vuln in parser.vulns:\n            h_id = self.createAndAddHost(vuln['ip'], vuln['os'], hostnames=vuln['hostname'])\n            s_id = self.createAndAddServiceToHost(h_id, 'webserver', protocol='tcp', ports=vuln['port'])\n            v_id = self.createAndAddVulnWebToService(h_id, s_id, vuln['issue_text'], severity=vuln['severity'],\n                                                    path=vuln['path'])\n\ndef createPlugin(*args, **kwargs):\n    return ExampleToolPlugin(*args, **kwargs)\n
"},{"location":"Basic-plugin-development/#pluginjsonformat","title":"PluginJsonFormat:","text":"

Use this class if the plugin generates vulnerabilities from a json file.

If yor report has json format but a different extension (not .json), remember to define the extension attribute

To identify the file set in the json_keys attribute a set with some identifiers keys of the json object

Example JSON

{\n  \"name\": \"some name\",\n  \"hosts\": [\"host1\", \"host2\"],\n  \"other_field\": \"some value\"\n}\n

class ExampleJsonTool(PluginJsonFormat):\n    def __init__(self, ignore_info):\n        super().__init__(ignore_info)\n        self.json_keys = {'name', 'hosts'}\n
"},{"location":"Basic-plugin-development/#pluginmultilinejsonformat","title":"PluginMultiLineJsonFormat:","text":"

Is the same as PluginJsonFormat but use it when the file has multiple lines and every line is a json.

Example JSON

{ \"name\": \"some name\", \"hosts\": [\"host1\", \"host2\"],\"other_field\": \"some value\"}\n{ \"name\": \"other name\", \"hosts\": [\"host3\", \"host4\"],\"other_field\": \"other value\"}\n

class ExampleMultipleJsonTool(PluginMultiLineJsonFormat):\n    def __init__(self, ignore_info):\n        super().__init__(ignore_info)\n        self.json_keys = {'name', 'hosts'}\n
"},{"location":"Basic-plugin-development/#plugincsvformat","title":"PluginCSVFormat:","text":"

Use this class if the plugin generates vulnerabilities from a csv file.

If yor report has csv format but a different extension (not .csv), remember to define the extension attribute

To identify the file set in the csv_headers attribute a set with some identifiers headers of the csv object

Example CSV

name,ip,os\nhost1,10.10.10.10,windows\nhost2,10.10.10.11,linux\n

class ExampleCSVTool(PluginCSVFormat):\n    def __init__(self, ignore_info):\n        super().__init__(ignore_info)\n        self.json_keys = {'name', 'ip'}\n
"},{"location":"Basic-plugin-development/#pluginzipformat","title":"PluginZipFormat:","text":"

Use this class if the plugin generates vulnerabilities from a zip file.

If yor report has csv format but a different extension (not .zip), remember to define the extension attribute

To identify the file set in the files_list attribute a set with some file names inside the zip file.

class ExampleJsonTool(PluginZipFormat):\n    def __init__(self, ignore_info):\n        super().__init__(ignore_info)\n        self.files_list = {'file1.txt', 'file2.txt'}\n
"},{"location":"Basic-plugin-development/#generating-data","title":"Generating data","text":"

The PluginBase class give you all the main methods to create hosts, services and vulnerabilities

After you parse the data you will need to create the objects with the information to send to faraday. This are the main methods

def createAndAddHost(self, name, os=\"unknown\", hostnames=None, mac=None, scan_template=\"\", site_name=\"\",\n                    site_importance=\"\", risk_score=\"\", fingerprints=\"\", fingerprints_software=\"\"):\n\ndef createAndAddServiceToHost(self, host_id, name, protocol=\"tcp?\", ports=None, status=\"open\", version=\"unknown\",\n                            description=\"\"):\n\ndef createAndAddVulnToHost(self, host_id, name, desc=\"\", ref=None, severity=\"\", resolution=\"\", vulnerable_since=\"\", \n                            scan_id=\"\", pci=\"\", data=\"\", external_id=None, run_date=None):\n\ndef createAndAddVulnToService(self, host_id, service_id, name, desc=\"\", ref=None, severity=\"\", resolution=\"\", \n                            risk=\"\", data=\"\", external_id=None, run_date=None):\n\ndef createAndAddVulnWebToService(self, host_id, service_id, name, desc=\"\", ref=None, severity=\"\", resolution=\"\",\n                                website=\"\", path=\"\", request=\"\", response=\"\", method=\"\", pname=\"\",\n                                params=\"\", query=\"\", category=\"\", data=\"\", external_id=None, run_date=None):\n

createAndAddHost and createAndAddServiceToHost will give you a host ID and a service ID. You need to send those to the create vulnerabilities methods

The main method to parse data and create the vulnerabilities objects is parseOutputString, no mather if is a File or a Command plugin.

"},{"location":"Basic-plugin-development/#command-plugins","title":"Command Plugins","text":"

For command plugins the detection is done via regex.

If the plugin is only for command you inherit from PluginBase if it also will support file detection inherit from the appropriate class for that type of file.

In both cases to detect a command you will need to set the _command_regex attribute with the regex to match the command

Here's an example of the Ping tool plugin:

class CmdPingPlugin(PluginBase):\n    def __init__(self, *arg, **kwargs):\n        super().__init__(*arg, **kwargs)\n            self.id = \"ping\"\n            self.name = \"Ping\"\n            self.plugin_version = \"0.0.1\"\n            self.version = \"1.0.0\"\n            self._command_regex = re.compile(r'^(sudo ping|ping|sudo ping6|ping6)\\s+.*?')\n\n    def parseOutputString(self, output):\n        reg = re.search(r\"PING ([\\w\\.-:]+)( |)\\(([\\w\\.:]+)\\)\", output)\n        if re.search(\"0 received|unknown host\", output) is None and reg is not None:\n            ip_address = reg.group(3)\n            hostname = reg.group(1)\n            self.createAndAddHost(ip_address, hostnames=[hostname])\n        return True\n\n    def _isIPV4(self, ip):\n        if len(ip.split(\".\")) == 4:\n            return True\n        else:\n            return False\n

In this case the plugin manager will run the command and send the output to the parseOutputString method.

But if the tool generate an ouput file instead of send the data to stdout you will need to check that the command has the required parameters to do that.

To do that you will need to implement the processCommandString method, by default it will return the command without modifications.

To use output files you will need to set 2 attributes in you plugin: _use_temp_file and _temp_file_extension

If _use_temp_file is set the plugin will create a temp file and assign its path to the attribute self._output_file_path of the plugin.

If you need that the temp file has and specific extension use the _temp_file_extension attribute like in the example.

If the _use_temp_file attribute is set the plugin will send te content of that file to parseOutputString()instead of the output of the command.

Here is and extract of the nmap plugin to see how processCommandString will modify the original command and return a new command with the required parameters.

class NmapPlugin(PluginXMLFormat):\n    \"\"\"\n    Example plugin to parse nmap output.\n    \"\"\"\n\n    def __init__(self, *arg, **kwargs):\n        super().__init__(*arg, **kwargs)\n        self.identifier_tag = \"nmaprun\"\n        self.id = \"Nmap\"\n        self.name = \"Nmap XML Output Plugin\"\n        self.plugin_version = \"0.0.3\"\n        self.version = \"6.40\"\n        self.framework_version = \"1.0.0\"\n        self.options = None\n        self._current_output = None\n        self._command_regex = re.compile(r'^(sudo nmap|nmap|\\.\\/nmap)\\s+.*?')\n        self._use_temp_file = True\n        self._temp_file_extension = \"xml\"\n        self.xml_arg_re = re.compile(r\"^.*(-oX\\s*[^\\s]+).*$\")\n        self.addSetting(\"Scan Technique\", str, \"-sS\")\n\n    def parseOutputString(self, output):\n        ...\n\n    def processCommandString(self, username, current_path, command_string):\n        \"\"\"\n        Adds the -oX parameter to get xml output to the command string that the\n        user has set.\n        \"\"\"\n        super().processCommandString(username, current_path, command_string)\n        arg_match = self.xml_arg_re.match(command_string)\n        if arg_match is None:\n            return re.sub(r\"(^.*?nmap)\",\n                          r\"\\1 -oX %s\" % self._output_file_path,\n                          command_string)\n        else:\n            return re.sub(arg_match.group(1),\n                          r\"-oX %s\" % self._output_file_path,\n                          command_string)\n
"},{"location":"Basic-plugin-development/#full-example","title":"Full Example","text":"File Plugin from XML

This is an example of a Faraday Plugin that process a xml report.

In this example we will create a plugin to analyze this XML provided by the output of a tool.

example.xml

 <?xml version=\"1.0\" ?>\n<!DOCTYPE example_tool>\n<example_tool scanstart=\"Thu Nov  9 15:59:13 2017\">\n    <details>\n    <item id=\"999979\" ip=\"10.23.49.232\" os=\"linux\">\n    <uri>http://test.com/example.php</uri>\n    <issue severity=\"low\">Some vuln text</issue>\n    </item>\n    <item id=\"39023023\" ip=\"10.232.62.20\" os=\"linux\">\n    <uri>http://test.com/login.php</uri>\n    <issue severity=\"low\">Some other text</issue>\n    </item>\n    <item id=\"8348343\" ip=\"10.12.37.24\" os=\"linux\">\n    <uri>http://test.com/example.php</uri>\n    <issue severity=\"low\">Yet another vuln text</issue>\n    </item>\n    <statistics elapsed=\"402\" itemsfound=\"3\" itemstested=\"10\" />\n    </details>\n</example_tool>\n

plugin.py

from urllib.parse import urlparse\nfrom faraday_plugins.plugins.plugin import PluginXMLFormat\nimport xml.etree.ElementTree as ET\n\nclass ExampleToolXmlParser:\n\n    def __init__(self, xml_output):\n        self.vulns = self.parse_xml(xml_output)\n\n    def parse_xml(self, xml_output):\n        vulns = []\n        tree = ET.fromstring(xml_output)\n        items = tree.iterfind('details/item')\n        for item in items:\n            ip = item.get('ip')\n            os = item.get('os')\n            uri = item.find('uri').text\n            url = urlparse(uri)\n            hostname = [url.netloc]\n            path = url.path\n            if url.scheme == 'https':\n                port = 443\n            else:\n                port = 80\n            issue = item.find('issue')\n            severity = issue.get('severity')\n            issue_text = issue.text\n            vuln = {'ip': ip, 'uri': uri, 'os': os,\n                    'hostname': hostname, 'port': port, 'path': path,\n                    'issue_text': issue_text, 'severity': severity}\n            vulns.append(vuln)\n        return vulns\n\n\nclass ExampleToolPlugin(PluginXMLFormat):\n    def __init__(self):\n        super().__init__()\n        self.identifier_tag = \"example_tool\"\n        self.id = \"example_tool\"\n        self.name = \"Name of the tool\"\n        self.plugin_version = \"0.0.1\"\n\n    def parseOutputString(self, output, debug=False):\n        parser = ExampleToolXmlParser(output)\n        for vuln in parser.vulns:\n            h_id = self.createAndAddHost(vuln['ip'], vuln['os'], hostnames=vuln['hostname'])\n            s_id = self.createAndAddServiceToHost(h_id, 'webserver', protocol='tcp', ports=vuln['port'])\n            v_id = self.createAndAddVulnWebToService(h_id, s_id, vuln['issue_text'], severity=vuln['severity'],\n                                                    path=vuln['path'])\n\ndef createPlugin(ignore_info=False, hostname_resolution=True):\n    return ExampleToolXmlParser(ignore_info=ignore_info)\n
"},{"location":"Basic-plugin-development/#test-and-debug","title":"Test and Debug","text":"

You can test your plugin by enabling the custom_plugins_folder setting, and try it with faraday.

You can also test your plugin from the command line.

"},{"location":"Basic-plugin-development/#test-plugins","title":"Test Plugins","text":"

List all available plugins

Verify that the plugins is loaded by the plugin manager

faraday-plugins list-plugins\n\nAvailable Plugins:\n...\n...\n...\nexample_tool - Name of the tool\nLoaded Plugins: 84\n

Test plugin report detection

Verify that your file is detected by your plugin

faraday-plugins detect-report /path/to/report.xml\n\nPlugin: example_tool\n

Test plugin process report

Verify that your plugin parses the file ok and generate the json structure that will be loaded into faraday

faraday-plugins process-report /path/to/report.xml\n\n\n{\"hosts\": [{\"ip\": \"10.23.49.232\", \"os\": \"linux\", \"hostnames\": [\"test.com\"], \"description\": \"\", \"mac\": null, \"credentials\": [], \"services\": [{\"name\": \"webserver\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"unknown\", \"description\": \"\", \"credentials\": [], \"vulnerabilities\": [{\"name\": \"Some vuln text\", \"desc\": \"\", \"severity\": \"low\", \"refs\": [], \"external_id\": null, \"type\": \"VulnerabilityWeb\", \"resolution\": \"\", \"data\": \"\", \"website\": \"\", \"path\": \"/example.php\", \"request\": \"\", \"response\": \"\", \"method\": \"\", \"pname\": \"\", \"params\": \"\", \"query\": \"\", \"category\": \"\"}]}], \"vulnerabilities\": [], \"scan_template\": \"\", \"site_name\": \"\", \"site_importance\": \"\", \"risk_score\": \"\", \"fingerprints\": \"\", \"fingerprints_software\": \"\"}, {\"ip\": \"10.232.62.20\", \"os\": \"linux\", \"hostnames\": [\"test.com\"], \"description\": \"\", \"mac\": null, \"credentials\": [], \"services\": [{\"name\": \"webserver\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"unknown\", \"description\": \"\", \"credentials\": [], \"vulnerabilities\": [{\"name\": \"Some other text\", \"desc\": \"\", \"severity\": \"low\", \"refs\": [], \"external_id\": null, \"type\": \"VulnerabilityWeb\", \"resolution\": \"\", \"data\": \"\", \"website\": \"\", \"path\": \"/login.php\", \"request\": \"\", \"response\": \"\", \"method\": \"\", \"pname\": \"\", \"params\": \"\", \"query\": \"\", \"category\": \"\"}]}], \"vulnerabilities\": [], \"scan_template\": \"\", \"site_name\": \"\", \"site_importance\": \"\", \"risk_score\": \"\", \"fingerprints\": \"\", \"fingerprints_software\": \"\"}, {\"ip\": \"10.12.37.24\", \"os\": \"linux\", \"hostnames\": [\"test.com\"], \"description\": \"\", \"mac\": null, \"credentials\": [], \"services\": [{\"name\": \"webserver\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"unknown\", \"description\": \"\", \"credentials\": [], \"vulnerabilities\": [{\"name\": \"Yet another vuln text\", \"desc\": \"\", \"severity\": \"low\", \"refs\": [], \"external_id\": null, \"type\": \"VulnerabilityWeb\", \"resolution\": \"\", \"data\": \"\", \"website\": \"\", \"path\": \"/example.php\", \"request\": \"\", \"response\": \"\", \"method\": \"\", \"pname\": \"\", \"params\": \"\", \"query\": \"\", \"category\": \"\"}]}], \"vulnerabilities\": [], \"scan_template\": \"\", \"site_name\": \"\", \"site_importance\": \"\", \"risk_score\": \"\", \"fingerprints\": \"\", \"fingerprints_software\": \"\"}], \"command\": {\"tool\": \"example_tool\", \"command\": \"example_tool\", \"params\": \"/path/to/report.xml\", \"user\": \"faraday\", \"hostname\": \"\", \"start_date\": \"2020-04-01T18:43:34.552623\", \"duration\": 2650, \"import_source\": \"report\"}}\n

You can optionally specify the plugin id to not do the detection step and force to process it with the specific plugin

faraday-plugins process-report --plugin_id YourPluginId /path/to/report.xml\n\n\n{\"hosts\": [{\"ip\": \"10.23.49.232\", \"os\": \"linux\", \"hostnames\": [\"test.com\"], \"description\": \"\", \"mac\": null, \"credentials\": [], \"services\": [{\"name\": \"webserver\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"unknown\", \"description\": \"\", \"credentials\": [], \"vulnerabilities\": [{\"name\": \"Some vuln text\", \"desc\": \"\", \"severity\": \"low\", \"refs\": [], \"external_id\": null, \"type\": \"VulnerabilityWeb\", \"resolution\": \"\", \"data\": \"\", \"website\": \"\", \"path\": \"/example.php\", \"request\": \"\", \"response\": \"\", \"method\": \"\", \"pname\": \"\", \"params\": \"\", \"query\": \"\", \"category\": \"\"}]}], \"vulnerabilities\": [], \"scan_template\": \"\", \"site_name\": \"\", \"site_importance\": \"\", \"risk_score\": \"\", \"fingerprints\": \"\", \"fingerprints_software\": \"\"}, {\"ip\": \"10.232.62.20\", \"os\": \"linux\", \"hostnames\": [\"test.com\"], \"description\": \"\", \"mac\": null, \"credentials\": [], \"services\": [{\"name\": \"webserver\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"unknown\", \"description\": \"\", \"credentials\": [], \"vulnerabilities\": [{\"name\": \"Some other text\", \"desc\": \"\", \"severity\": \"low\", \"refs\": [], \"external_id\": null, \"type\": \"VulnerabilityWeb\", \"resolution\": \"\", \"data\": \"\", \"website\": \"\", \"path\": \"/login.php\", \"request\": \"\", \"response\": \"\", \"method\": \"\", \"pname\": \"\", \"params\": \"\", \"query\": \"\", \"category\": \"\"}]}], \"vulnerabilities\": [], \"scan_template\": \"\", \"site_name\": \"\", \"site_importance\": \"\", \"risk_score\": \"\", \"fingerprints\": \"\", \"fingerprints_software\": \"\"}, {\"ip\": \"10.12.37.24\", \"os\": \"linux\", \"hostnames\": [\"test.com\"], \"description\": \"\", \"mac\": null, \"credentials\": [], \"services\": [{\"name\": \"webserver\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"unknown\", \"description\": \"\", \"credentials\": [], \"vulnerabilities\": [{\"name\": \"Yet another vuln text\", \"desc\": \"\", \"severity\": \"low\", \"refs\": [], \"external_id\": null, \"type\": \"VulnerabilityWeb\", \"resolution\": \"\", \"data\": \"\", \"website\": \"\", \"path\": \"/example.php\", \"request\": \"\", \"response\": \"\", \"method\": \"\", \"pname\": \"\", \"params\": \"\", \"query\": \"\", \"category\": \"\"}]}], \"vulnerabilities\": [], \"scan_template\": \"\", \"site_name\": \"\", \"site_importance\": \"\", \"risk_score\": \"\", \"fingerprints\": \"\", \"fingerprints_software\": \"\"}], \"command\": {\"tool\": \"example_tool\", \"command\": \"example_tool\", \"params\": \"/path/to/report.xml\", \"user\": \"faraday\", \"hostname\": \"\", \"start_date\": \"2020-04-01T18:43:34.552623\", \"duration\": 2650, \"import_source\": \"report\"}}\n

If you do not have faraday-server installed or don't have the custom_plugins_folder setting, you can use the --custom_plugins_folder parameter with any if the commands (list, detect and process)

Example:

faraday-plugins list-plugins --custom-plugins-folder /home/user/.faraday/plugins/\n
"},{"location":"Basic-plugin-development/#logging","title":"Logging","text":"

In the PluginBase there is a logger defined in self.logger that you can use.

If you need to debug for plugins with the command line set this variable:

export PLUGIN_DEBUG=1\nfaraday-plugins process-report appscan /path/to/report.xml\n2019-11-15 20:37:03,355 - faraday.faraday_plugins.plugins.manager - INFO [manager.py:113 - _load_plugins()]  Loading Native Plugins...\n2019-11-15 20:37:03,465 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [acunetix]\n2019-11-15 20:37:03,495 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [amap]\n2019-11-15 20:37:03,549 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [appscan]\n2019-11-15 20:37:03,580 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [arachni]\n2019-11-15 20:37:03,613 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [arp_scan]\n2019-11-15 20:37:03,684 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [beef]\n2019-11-15 20:37:03,714 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [brutexss]\n2019-11-15 20:37:03,917 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [burp]\n2019-11-15 20:37:03,940 - faraday.faraday_plugins.plugins.manager - DEBUG [manager.py:123 - _load_plugins()]  Load Plugin [dig]\n...\n
"},{"location":"Burp-proxy-extender/","title":"Burp","text":"

This plugin is a script developed in Java as a extender to the Burp Proxy API (Pro/Community).

"},{"location":"Burp-proxy-extender/#installation","title":"Installation","text":""},{"location":"Burp-proxy-extender/#from-the-app-store","title":"From the App Store","text":"

You can install the Burp extension from the Burp App Store

"},{"location":"Burp-proxy-extender/#from-file","title":"From file","text":"

Download the jar from this link

Once you have it, follow these steps:

  • Go to Extender->Extensions and click in the Add button.

  • In the Extension Details section, the extension type should be Java, and select the file.

  • Click Next, and if everything went well, you should see no errors and you can close the window.

  • Now, make sure the extension is loaded in the Extensions tab.

"},{"location":"Burp-proxy-extender/#extension-configuration","title":"Extension configuration","text":"

Once the Faraday extension is loaded into your Burp, you will see a new tab called \"Faraday\".

Here, you can login to Faraday and you can edit the extension's settings:.

"},{"location":"Burp-proxy-extender/#login-to-faraday","title":"Login to Faraday","text":"

In order to connect the Faraday's Burp extension to Faraday, follow these steps:

1) Set your Faraday Server URL. This should point to the same URL that you use when you are connecting to Faraday Server, e.g: http://127.0.0.1:5985

2) Connect Burp to Faraday by clicking on the Connect button.

3) Once you are connected, type your Faraday's credentials: username, password and 2FA Token (if it is the case).

4) Login into Faraday by click on the Login button. If everything goes well, Burp should pop up a Login successful! modal.

5) Once you are logged in, you can edit the extension's settings.

"},{"location":"Burp-proxy-extender/#extension-settings","title":"Extension Settings","text":"

From here, you can:

1) Choose the workspace where you want to work on.

2) Choose whether the vulnerabilities should be imported automatically or not (it's disabled by default).

3) Import the vulnerabilities you've found so far.

4) Check if you want to use only Burp scope.

"},{"location":"Burp-proxy-extender/#send-to-faraday","title":"Send to Faraday","text":"

Once you have everything setup, you can send the issues or requests to Faraday.

!!! warning \"REMEMBER: If the request is missing the response, the information can't be sent to faraday! REMEMBER 2: Vulnerabilities will only work with commercial versions of burp\"

"},{"location":"Burp-proxy-extender/#other-settings","title":"Other Settings","text":"

From here, you can Restore Settings to default.

"},{"location":"Comments/","title":"Comments & Notifications","text":"

Now, you can enrich Vuln data by leaving Comments and Notes, while mentioning other users to notify them about important events in real time. Also, you are now able to configure alerts to follow up on each project, having a more efficient view of their status and updates.

The idea behind this is promoting better ways to get involved with your co-workers by improving communication and daily results.

Usage Go into the vulnerability preview (by clicking in the name of the vulnerability). Then click on Comments tab:

"},{"location":"Contact-us/","title":"Contact Us","text":"

More info about Faraday at faradaysec.com

"},{"location":"Contact-us/#frequently-asked-questions","title":"Frequently Asked Questions","text":"

Visit our [[FAQ]] to know the answer to common questions

"},{"location":"Contact-us/#troubleshooting","title":"Troubleshooting","text":"

Having problems with Faraday? That's weird! Try our [Troubleshooting] guide.

"},{"location":"Contact-us/#issue-tracker","title":"Issue tracker","text":"

Not satisfied? Having troubles? Want to cheer us? Open a ticket!

"},{"location":"Contact-us/#our-community","title":"Our community","text":"

You can reach us and find other Faraday users on: Open an Issue

"},{"location":"Contact-us/#twitter","title":"Twitter","text":"

http://twitter.com/faradaysec

"},{"location":"Custom-Fields-v4/","title":"Custom Attributes","text":"

Custom Attributes allow you to extend the vulnerability's model with more fields. Custom attributes type can be int, string, choice, date, markdown and list.

If you want to learn more about the usage of Custom Attributes through Faraday's API, follow this link.

"},{"location":"Custom-Fields-v4/#how-to-create-custom-attributes","title":"How to create Custom Attributes","text":""},{"location":"Custom-Fields-v4/#from-web-ui","title":"From Web UI","text":"

You can create/edit/delete a Custom Attribute clicking in the Custom Attributes button from the Column Order icon.

Let's create one as an example:

  • You must fill the following fields in order to create a Custom Attribute:

    • name: the display name that you will see on the vulnerability form.
    • Type: data type of the field.

  • After successfully creating the Custom Attribute, you will see it on the vulnerability form:

"},{"location":"Custom-Fields-v4/#from-terminal-local-install-only","title":"From Terminal (local install only)","text":"

Step 1: Add custom attribute

$ faraday-manage add-custom-field \n

Step 2: After the command execution, you will be prompted by a wizard where you must input the following information:

  • Field name: the name of the field.
  • Display name: the display name that you will see on the vulnerability form.
  • Type: data type of the field, it can be: int, string, choice, markdown and list.
  • Order: the order shown on the vulnerability form.

The following example will add the CVSS field to the vulnerability model:

This wizard will guide you to ADD custom attributes to the vulneraiblity model.\nField name: cvss\nDisplay name: CVSS\nField type (int, str, list) (int, str, list): str\nField order index: 0\nNew CustomField will be added to vulnerability -> Order 0 (cvss,CVSS,str) <-, confirm to continue (yes/no): yes\n
"},{"location":"Dashboard-v4/","title":"Dashboard","text":"

Faraday's Dashboard contains a summary of all data within a Workspace. Each box is a visualization for an specific aspect of the collected information.

When you create a new Workspace an empty dashboard will look as below

Once you start adding data by importing scans, running tools, etc, it will be like this

Let's see in more detail the functionality and information displayed in the dashboard

"},{"location":"Dashboard-v4/#switching-workspaces","title":"Switching Workspaces","text":"

Top left corner next to F you can see the current Workspace, click on it and a drop-list will be displayed to switch between Workspace quickly

"},{"location":"Dashboard-v4/#progress-and-vulnerabilities-distributioncounters","title":"Progress and Vulnerabilities Distribution/Counters","text":"

Percentage of time spend using Workspace settings (start/end date) and pie charts for vulnerabilies by Severity and Status also total counters of vulnerabilities by Severity included

"},{"location":"Dashboard-v4/#activity-feed","title":"Activity Feed","text":"

Users and actions with results performed on the workspace for quickly seeing the progress been made on the workspace

"},{"location":"Dashboard-v4/#last-vulnerabilities","title":"Last Vulnerabilities","text":"

Quick list of latest vulnerabilities added into the workspace

"},{"location":"Dashboard-v4/#service-report","title":"Service Report","text":"

A counter view of Services found in the workspace

"},{"location":"Dashboard-v4/#workspace-summary","title":"Workspace Summary","text":"

An overall summary of Hosts, Services and Vulnerabilties found so far

"},{"location":"Dashboard-v4/#hosts","title":"Hosts","text":"

List of Assets and Vulnerabilities currently in the workspace.

"},{"location":"Dashboard-v4/#tags","title":"Tags","text":"

View of the recent used tags.

"},{"location":"Development-setup/","title":"Development setup","text":""},{"location":"Development-setup/#to-use-faraday-follow-the-new-faraday-install-guide-this-is-for-development","title":"To use faraday follow the new Faraday Install Guide. This is for development","text":""},{"location":"Development-setup/#index","title":"Index","text":"
  • Server
  • Client
"},{"location":"Development-setup/#topics","title":"Topics","text":""},{"location":"Development-setup/#faraday-server","title":"Faraday Server","text":"

Faraday Server is the interface between PostgreSQL and Faraday Client and WebUI. The server's responsibility is to transmit information between the client or WebUI and PostgreSQL, and make sure that they are kept in sync. The Web UI client, which allows you to handle enormous workspaces from your favorite web browser.

Important: You should keep in mind that is recommended to install Faraday server on the same instance as PostgreSQL.

"},{"location":"Development-setup/#downloading","title":"Downloading","text":"

Clone the Faraday Git Project repository and checkout the dev branch:

$ git clone https://github.com/infobyte/faraday.git faraday-dev\n$ cd faraday-dev\n$ pip install .\n

After doing so, make sure to install system dependencies, install Python dependencies and configure the Server.

"},{"location":"Development-setup/#requirements","title":"Requirements","text":"

Faraday Server is built with minimum requirements. This is by design, so you can install it even on the most bare-bones machine you can possibly imagine.

The Python requirements for the server are stored in the requirements.

"},{"location":"Development-setup/#installing-system-dependencies","title":"Installing system dependencies","text":""},{"location":"Development-setup/#debian-based-distributions-debian-ubuntu-backtrack-etc","title":"Debian based distributions (Debian, Ubuntu, Backtrack, etc)","text":"

Or if you wanna do it manually you can run the following command to install the required dependencies on any Debian based distribution.

$ sudo apt update\n\n$ sudo apt install build-essential ipython python3-setuptools \\\n                python3-pip python3-dev libssl-dev \\\n                libffi-dev pkg-config libxml2-dev \\\n                libxslt1-dev libfreetype6-dev libpng-dev postgresql libpq-dev\n
Warning: If you already have postgresql installed, please corroborate the version is upper than 9.4.

"},{"location":"Development-setup/#kali-linux","title":"Kali Linux","text":"

If you are running Kali, please run the following commands:

$ sudo apt-get update\n$ sudo apt-get install build-essential ipython python-setuptools \\\n                python-pip python-dev libssl-dev \\\n                libffi-dev pkg-config libxml2-dev \\\n                libxslt1-dev libfreetype6-dev libpng-dev\n
"},{"location":"Development-setup/#others","title":"Others","text":"

Please consult with your distribution documentation to install the dependencies listed above.

"},{"location":"Development-setup/#creating-a-virtualenv","title":"Creating a virtualenv","text":"

Before installing Faraday, we need to create a virtualenv so Faraday runs in it. In order to install and create a virtualenv, run the following commands:

$ pip install virtualenv\n$ virtualenv -p python3 faraday_venv\n$ source faraday_venv/bin/activate\n

For more information about virtualenv, please follow this link.

"},{"location":"Development-setup/#installing-python-3-dependencies","title":"Installing Python 3 dependencies","text":"

Once you have the required system dependencies, you just have to install the Python modules needed to run the server using:

$ python setup.py develop\n

"},{"location":"Development-setup/#initializing-postgresql","title":"Initializing PostgreSQL","text":"

In order to initialize PostgreSQL database, run the following command:

faraday-manage initdb\n

IMPORTANT: The command initdb will create a random password for the admin user, remeber to COPY THE PASSWORD. You can use the command faraday-manage change-password if you want to change it.

Note: You sould have the PostgreSQL service started. To do it run systemctl start postgresql or the equivalant command for your GNU/Linux distro.

Note: if at the moment you run this command, it throws an error, be sure you have sudo installed. Once you have installed it, run the command again.

"},{"location":"Development-setup/#manual-postgresql-configuration","title":"Manual PostgreSQL configuration","text":"

If you need an advance configuration of the postgres database, like having a custom database name or run it in a separate host, the faraday-manage initdb command probably won't be enough for you, so you should configure it manually by doing something like this:

sudo -u postgres psql -c \"CREATE ROLE faraday_postgresql WITH LOGIN PASSWORD 'YOURPASSWORD'\"\nsudo -u postgres createdb -O faraday_postgresql faraday\n

Then, edit the ~/.faraday/config/server.ini by adding the connection string to the database:

[database]\nconnection_string = postgresql+psycopg2://faraday_postgresql:YOURPASSWORD@localhost/faraday\n

Then you should run faraday-manage create-tables to create all the required tables to make faraday work, and faraday-manage createsuperuser to create an admin user.

"},{"location":"Development-setup/#manually-importing-from-couchdb","title":"Manually importing from CouchDB","text":"

If you were using Faraday 2.7.2 and setup the database manually instead of using the faraday-manage initdb, you should run the following command to import the data from CouchDB:

$ python manage.py import-from-couchdb\n
"},{"location":"Development-setup/#updating-nginx-configuration","title":"Updating Nginx configuration","text":"

Note: This only applies if you are using Nginx and https.

Please, make sure you have this settings on your Nginx config:

proxy_pass http://localhost:5985/;\nproxy_redirect http:// $scheme://;\n
"},{"location":"Development-setup/#configuration","title":"Configuration","text":"

By default, Faraday server will listen on port 5985. You can edit this on ~/.faraday/config/server.ini.

"},{"location":"Development-setup/#exposing-the-server","title":"Exposing the Server","text":"

If you wish to access the Server form a different box you need to expose the service. In order to do so, edit the server configuration file and set the bind_address param to 0.0.0.0.

Edit the file located in ~/.faraday/config/server.ini and under the section [faraday-server] set the param, it should look something like this:

[faraday-server]\n...\nbind_address=0.0.0.0\n

Then restart the server if you had it running and reload your browser in case you were already trying to access the Web UI form a different IP.

faraday-server also allow to use --bind and --port to override server.ini settings.

"},{"location":"Development-setup/#running","title":"Running","text":"

Once everything is installed and the server is configured, you can proceed to run the Faraday server script:

$ faraday-server\n

If you want to run the server in background mode, you should use the --start option:

$ faraday-server --start\n

This is the recommended way to do this. Other methods like using the bash & could cause unexpected IOErrors and other related exceptions.

"},{"location":"Development-setup/#web-ui","title":"Web UI","text":"

Once the server is running, you can access Faraday's Web UI using any browser: just point it to http://SERVER_IP:SERVER_PORT/ (by default it will be http://localhost:5985/) and you can start playing with Faraday.

"},{"location":"Development-setup/#faraday-client","title":"Faraday Client","text":"

Faraday Client is the software which will allow you to work with your favorite security tools and capture their output in an organized manner. It works under a GTK+3 interface with the popular VTE terminal with a custom ZSH shell that respects the user's configuration (yes, that means you get to keep your exact ZSH terminal inside Faraday, even if you use ZPrezto or Oh My ZSH).

From the client you can also create and delete workspaces, specify plugin configuration, view information about your hosts, resolve conflics that may arise and much more.

It's also a responsibility of the client to send all of the collected information to the server, which will then process it and format it in an friendly way for you to view, edit, and confirm.

The client is bundled in the same package as the server, so if you have already downloaded Faraday, you can skip the next step.

"},{"location":"Development-setup/#downloading_1","title":"Downloading","text":"

Download the latest tarball or clone the Faraday Git Project repository and checkout dev branch:

$ git clone https://github.com/infobyte/faraday.git faraday-dev\n$ git checkout dev\n$ cd faraday-dev\n
"},{"location":"Development-setup/#requirements_1","title":"Requirements","text":"

Faraday Client works under any modern Linux distribution or Mac OS X, and needs Python 3.6+.

The Python requirements for the client are stored in the requirements.txt file. Some additional requirements are necessary for specific features to work, these are stored in the requirements_extras.txt file.

Out tests include Debian, Ubuntu, Kali, Backtrack.

"},{"location":"Development-setup/#installing-system-dependencies_1","title":"Installing system dependencies","text":""},{"location":"Development-setup/#debian-and-derivatives","title":"Debian and derivatives","text":"

You can run the following command to install the required dependencies on any Debian based distribution.

$ sudo apt update\n

If you are running Ubuntu 12.04 LTS, or Ubuntu 14.04 LTS, please execute this command:

$ sudo apt install libpq-dev python-pip python-dev gir1.2-gtk-3.0 gir1.2-vte-2.90 python-gobject zsh curl\n

If you are any other version, please execute the following command:

$ sudo apt install libpq-dev python-pip python-dev gir1.2-gtk-3.0 gir1.2-vte-2.91 python-gobject zsh curl\n
"},{"location":"Development-setup/#gentoo","title":"Gentoo","text":"

This are the dependencies for Gentoo with Emerge:

dev-libs/gobject-introspection net-libs/webkit-gtk x11-libs/gtk+ \\\nx11-libs/vte dev-python/pygobject app-shells/zsh net-misc/curl dev-python/ipython\n

Extras dependencies:

dev-python/beautifulsoup dev-python/gevent-psycopg2\n
"},{"location":"Development-setup/#using-gtk-client-with-virtualenv","title":"Using GTK client with virtualenv","text":"

If you are working inside a Virtual enviroment you need to follow this extra steps for GTK to work:

pip install vext\npip install vext.pygtk\npip install vext.gi\n

"},{"location":"Development-setup/#configuration_1","title":"Configuration","text":"

Now you need to configure every Faraday instance so it can connect to the server.

  • If you're using the GTK interface click on the Preferences icon and fill in the server URL, for example http://127.0.0.1:5985

  • If you are using the --gui=no-gui option

Edit the file: ~/.faraday/config/user.xml And search for the following api_uri tag and set it to the server URL, for example:

<api_uri>http://127.0.0.1:5985</api_uri>

If you are using SSL you need to use https in your configuration. For example use https://192.168.0.20 when you are using an nginx server with SSL enabled and faraday-server is listening on 192.168.0.20.

"},{"location":"Development-setup/#running_1","title":"Running","text":"

Once you have already configured the client and have Faraday Server running, you simply have to run:

$ faraday-client\n

Some distributions or installations require additional steps, so look down below if you are using something different than Debian or Ubuntu, or if you need to apply some configuration to the client.

"},{"location":"Development-setup/#kali","title":"Kali","text":"

Faraday comes pre-installed in Kali Rolling. The package name is python-faraday. Keep in mind that this package can only be used for the Community edition.

In order to run Faraday in Kali:

$ systemctl start postgresql.service\n$ cd /usr/share/python-faraday\n$ faraday-server\n$ faraday-client\n

Due to Kali's package updates the pre-installed package may not be the last version. If you want the latest updates use the Debian install steps.

"},{"location":"Development-setup/#gentoo_1","title":"Gentoo","text":"

If you are running Gentoo, this are the dependencies with Emerge:

dev-python/flask-sqlalchemy dev-python/service_identity dev-python/twisted \\\ndev-python/pyopenssl dev-java/mockito dev-python/Whoosh \\\ndev-python/configargparse dev-python/restkit dev-python/requests www-servers/tornado \\\ndev-python/flask dev-python/colorama dev-python/setuptools dev-python/pip dev-libs/libpqxx \\\nlibffi-dev\n
"},{"location":"FAQ/","title":"FAQs","text":""},{"location":"FAQ/#index","title":"Index","text":"
  • Where does the name come from?
  • What is Faraday?
  • Is Faraday free?
  • Does Faraday have collaboration tools?
  • Which platforms are supported?
  • Does Faraday work on my servers or on the cloud?
  • What are the system requirements to run Faraday?
  • I purchased a License, now what?
  • Can I keep using the Kali version with my newly bought pro/corp license?
  • Can I install the Server and/or Client in my own box instead of using a Virtual Machine?
  • What version am I using?
  • What if I want to add a Vulnerability manually?
  • How do I bind Faraday to 0.0.0.0?
  • Where are my credentials?
  • I lose my credentials?

Is your question not listed here? Contact us

"},{"location":"FAQ/#topics","title":"Topics","text":""},{"location":"FAQ/#where-does-the-name-come-from","title":"Where does the name come from?","text":"

The name was picked to honor Michael Faraday, an English scientist whose main discoveries include electromagnetism induction, diamagnetism and electrolysis. Mainly his six principles of scientific discipline, acquired at a young age from Isaac Watts' \"The Improvement of the mind\": * Always carry a small pad to take notes at any time * Maintain abundant correspondence * Collaborate regularly with others to exchange ideas * Avoid controversy * Verify everything that was said to him * Do not generalize, speak and write as precisely as possible

Read more at: https://en.wikipedia.org/wiki/Michael_Faraday http://www.eng.auburn.edu/~sjreeves/cm/improve.html

"},{"location":"FAQ/#what-is-faraday","title":"What is Faraday?","text":"

Faraday is a multiuser integrated penetration test and vulnerability management environment. It is to Penetration Testing what an IDE is to Development. The main purpose of Faraday is to re-use the available tools in the community to take advantage of them in a multiuser way.

"},{"location":"FAQ/#is-faraday-free","title":"Is Faraday free?","text":"

Yes, we have a Community version which is totally free, you can download it from Github We also have two Commercial versions, details about those in our webpage.

Compare different versions of Faraday

"},{"location":"FAQ/#does-faraday-have-collaboration-tools","title":"Does Faraday have collaboration tools?","text":"

Faraday supports over 80 tools. Full plugin list available here.

"},{"location":"FAQ/#which-platforms-are-supported","title":"Which platforms are supported?","text":"

RedHat, CentOS, Fedora, Debian, Kali, Ubuntu, Docker.

"},{"location":"FAQ/#does-faraday-work-on-my-servers-or-on-the-cloud","title":"Does Faraday work on my servers or on the cloud?","text":"

Yes it does, depending on your needs. For more information you can contact us at sales@infobytesec.com

"},{"location":"FAQ/#what-are-the-system-requirements-to-run-faraday","title":"What are the system requirements to run Faraday?","text":"

CPU: 2 Dualcore 2GHz Intel CPU Disk: 40 GB Memory: 4 GB RAM (8 GB RAM recommended)

Current tests include Debian, Ubuntu, Kali, and Backtrack.

If instead of installing you want to take a quick look at Faraday you can also use Docker.

"},{"location":"FAQ/#i-purchased-a-license-now-what","title":"I purchased a License, now what?","text":"

You will receive an email with a link to download everything regarding your license. If you haven\u2019t received it or are having issues, please contact us at sales@infobytesec.com.

"},{"location":"FAQ/#can-i-keep-using-the-kali-version-with-my-newly-bought-professionalcorporate-license","title":"Can I keep using the Kali version with my newly bought Professional/Corporate license?","text":"

In a nutshell, yes. Even though the Kali Faraday version is incompatible with both the Professional and Corporate licenses, you can upgrade the platform in the same box without losing all your data.

You will need to remove the package python-faraday and then you need to install the pro/corp .deb with apt install ./faraday-server_amd64.deb

"},{"location":"FAQ/#can-i-install-the-server-andor-client-in-my-own-box-instead-of-using-a-virtual-machine-you-provided","title":"Can I install the Server and/or Client in my own box instead of using a Virtual Machine you provided?","text":"

The only intended purpose for the Faraday VM is as a commercial demo.

For production environments we recommend doing a fresh install in a Ubuntu Server, please do not use your provided Demo License VM.

If the use of a Virtualized environment is a must-have, then we recommend doing a proper install in a fresh Virtual Machine following the regular installation steps.

"},{"location":"FAQ/#how-do-i-know-which-faraday-version-im-using","title":"How do I know which Faraday Version I'm using?","text":"

By running faraday-server --version or hovering your mouse over the Faraday logo at the top left of the Web UI. Latest version and information available in the Upgrading Faraday section.

To get the latest available version:

  • for the community version, visit Github
  • for the commercial versions, check the Customer Portal

"},{"location":"FAQ/#what-if-i-want-to-add-a-vulnerability-manually","title":"What if I want to add a Vulnerability manually?","text":"

You can do this using our Web UI, read our documentation on manually adding vulnerabilities.

"},{"location":"FAQ/#how-do-i-bind-faraday-to-0000","title":"How do I bind Faraday to 0.0.0.0?","text":"

Just go to /home/faraday/.faraday/config/server.ini and inside the [faraday-server] section write:

bind_address=0.0.0.0

Restart Faraday Server if you had it running. That's it!

"},{"location":"FAQ/#where-are-my-credentials","title":"Where are my credentials?","text":"

When installing Faraday you run the following command:

faraday-manage initdb\n

and get your credentials on the terminal (something like this):

username: faraday\npassword: a7e8d3seWqy5\n
If you don't remember this, below, you can see how to re-generate them.

"},{"location":"FAQ/#i-lost-my-credentials","title":"I lost my credentials","text":"

If during the instalation you forget to store or keep your credentials, don't worry, you can either create a new admin user or change the default admin user:

Change faraday default admin user (enter the new password):

$ faraday-manage change-password\n
    Username: faraday\n    Password:\n    Repeat for confirmation:\n    Password changed succesfully\n

Create a new admin user (Only for paid users):

$ faraday-manage create-superuser\n
    Username: admin\n    Email: admin@example.com\n    Password:\n    Repeat for confirmation:\n    User admin created successfully!\n

Is your question not listed here?

Generate a support ticket to get aid from our Help Desk staff.

If you are using Faraday community, you can reach us by using our GitHub issues page.

"},{"location":"Faraday-Manage-Settings-v4/","title":"Faraday Manage Settings","text":"

The purpose of this documentation is to explain how to use faraday-manage settings

"},{"location":"Faraday-Manage-Settings-v4/#update-executive-reports-configuration","title":"Update executive reports configuration","text":"

To update executive reports configuration to enable markdown

faraday-manage settings -a update executive_reports\n\nmarkdown: True\nborder_size: 3\n
Then restart your Faraday Server instance
systemctl restart faraday-server\n

"},{"location":"Faraday-Manage-Settings-v4/#update-smtp-configuration","title":"Update SMTP configuration","text":"

To setup your SMTP configurations

faraday-manage settings -a update smtp\n\nenabled:\nusername\nhost:\nport: \nsender: \nssl:\n

Then update every field to the desired configuration

"},{"location":"Faraday-Manage-Settings-v4/#update-reports-configuration-and-custom-plugin-folder","title":"Update reports configuration and custom plugin folder","text":"

To update the custom plugin folder run the following command

faraday-manage settings -a update reports\n\nignore_info_severity[False]: \ncustom_plugins_folder:\n

Then update the field custom plugin folder to the specified path

"},{"location":"Faraday-Manage-Settings-v4/#enable-saml","title":"Enable SAML","text":"

To enable SAML and update the SAML configuration,

faraday-manage settings -a update saml\n\nenabled[False]: \ndisplay_name [Identity Provider]:\nidentity_id []:\nuser_role [admin]:\nattribute_identifier []:\nsso_url [http://localhost/saml/login]:\nsp_certificate []:\nsp_private_key []:\nidp_certificate []:\n

"},{"location":"Faraday-Manage/","title":"Faraday Manage","text":"

Faraday Manage is a backend tool that helps us administrate Faraday's configuration.

To use Faraday Manage, you can run it as follow:

$ faraday-manage COMMAND\n

If you run only faraday-manage, it will list you all the available commands.

"},{"location":"Faraday-Manage/#available-commands","title":"Available Commands","text":""},{"location":"Faraday-Manage/#add-custom-attribute","title":"add-custom-attribute","text":"

This command allows you to create Custom Fields from the terminal. For more information about Custom Fields, you can see their wiki page

"},{"location":"Faraday-Manage/#change-password","title":"change-password","text":"

It allows you to change your user's password

"},{"location":"Faraday-Manage/#create-superuser","title":"create-superuser","text":"

The name says it all! This is the way to create a new admin user through the command line.

"},{"location":"Faraday-Manage/#create-tables","title":"create-tables","text":"

This command allows the user to manually create a table on Faraday's database. It would come in handy if something in the initdb command fails for example.

"},{"location":"Faraday-Manage/#create-workspace","title":"create workspace","text":"

Create workspace

"},{"location":"Faraday-Manage/#database-schema","title":"database-schema","text":"

This will print a PNG image with Faraday's internal working scheme.

"},{"location":"Faraday-Manage/#delete-custom-field","title":"delete-custom-field","text":"

It allows you to delete a Custom Field from terminal

"},{"location":"Faraday-Manage/#generate-nginx-config","title":"generate-nginx-config","text":"

This command displays the nginx config example to be added in nginx config

"},{"location":"Faraday-Manage/#generate-roles-permission","title":"generate-roles-permission","text":"

This command displays the roles permission in a JSON file

"},{"location":"Faraday-Manage/#generate-rsa-keys","title":"generate-rsa-keys","text":"

It will create an RSA key for integrations

"},{"location":"Faraday-Manage/#import-license","title":"import-license","text":"

Imports Faraday License.

"},{"location":"Faraday-Manage/#import-methodologies","title":"import-methodologies","text":"

Imports methodologies and tasks from a csv file

"},{"location":"Faraday-Manage/#import-vulnerability-templates","title":"import-vulnerability-templates","text":"

Imports vuln templates from a file

"},{"location":"Faraday-Manage/#initdb","title":"initdb","text":"

This command needs to be executed only at the moment of Faraday's installation. It will create the tables of the database, Faraday's user among other things.

If you try to execute this a second time it will indeed fail.

Danger

Warning: Please do not lose the random password that this command will print on the screen. It will be necessary to login into Faraday.

"},{"location":"Faraday-Manage/#list-plugins","title":"list-plugins","text":"

Lists available plugins.

"},{"location":"Faraday-Manage/#load-samples","title":"load-samples","text":"

Loads pre-loaded samples for config, attributes, searchfilters, pipelines and planner

"},{"location":"Faraday-Manage/#migrate","title":"migrate","text":"

Migrates database schema.

"},{"location":"Faraday-Manage/#openapi-yaml","title":"openapi-yaml","text":"

Show URLs in OpenApi format

"},{"location":"Faraday-Manage/#remove-rsa-keys","title":"remove-rsa-keys","text":"

Remove RSA key pair generated for an...

"},{"location":"Faraday-Manage/#rename-user","title":"rename-user","text":"

Change username.

"},{"location":"Faraday-Manage/#settings","title":"settings","text":"

It allows you to manage settings inside faraday configuration

"},{"location":"Faraday-Manage/#show-rsa-keys","title":"show-rsa-keys","text":"

Show RSA key pair for an integration's

"},{"location":"Faraday-Manage/#show-urls","title":"show-urls","text":"

Prints a list of all the URLs available to communicate with our API Rest.

"},{"location":"Faraday-Manage/#sql-shell","title":"sql-shell","text":"

This command will open a PostgreSQL shell already configured with Faraday's user and configuration.

"},{"location":"Faraday-Manage/#take-stats-snapshot","title":"take-stats-snapshot","text":"

Generates vulnerabilities stats of the analytics and workspace view.

"},{"location":"Faraday-Manage/#update-enrichment-database","title":"update-enrichment-database","text":"

Download latest enrichment database

"},{"location":"Faraday-Zap-extension/","title":"Faraday Zap extension","text":""},{"location":"Faraday-Zap-extension/#importing-to-faraday-a-xml-report-generated-by-owasp-zap","title":"Importing to Faraday a XML report generated by OWASP Zap","text":""},{"location":"Faraday-Zap-extension/#using-faraday-zap-extension","title":"Using Faraday Zap Extension","text":"

With Faraday Zap Extension, you are able to send new issues directly from OWASP Zap into Faraday.

"},{"location":"Faraday-Zap-extension/#download-faraday-zap-extension","title":"Download Faraday Zap Extension","text":"

The first thing we need to do is to download Faraday Zap Extension.

"},{"location":"Faraday-Zap-extension/#configuring-faraday-zap-extension","title":"Configuring Faraday Zap Extension","text":"

Once we have downloaded it, we need to load it into OWASP Zap. You can load an add-on as the sample image below or by typing [Ctrl + L]:

Now we need to authenticate into the Faraday Zap extension by using our Faraday's credentials. Go into Tools/Faraday configuration options or type [Ctrl+Alt+F]:

Type your credentials and set the Faraday Server URL to the correct one. Then click Login:

Once you are logged in, you can go to the Configuration tab and select the workspace where you want to work in:

Note: by clicking on Refresh, you can update your workspaces from Faraday.

"},{"location":"Faraday-Zap-extension/#sending-requests-and-alerts-into-faraday","title":"Sending requests and alerts into Faraday","text":"

Now that you have configured Faraday Zap extension, you can proceed to send issues into Faraday:

  • Sending a request:

  • Sending an alert:

"},{"location":"Faraday-Zap-extension/#uninstalling-faraday-zap-extension","title":"Uninstalling Faraday Zap Extension","text":"

To uninstall the extension, go into Manage Add-ons, select the extension named Faraday and then click on Uninstall Selected

"},{"location":"Filters/","title":"Search","text":""},{"location":"Filters/#using-search-field-in-faraday-v-4","title":"Using Search Field in Faraday V 4","text":"

In ordear to ease the need of searching we've developed a way to use the search bar in order to be able to select the search fields and easily build the queries needed.

To select Vulns click on Vulnerability as the image bellow:

then select the desired Field as:

Operator value Contains:

and then type the value that will be searched:

After finishing typing hit Enter or click on the search button

"},{"location":"Filters/#filters","title":"Filters","text":""},{"location":"Filters/#making-search-queries","title":"Making search queries","text":"

Clients can make advanced searchs using the UI Clicking on the Switch to advanced mode Link, after doing this the search field will admit using a dictionary with values as the description bellow

{\"name\": <fieldname>, \"op\": <operatorname>, \"val\": <argument>}

The operator strings recognized by the API incude:

==, eq, equals, equals_to\n!=, neq, does_not_equal, not_equal_to\n>, gt, <, lt\n>=, ge, gte, geq, <=, le, lte, leq\nin, not_in\nis_null, is_not_null\nlike\nilike\nhas\nany\n
"},{"location":"Filters/#manage-vulns-aka-status-report-fields","title":"Manage vulns (aka status report) fields","text":"Field name Field Type Valid Operators Confirmed Working name string all description string all severity severities enum eq, neq target string all service relationship service.name string all service.port number eq, neq, >,>=, <, <= easeofresolution (ease_of_resolution in model) ease_of_resolutions enum eq, neq references (reference_instances in model) relationship references.name string all resolution string all data string all request string all method string all response string all pname (parameter_name en el modelo) string all params (parameters en el model) string all path string all query (query_string en el modelo) string all website string all creator relationship creator.username string all type vuln_types enum eq, neq confirmed boolean eq, neq id number eq, neq, >, >=, <, <=

Data types

boolean = [ true, True, false, False ]\n\nEASE_OF_RESOLUTIONS = [\n    'trivial',\n    'simple',\n    'moderate',\n    'difficult',\n    'infeasible'\n]\n\nVULN_TYPES = [\n    'vulnerability',\n    'vulnerability_web',\n    'vulnerability_code'\n]\n\nSEVERITIES = [\n    'critical',\n    'high',\n    'medium',\n    'low',\n    'informational',\n    'unclassified',\n]\n\nSTATUS = [\n    'open',\n    'closed',\n    'filtered'\n]\n
"},{"location":"Filters/#some-examples","title":"Some examples","text":"

Endpoint

http://localhost:5985/_api/v2/ws/testws1/vulns/filter?q={\"filters\": [...]}

Basic one

name == \"test 1\"

{\n    \"filters\": [\n                { \"name\": \"name\", \n                    \"op\": \"eq\",  \n                   \"val\": \"test1\" \n                }\n               ]\n}\n
With and

severity == medium

{\n    \"filters\": [\n                { \"name\": \"name\", \n                    \"op\": \"eq\",  \n                   \"val\": \"test1\" \n                },\n                { \"name\": \"severity\",  \n                    \"op\": \"eq\",\n                   \"val\": \"medium\" \n                } \n              ]\n}\n

A bit complex one

name like \"t%\" and (severity == \"critical\" or severity == \"medium\")

{ \"filters\": [ \n                { \"name\": \"name\", \"op\": \"like\", \"val\": \"t%\"  }, \n                {  \"or\": [ \n                     { \"name\": \"severity\",    \"op\": \"eq\",    \"val\": \"medium\"  } ,\n                     { \"name\": \"severity\",    \"op\": \"eq\",    \"val\": \"critical\"  }\n                  ] \n                 } \n            ]\n}\n
so to do this query it can be used something like this:

With case insensitive logic and fields with relationships

name ilike \"%php%\" and (service.name like \"%http%\" or service.port eq 80)

{ \"filters\": [ \n                { \"name\": \"name\", \"op\": \"ilike\", \"val\": \"%php%\"  }, \n                {  \"or\": [ \n                     { \"name\": \"service\", \n                        \"op\": \"has\",  \n                        \"val\": { \"name\": \"name\", \"op\": \"like\",  \"val\": \"%http%\" } \n                      } ,\n                     { \"name\": \"service\", \n                        \"op\": \"has\",  \n                       \"val\": { \"name\": \"port\", \"op\": \"eq\",  \"val\": \"80\" } \n                     }\n                   ] \n                } \n            ]\n}\n

Previous filters but just the ones created by user faraday

name ilike \"php%\" and (service.name like \"%http%\" or service.port eq 80) and creator.username == 'faraday'

{ \"filters\": [\n                { \"name\": \"creator\", \n                    \"op\": \"has\",\n                   \"val\": { \"name\": \"username\", \"op\": \"eq\",  \"val\": \"faraday\" } } ,\n                { \"name\": \"name\", \"op\": \"ilike\", \"val\": \"%php%\"  }, \n                {  \"or\": [ \n                     { \"name\": \"service\", \n                        \"op\": \"has\",  \n                        \"val\": { \"name\": \"name\", \"op\": \"like\",  \"val\": \"%http%\" } \n                      } ,\n                     { \"name\": \"service\", \n                        \"op\": \"has\",  \n                       \"val\": { \"name\": \"port\", \"op\": \"eq\",  \"val\": \"80\" } \n                     }\n                   ] \n                } \n            ]\n}\n
"},{"location":"Filters/#hosts","title":"HOSTS","text":""},{"location":"Filters/#manage-hosts-fields","title":"Manage hosts fields","text":"

Endpoint

http://localhost:5985/_api/v2/ws/testws1/hosts/filter?q={\"filters\": [..]

Field name Field Type Valid Operators ip string all hostnames relationship hostnames.name string all services relationship services.name string all services.port number eq, neq, >,>=, <, <= services.status status enum eq, neq os string all owned boolean eq, neq vulnerability_critical_generic_count number eq, neq, >,>=, <, <= vulnerability_high_generic_count number eq, neq, >,>=, <, <= vulnerability_medium_generic_count number eq, neq, >,>=, <, <= vulnerability_low_generic_count number eq, neq, >,>=, <, <= vulnerability_info_generic_count number eq, neq, >,>=, <, <= vulnerability_unclassified_generic_count number eq, neq, >,>=, <, <=

Some examples

{\"filters\": [\n       { \"and\":  [\n              { \"name\": \"hostnames\", \n                  \"op\": \"any\", \n                 \"val\": { \"name\": \"name\", \n                            \"op\": \"eq\", \n                           \"val\": \"asdf1\" \n                        }\n              }\n          ] \n      } \n  ] \n}\n
{\"filters\": [\n       { \"and\":  [\n              { \"name\": \"services\", \n                  \"op\": \"any\", \n                 \"val\": { \"name\": \"port\", \n                            \"op\": \"eq\", \n                           \"val\": \"80\" \n                        }\n              }\n          ] \n      } \n  ] \n}\n
{\n    \"filters\": [\n                { \"name\": \"ip\", \n                    \"op\": \"like\",  \n                   \"val\": \"192.168.0.%\" \n                }\n               ]\n}\n
"},{"location":"First-Steps/","title":"First Steps","text":"

Now that you have installed Faraday, we will take the first steps together in this journey

"},{"location":"First-Steps/#accessing-faraday-web-ui","title":"Accessing Faraday Web UI","text":"

First, navigate to Faraday Web UI and log in.

Where are my credentials?

"},{"location":"First-Steps/#creating-a-workspace","title":"Creating a Workspace","text":"

Faraday has the concept of Workspaces where you can put all your data related to a project in one place, you can have many workspaces to represent different engagements, weekly/monthly scans for internal/dmz/external networks, specific application assessments, etc

Details on Workspace here

"},{"location":"First-Steps/#creating-a-host","title":"Creating a Host","text":"

See how to create, edit and delete an asset in Assets and Services

"},{"location":"First-Steps/#creating-a-vuln","title":"Creating a Vuln","text":"

See how to create, edit and delete a vuln in Vulns

"},{"location":"First-Steps/#creating-a-report","title":"Creating a Report","text":"

See how to create, edit and delete a report in Reports

"},{"location":"First-Steps/#getting-started","title":"Getting Started","text":"

Using faraday to integrate your tools has never been this easy!

Details on Getting started here

"},{"location":"Getting-started/","title":"First Steps","text":""},{"location":"Getting-started/#getting-started","title":"Getting Started","text":"

Learn about Faraday holistic approach and rethink vulnerability management.

  • Centralize your vulnerability data

  • Automate the scanners you need

"},{"location":"Getting-started/#integrating-faraday-in-your-cicd","title":"Integrating faraday in your CI/CD","text":"

Setup Bandit and OWASP ZAP in your pipeline

  • GitHub [PDF]

  • Jenkins [PDF]

  • TravisCI [PDF]

Setup Bandit, OWASP ZAP and SonarQube in your pipeline

  • Gitlab [PDF]
"},{"location":"How-to-build-your-template/","title":"How to build a Template","text":"

We use Jinja2 to create Report Templates. Here are listed the main variables available when creating a Template.

"},{"location":"How-to-build-your-template/#general-variables","title":"General Variables","text":"

These are the variables loaded when creating a report

  • date - the date when the Report was created, as the name of the month and four digits for the year

  • title

  • enterprise

  • summary

  • conclusions

  • recommendations

  • scope

  • objectives

Workspace
  • workspace.scope - a list containing the different scopes of the workspace.
  • workspace - a dictionary with all workspace information.
    • name
    • description
    • id
    • duration.start_date
    • duration.end_date
    • users
    • update_date
    • stats.total_vulns
    • stats.std_vulns
    • stats.web_vulns
    • stats.code_vulns
    • stats.hosts
    • stats.services
    • stats.credentials
    • public
    • readonly
    • active
    • create_date
    • _id

Date Format

start_date and end_date are displayed in timestamp format. If you want to change their format, you can use datetimeformat() function and pass the desired format as parameter. E.g.:

   workspace.duration.start_date|datetimeformat('%m-%d-%Y')\n\n   workspace.duration.end_date|datetimeformat('%B %Y')\n
For more information about date format check Python docs.

Host
  • hosts_amount - an int containing the amount of hosts in the Workspace
  • hosts - a dictionary with all the hosts in the Workspace
    • type
    • description
    • default_gateway
    • ip
    • owned
    • tags
    • name
    • services
    • versions
    • mac
    • hostnames
    • vulns
    • owner
    • credentials
    • service_summaries
    • id
    • os
    • metadata
Service
  • services_amount - an int containing the amount of services in the Workspace
  • services - a dictionary with all the services in the Workspace
    • status
    • protocol
    • description
    • parent
    • tags
    • vulns
    • metadata
    • owned
    • summary
    • port
    • owner
    • version
    • host_id
    • id
    • credentials
    • type
    • ports
    • name
Vulnerability
  • counter_severity - a dictionary with all the severities and the amount of vulns for each one vulnerability pie charts
  • vulns_amount - an int containing the amount of vulnerabilities in the Workspace except for vulns with severity unclassified, which are not included
  • vulns - a dictionary with all the vulnerabilities in the Workspace except for vulns with severity unclassified, which are not included
    • update_user
    • parent_type
    • owned
    • owner
    • id
    • impact
    • confirmed
    • severity
    • service
    • data
    • policyviolations
    • evidence_subdoc
    • type
    • refs
    • metadata
    • status
    • issuetracker
    • description
    • parent
    • tags
    • easeofresolution
    • hostnames
    • data
    • host_os
    • desc
    • name
    • obj_id
    • target
    • resolution
    • severity_numbers
    • method
    • params
    • website
    • query
    • path
    • request
    • response

Grouped reports will have an additional field: vulns_grouped_amount - an int containing the total amount of vulnerabilities after grouping

"},{"location":"How-to-build-your-template/#custom-fields-in-executive-report","title":"Custom Fields in Executive Report","text":"

You can access your Custom Attributes on the docx templates like a dictionary and by the field name:

vuln.custom_fields[\"cvss\"] \n

"},{"location":"How-to-build-your-template/#jinja2-context","title":"Jinja2 Context","text":"

For more technical information, here is the Jinja2 context, where you can find all the DataTypes and structures implemented with Jinja.

"},{"location":"How-to-build-your-template/#template-examples","title":"Template Examples","text":"

Here are some basic templates.

"},{"location":"How-to-build-your-template/#default-templates","title":"Default Templates","text":"

Default Generic/Grouped

"},{"location":"How-to-build-your-template/#markdown-templates","title":"Markdown Templates","text":"

Markdown_Grouped/Generic

"},{"location":"Install-guide-Advanced/","title":"Faraday Advanced Installation with Websockets Notifications","text":"

Faraday, as a powerful security platform, supports sending notifications through websockets, a crucial feature also utilized by Faraday Agents. To enable and properly configure websockets in an on-premises installation, follow the comprehensive guide below.

"},{"location":"Install-guide-Advanced/#install-nginx","title":"Install NGINX:","text":"
sudo apt install nginx\n
"},{"location":"Install-guide-Advanced/#configuring-nginx","title":"Configuring NGINX","text":"

Use the following configuration file:

map $http_upgrade $connection_upgrade {\n    default upgrade;\n    ''      close;\n}\n\nserver {\n    listen 443 ssl; \n    server_name faraday.local;\n    client_max_body_size 500M;\n    ssl_session_cache shared:SSL:50m;\n    ssl_certificate /etc/ssl/faraday.crt;\n    ssl_certificate_key /etc/ssl/faraday.key;\n\n    location / {\n        alias /opt/faraday/lib/python3.10/site-packages/faraday/server/www;\n        try_files $uri $uri/ /index.html;\n    }\n\n    location /_api/ {\n        proxy_pass http://127.0.0.1:5985/_api/;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Ssl on;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n\n\n\n    location /socket.io {\n        include proxy_params;\n        proxy_http_version 1.1;\n        proxy_buffering off;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection $connection_upgrade;\n        proxy_pass http://127.0.0.1:5985;# Expires map\nmap $sent_http_content_type $expires {\n    default                    off;\n    text/html                  max;\n    text/css                   max;\n    application/javascript     max;\n    ~image/                    max;\n}\n\nserver {\n    server_name replacewithyourip;\n    listen 443 ssl http2;\n\n    add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\" always;\n    add_header X-XSS-Protection \"1; mode = block\";\n    add_header X-Frame-Options \"SAMEORIGIN\";\n    add_header X-Content-Type-Options nosniff;\n    client_max_body_size 5G;\n\n    ssl on;\n    ssl_session_cache shared:SSL:50m;\n    ssl_certificate           /etc/ssl/faraday.crt;\n    ssl_certificate_key       /etc/ssl/faraday.key;\n    gzip on;\n    gzip_types application/javascript text/css;\n\n    expires $expires;\n\n    location / {\n        alias /opt/faraday/lib/python3.10/site-packages/faraday/server/www/;\n        try_files $uri $uri/ /index.html;\n    }\n\n    location /_api/ {\n        proxy_pass http://{faraday-ip}:5985/_api/;\n        proxy_redirect http:// $scheme://;\n        proxy_read_timeout 6000;\n    proxy_connect_timeout 6000;\n    proxy_send_timeout 6000;\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Ssl on;\n        proxy_cookie_path / \"/; secure\";\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n\n    location /websockets {\n        proxy_http_version 1.1;\n        proxy_pass http://{faraday-ip}:9000/websockets;\n\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n    }\n\n    location /_api/wsocket/v1/ {\n      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n      proxy_pass http://{faraday-ip}:5000/_api/wsocket/v1/;\n      proxy_http_version 1.1;\n      proxy_set_header Upgrade $http_upgrade;\n      proxy_set_header Connection \"upgrade\";\n    }\n\n\n}\n\nserver {\n    server_name {faraday-ip};\n    listen 80 ;\n    listen [::]:80 ;\n\n    # https redirect\n    if ($host = {faraday-ip}) {\n        return 301 https://$host$request_uri;\n    } \n\n    return 404;\n}\n

Place it in /etc/nginx/sites-available.

"},{"location":"Install-guide-Advanced/#generating-certificates","title":"Generating Certificates","text":"
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/faraday.key -out /etc/ssl/faraday.crt\n

The Common Name should be the same as the FQDN, in our case faraday.

Create an alias inside the file pointing front on location / to the path where the static files are.

Section location inside the nginx file (no need to change it):

location / {\n    alias /home/faraday/faraday/faraday/frontend/www/;\n}\n

Create symlinks for sites-enabled to sites-available:

sudo ln -s /etc/nginx/sites-available/faraday /etc/nginx/sites-enabled/faraday\n

Restart NGINX:

sudo systemctl restart nginx\n

Startup the websockets server:

faraday-websocket-server\n

After this local configuration, you should see http://faraday.local with websockets up and running.

In case faraday.local is not resolved, check /etc/hosts for the line:

127.0.0.1    faraday.local\n

We highly recommend you to check our First Steps guide.

"},{"location":"Install-guide-Docker/","title":"Faraday Community Edition Installation Guide with Docker","text":"

This guide provides step-by-step instructions for installing the Community Version of Faraday using Docker. The instructions cover both running Faraday as a standalone container and as a service. Additionally, environment variables and volumes for configuration are explained in detail.

"},{"location":"Install-guide-Docker/#configuration","title":"Configuration","text":"

This image can be run as a service or as a standalone container. Both run Faraday Server without PostgreSQL. You will note that we have created /faraday-storage and /faraday-config volumes (for mounting your storage and configuration). We have also created environment variables for Faraday configuration in case you don't mount a config volume. We will get more in detail of these volumes and environment variables:

Example:

Running Faraday as a standalone container

docker run \\\n    ...\n    -v /path/to/my_doc_folder:/faraday-license \\\n    -v /path/to/my_storage_folder:/faraday-storage \\\n    -v /path/to/my_config_folder:/faraday-config\n    ...\n    faradaysec/faraday:4.6.2\n

Running Faraday as a service

vim docker-compose.yml\nversion: '4.02'\nservices:\n  ...\n  volumes:\n    - /path/to/{my_config_folder}:/home/faraday/.faraday\n  ...\n

We will get more in details about this configuration below.

"},{"location":"Install-guide-Docker/#environment-variables","title":"Environment Variables","text":"

In case you don't have a configuration file you'll need to set some environment variables. These come with default values so you'll need to customize some or all of them depending on your installation config.

PGSQL_HOST=172.2.0.1 # PostgreSQL server host.\nPGSQL_USER=faraday_postgresql # PostgreSQL user\nPGSQL_PASSWD=mypgsqlpassword # PostgreSQL user's password.\nPGSQL_DBNAME=faraday # Faraday's database name\n
"},{"location":"Install-guide-Docker/#running-faraday","title":"Running Faraday","text":"

Now that we have learnt about the volumes and the environment variables above, let's run Faraday assuming we want to connect into PostgreSQL's address 192.168.20.29 and that we have located Faraday's config folder in its default location: ~/.faraday

"},{"location":"Install-guide-Docker/#as-a-standalone-container","title":"As a standalone container","text":"

Run the following command specifying the correct information:

With environment variables

docker run \\\n    -v ~/.faraday/doc:/faraday-license \\\n    -v ~/.faraday/storage:/faraday-storage \\\n    -p 5985:5985 \\\n    -e PGSQL_HOST='192.168.20.29' \\\n    -e PGSQL_PASSWD='mypgsqlpassword' \\\n    -e LISTEN_ADDR='0.0.0.0' \\\n    faradaysec/faraday:latest\n

With config volume mounted

docker run \\\n    -v ~/.faraday/doc:/faraday-license \\\n    -v ~/.faraday/storage:/faraday-storage \\\n    -v ~/.faraday/config:/faraday-config \\\n    -p 5985:5985 \\\n    faradaysec/faraday:latest\n

To check the container, run the following command:

docker container ls\n

As you can see, Faraday Server is running on port 5985.

"},{"location":"Install-guide-Docker/#as-a-service","title":"As a service","text":"
  1. Initialize a Swarm:

    docker swarm init\n# In case you have more than one IP addr configured in your machine you have to specify which one to use.\ndocker swarm init --advertise-addr=192.168.20.29\n

  2. Docker Compose File: Now, you need to create a docker-compose.yml file. You can use this docker-compose as an example:

With environment variables

version: '4.02' \n\nservices: \n  server: \n    image: faradaysec/faraday:latest\n    environment: \n      - LISTEN_ADDR=0.0.0.0 \n      - PGSQL_HOST=192.168.20.29 \n      - PGSQL_USER=faraday_postgresql \n      - PGSQL_PASSWD=/run/secrets/pgsql_passwd \n      - PGSQL_DBNAME=faraday \n    secrets: \n      - pgsql_passwd \n    ports: \n      - 5985:5985 \n    volumes: \n      - ~/.faraday/storage:/faraday-storage \n    deploy: \n      replicas: 1 \n      placement: \n        constraints: [node.role == manager] \nsecrets: \n  pgsql_passwd: \n    external: true\n

When Faraday runs as a service, PGSQL_PASSWD can be configured with Docker secrets (default in docker-compose.yml). The simplest way to create a secret is reading from standard input (you should take care of bash history).

printf mypgsqlpassword | docker secret create pgsql_passwd -\n

Once you have created the secret, edit your docker-compose.yml and set:

vim docker-compose.yml\nversion: 'latest'\nservices:\n  ...\n  environment:\n    - PGSQL_PASSWD=/run/secrets/pgsql_passwd  \n  ...\n

For more information about secrets, check Docker\u2019s web page

With config volume mounted

version: '4.02' \n\nservices: \n  server: \n    image: faradaysec/faraday:latest\n    ports: \n      - 5985:5985 \n    volumes: \n      - ~/.faraday/storage:/faraday-storage \n      - ~/.faraday/config:/faraday-config \n    deploy: \n      replicas: 1 \n      placement: \n        constraints: [node.role == manager] \n

  1. Deploy: Once you are done setting up your docker-compose.yml file, let's deploy it by running the following command:

    docker stack deploy -c docker-compose.yml faraday\n

  2. Check service: To check the service, run the following command:

    docker service ls\ndocker service logs faraday_server\n

"},{"location":"Install-guide-Docker/#web-ui","title":"Web UI","text":"

Once Faraday Server is running, you'll have to obtain the container's IP address. For this, run:

docker inspect $(docker ps -lq) | grep \\\"IPAddress\n

This command will throw the following output:

\"IPAddress\": \"172.17.0.2\",\n\"IPAddress\": \"172.17.0.2\",\n

Now you can direct your browser to http://172.17.0.2:5985/_ui/

We highly recommend you to check our First Steps guide.

"},{"location":"Install-guide-Linux/","title":"Installation Guide for Ubuntu/Debian/Kali","text":""},{"location":"Install-guide-Linux/#requirements","title":"Requirements:","text":"
  • Postgres
  • Redis
"},{"location":"Install-guide-Linux/#postgresql","title":"PostgreSQL","text":"

Please follow the installation guide from the PostgreSQL site for installing PostgreSQL >= 9.6 either local or remote.

# Ubuntu\nsudo apt-get install postgresql\n
"},{"location":"Install-guide-Linux/#redis","title":"Redis","text":"

Please follow the installation guide from the PostgreSQL site for installing PostgreSQL >= 9.6 either local or remote.

# Ubuntu\nsudo apt-get install redis\n
"},{"location":"Install-guide-Linux/#installing-faraday","title":"Installing Faraday","text":""},{"location":"Install-guide-Linux/#step-1-downloading-faraday-installer","title":"Step 1 - Downloading Faraday Installer","text":"

Download the Faraday installer (.deb or .rpm) from:

  • Faraday Portal for Professional/Corporate
"},{"location":"Install-guide-Linux/#step-2-installing-the-package","title":"Step 2 - Installing the package","text":"

Go to your Download directory and run the following command:

# For .deb\nsudo dpkg -i ./faraday-server_amd64.deb\n
"},{"location":"Install-guide-Linux/#step-3-adding-user-to-faraday-group","title":"Step 3 - Adding User to faraday Group","text":"

Once installed, add your user to the faraday group and re-login:

sudo usermod -aG faraday $USER\n
"},{"location":"Install-guide-Linux/#step-4-initializing-the-database-first-time-only","title":"Step 4 - Initializing the Database (first time only)","text":"

Initialize the DB, use it for Faraday Web UI and change it:

faraday-manage initdb\n
"},{"location":"Install-guide-Linux/#importing-license","title":"Importing License","text":"
faraday-manage import-license\n

Or, in isolated servers, download the license file from the portal and place it in /home/faraday/.faraday/doc/. Remove old license files from the doc folder when renewing the license:

tar xvf {license file}.tar.gz\n
"},{"location":"Install-guide-Linux/#post-install-first-time-only","title":"Post Install (First Time Only)","text":"

Start the Faraday server by running:

systemctl start faraday-server\nsystemctl enable faraday-server\n\nsystemctl start faraday-worker\nsystemctl enable faraday-worker\n\nsystemctl start faraday-worker-reports\nsystemctl enable faraday-worker-reports\n

We highly recommend checking our First Steps guide and the Advanced Install guide for starting Faraday using nginx and expose ssl certificates.

Update Advanced Install Remote db implementation

"},{"location":"Install-guide-Redhat-8/","title":"RedHat8","text":""},{"location":"Install-guide-Redhat-8/#before-installation","title":"Before installation","text":"

Please note that PostgreSQL YUM repository and Faraday, depend on EPEL repository for some packages. Users with RHEL, CentOS, etc. should install EPEL repo RPM along with PGDG repo RPMs to satisfy dependencies. In order to do that, follow these instructions:

If you are using RHEL, first run the following command:

Install EPEL using the following command:

yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm\n
Refresh repo by typing the following command:
yum repolist\n

"},{"location":"Install-guide-Redhat-8/#redhat8-installation-guide-for-postgresql","title":"RedHat8 Installation Guide for PostgreSQL","text":"
  1. Install PostgreSQL >= 9.6 (local or remote). Follow the Postgres installation guide for Redhat: Postgres(RedHat)

  2. Download Faraday installer (.rpm)

    • GitHub for Community Edition
    • Faraday Portal for Professional/Corporate
  3. Go to your Download directory and run the following command
    sudo yum install ./faraday-server_amd64.rpm\n

    If PostgreSQL is running in a remote machine please follow these instructions, if instead, it is running locally, you need to open the pg_hba.conf file.

There, you need to modify the localhost authentication type from \"ident\" to \"md5\". To do this, change host IPV4 local and IPV6 local from \"ident\" to \"md5\".

  1. Go to the file:
    $ nano /var/lib/pgsql/POSTGRESQL_VERSION/data/pg_hba.conf  \n
    Edit the following lines:
    # IPv4 local connections:\nhost all         all 127.0.0.1/32       md5\n# IPv6 local connections:\nhost all         all ::1/128       md5\n
  2. Once installed, add your user to the faraday group and re-login

    sudo usermod -aG faraday $USER\n

  3. Restart PostgreSQL server and initialize the database(first time only) This will generate a random password, use it for Faraday Web UI and change it

sudo systemctl restart postgresql-XX\n
sudo faraday-manage initdb\n

Important: In case of being in a SELinux environment run prior to the checks:

sudo setenforce 0\n
"},{"location":"Install-guide-Redhat-8/#redis-install","title":"Redis install","text":"
sudo dnf install redis\n
"},{"location":"Install-guide-Redhat-8/#importing-license","title":"Importing License","text":""},{"location":"Install-guide-Redhat-8/#step-1","title":"Step 1","text":"

Import license from Faraday Portal

faraday-manage import-license\n
In case of offline environment, check import license on Install Guide Advanced

"},{"location":"Install-guide-Redhat-8/#step-2","title":"Step 2","text":"
  1. Start and enable the autostart of Faraday server by running:
    systemctl start faraday-server\nsystemctl enable faraday-server\n\nsystemctl start faraday-worker\nsystemctl enable faraday-worker\n\nsystemctl start faraday-worker-reports\nsystemctl enable faraday-worker-reports\n

We highly recommend you to check our First Steps guide.

"},{"location":"Install-guide-Troubleshooting/","title":"Troubleshooting","text":""},{"location":"Install-guide-Troubleshooting/#pypigithub","title":"PyPI/GitHub","text":"

If you're getting the following error:

    Complete output from command python setup.py egg_info:\n    running egg_info\n    creating pip-egg-info/psycopg2.egg-info\n    writing pip-egg-info/psycopg2.egg-info/PKG-INFO\n    writing dependency_links to pip-egg-info/psycopg2.egg-info/dependency_links.txt\n    writing top-level names to pip-egg-info/psycopg2.egg-info/top_level.txt\n    writing manifest file 'pip-egg-info/psycopg2.egg-info/SOURCES.txt'\n    Error: b'You need to install postgresql-server-dev-NN for building a server-side extension or libpq-dev for building a client-side application.\\n'\n\n    ----------------------------------------\nCommand \"python setup.py egg_info\" failed with error code 1 in /tmp/pip-install-mkj8d84u/psycopg2/\n

If you never install PostgreSQL before, you must install it first, by doing this:

sudo apt install postgresql-12\n
or
sudo yum install postgresql-12\n

Once you installed this, run the pip3 command again.

pip3 install faradaysec\n
or
pip3 install .\n

"},{"location":"Install-guide-Troubleshooting/#nix","title":"Nix","text":"

directory /nix exists, but is not writable by you

If you never install Nix before, this error appears because you have installed Faraday server or client .deb or .rpm on the system. You must uninstall it first, by doing this:

sudo apt remove faraday-server\n
Once you uninstalled this, remove /nix directory and then run the Nix install again.

sudo rm -rf /nix\n

Error: while setting up the build environment: mounting /proc: Operation not permitted

This happens when running Nix on a container like LXC or similar. In theses cases, you should disable the sandbox.

First, create the following file:

~/.config/nix/nix.conf\n

Run the following command to add the flag to the file:

echo 'sandbox = false' >> ~/.config/nix/nix.conf\n

The, run the Nix install again.

"},{"location":"Install-guide-community/","title":"Community","text":""},{"location":"Install-guide-community/#install-guide","title":"Install Guide","text":"

In order to install Faraday Community version, you can use pip to install Faraday or you can clone the repository. Additionally you can either use our docker-compose.yml file that will install all in one place.

"},{"location":"Install-guide-community/#install-using-docker","title":"Install using Docker","text":"

git clone git@github.com:infobyte/faraday.git\ndocker-compose up -d\n
then run the following to check if the pod is running:

docker-compose ps\n
"},{"location":"Install-guide-community/#startup-docker-postgres","title":"Startup docker postgres","text":"
docker pull postgres\ndocker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d postgres\n
"},{"location":"Install-guide-community/#installation-from-pypi","title":"Installation from PyPI","text":"

You can install Faraday from PyPI by running the following command:

pip3 install faradaysec\n
"},{"location":"Install-guide-community/#installation-from-using-pip-from-source","title":"Installation from using pip from source","text":"
git clone git@github.com:infobyte/faraday.git\ncd faraday\npip install .\n
"},{"location":"Install-guide-community/#after-installation","title":"After Installation","text":"

Once the installation is completed, make sure you have a PostgreSQL (local or remote)

Then initialize the database This will generate a random password, use it for Faraday Web UI and change it

faraday-manage initdb\n

Start Faraday server by running:

As a service
sudo systemctl start faraday-server\n
As a process
faraday-server\n

We highly recommend you to check our First Steps guide.

"},{"location":"Jinja2-context/","title":"Jinja2 Context json","text":"

These are examples of jinja2 static dataset usage. You can access this information from the docx template.

Info

Executive reports use jinja for rendering the report, check jinja documentation for more details.

"},{"location":"Jinja2-context/#report-context","title":"Report Context","text":"Generic

This report lists all vulnerabilities of the workspace.

{\n    \"counter_severity\": <severities dict>,\n    \"date\": <datetime>,\n    \"enterprise\": format_text_docxtpl_patch(report.enterprise),\n    \"hosts\": <list host>,\n    \"hosts_amount\": <int>,\n    \"overview_images\": <image>,\n    \"vulnerabilities_image\": <image>,\n    \"ease_resolution_image\": <image>,\n    \"impact_image\": <image>,\n    \"services\": <list service>,\n    \"services_amount\": <int>,\n    \"title\": <str>,\n    \"vulns\": <list of vuln>,\n    \"vulns_amount\": <int>,\n    \"workspace\": <workspace_object>,\n   \"conclusions\": <string>,\n    \"objectives\": <string>,\n    \"recommendations\": <string>,\n    \"scope\": <string>,\n    \"summary\": <string>,\n    \"methodologies\": [<methodology>]\n}\n

Grouped

This type of report groups the data using the name and description of the vulnerability. vulns_grouped_amount number of vulnerabilities in the group.

{\n    \"counter_severity\": <dict severities>,\n    \"date\": <datetime>,\n    \"enterprise\": format_text_docxtpl_patch((report.enterprise)),\n    \"hosts\": <list host>,\n    \"hosts_amount\": <int>,\n    \"overview_images\": <image>,\n    \"vulnerabilities_image\": <image>,\n    \"ease_resolution_image\": <image>,\n    \"impact_image\": <image>,\n    \"services\": <list service>,\n    \"services_amount\": <int>,\n    \"title\": <str>,\n    \"vulns\": <list of vuln>,\n    \"vulns_amount\": <int>,\n    \"vulns_grouped_amount\": <int>,\n    \"workspace\":<str>,\n    \"conclusions\": <string>,\n    \"objectives\": <string>,\n    \"recommendations\": <string>,\n    \"scope\": <string>,\n    \"summary\": <string>,\n    \"methodologies\": [<methodology>]\n}\n

Inside each Template, in either of the two report Dataset, we can use these variables:

Host
{\n'_rev': '',\n'type': 'Host',\n'_id': 1,\n'versions': [],\n'owned': False,\n'mac': <str>,\n'os': 'Linux Kernel 3.8',\n'owner': None,\n'services': 1,\n'ip': '127.0.0.1',\n'default_gateway': '',\n'service_summaries': ['(80/tcp) www'],\n'tags': ['QA'],\n'credentials': 0,\n'description': '',\n'name': '127.0.0.1',\n'hostnames': ['localhost'],\n'metadata': {'create_time': <datetime>,\n'update_time': <datetime>,\n'creator': '',\n'update_controller_action': '',\n'owner': None,\n'command_id': None,\n'update_action': 0,\n'update_user': None},\n'id': 1,\n'vulns': 91\n}\n
Service
{\n'_rev': '',\n'type': 'Service',\n'_id': 1,\n'owned': False,\n'summary': '(80/tcp) http',\n'version': 'unknown',\n'parent': 4,\n'owner': None,\n'tags': ['QA'],\n'protocol': 'tcp',\n'credentials': 0,\n'port': <int>,\n'description': '',\n'name': 'http',\n'host_id': 4,\n'ports': 80,\n'metadata': {'create_time': <datetime>,\n'update_time': <datetime>,\n'creator': '',\n'update_controller_action': '',\n'owner': None,\n'command_id': None,\n'update_action': 0,\n'update_user': None},\n'id': 1,\n'vulns': 1,\n'status': 'open'\n}\n
Vulnerability
{\n'data': <SubDoc>,\n'vulnerability_duplicate_id': None,\n'confirmed': False,\n'_rev': '',\n'easeofresolution': None,\n'childs': [],\n'cvss3_vector_string' : <str>,\n'cvss3_base_score' : <float>,\n'cvss3_exploitability_score' : <float>,\n'cvss3_impact_score' : <float>,\n'cvss3_base_severity' : <str>,\n'cvss3_temporal_score' : <float>,\n'cvss3_temporal_severity' : <str>,\n'cvss3_environmental_score' : <float>,\n'cvss3_environmental_severity' : <str>,\n'cvss3_attack_vector' : <str>,\n'cvss3_attack_complexity' : <str>,\n'cvss3_privileges_required' : <str>,\n'cvss3_user_interaction' : <str>,\n'cvss3_confidentiality_impact' : <str>,\n'cvss3_integrity_impact' : <str>,\n'cvss3_availability_impact' : <str>,\n'cvss3_exploit_code_maturity' : <str>,\n'cvss3_remediation_level' : <str>,\n'cvss3_report_confidence' : <str>,\n'cvss3_confidentiality_requirement' : <str>,\n'cvss3_integrity_requirement' : <str>,\n'cvss3_availability_requirement' : <str>,\n'cvss3_modified_attack_vector' : <str>,\n'cvss3_modified_attack_complexity' : <str>,\n'cvss3_modified_privileges_required' : <str>,\n'cvss3_modified_user_interaction' : <str>,\n'cvss3_modified_scope' : <str>,\n'cvss3_modified_confidentiality_impact' = <str>,\n'cvss3_modified_integrity_impact' : <str>,\n'cvss3_modified_availability_impact' : <str>,\n'type': 'Vulnerability',\n'_id': 1,\n'severity': 'med',\n'refs': ['CVSS: 3.2'],\n'date': <datetime>,\n'owned': False,\n'parent': 1,\n'policyviolations': [],\n'resolution': 'Resolution text',\n'owner': None,\n'service': {'version': 'unknown',\n'name': 'postgresql',\n'protocol': 'tcp',\n'ports': 80,\n'_id': 1,\n'summary': '(80/tcp) http',\n'status': 'open'},\n'issuetracker': {},\n'update_user': None,\n'external_id': '1233',\n'tags': [],\n'vulnerability_template_id': None,\n'impact': {'accountability': False,\n'confidentiality': False,\n'integrity': False,\n'availability': False},\n'obj_id': '1',\n'custom_fields': {'list': None, 'integer': None, 'choice': None},\n'parent_type': 'Service',\n'description': 'Description',\n'host_os': 'Linux Kernel 4.8',\n'name': 'Vulnerability title',\n'_attachments': {},\n'hostnames': ['localhost'],\n'desc': <SubDoc>,\n'target': '127.0.0.1',\n'metadata': {'create_time': <datetime>,\n'update_time': <datetime>,\n'creator': 'OpenVAS',\n'update_controller_action': '',\n'owner': None,\n'command_id': 1,\n'update_action': 0,\n'update_user': None},\n'status': 'opened',\n'id': 1,\n'__target__': '127.0.0.1 / 80 / tcp'\n}\n
"},{"location":"LDAP-OKTA/","title":"LDAP with OKTA","text":"

Here are the steps to integrate LDAP to Faraday using OKTA:

Step 1: Navigate to OKTA's website.

Step 2: Sing up.

Remember your user and workdomain from user@workdomain.com

Step 3: Okta will send you an e-mail with the URL and your temporary password, use those to log-in into Okta.

Step 4: Enter to the Directory Integrations Label from your Okta URL.

Step 5: Click Add LDAP Interface

Step 6: Configure your Faraday Server.

Run the following command:

faraday-manage settings -a update ldap\n
enabled = true\nserver = <domain>.ldap.okta.com\ndomain_dn = OU=users, DC=<domain>, DC=okta, DC=com\ndomain =<domain>.okta.com\nadmin_group = fadmin\npentester_group = fpentester\nasset_owner_group = fassetowner\nclient_group = fclient\nuse_ldaps = true\nuse_start_tls = false\nport = 636\ndisconnect_timeout = 2.0\nuse_local_roles = true\ndefault_local_role = admin\nbind_format = DN\nbind_dn = dc=<domain>,dc=okta,dc=com\n

Check our LDAP Article if you need more info.

Step 7: Restart Faraday Server with:

systemctl restart faraday-server\n

Step 8: Login into Faraday with the User and Password you used to login into Okta.

Info

(Remember you can only access as an Admin user and you can't create more users).

"},{"location":"LDAP/","title":"LDAP Configuration","text":""},{"location":"LDAP/#ui-settings","title":"UI Settings","text":"

Using the LDAP integration has never been that easy, now with faraday UI you can use LDAP users and assign roles to the ldap groups, you can configure it going to upper right corner click on the User circle and then hit on preferences.

after this, click on preferences, and go to the Ldap section and click on the activate LDAP slider.

Follow the steps to complete the configuration. Don't forget click on the Save button on the upper corner.

"},{"location":"LDAP/#console-settings","title":"Console Settings","text":"

LDAP Users

For the time being Faraday doesn't support a hybrid installation using both LDAP and local users. Enabling LDAP disables local users and vice versa.

In order to configure LDAP, run the following command:

faraday-manage settings -a update ldap\n

Then update every field according to the configuration on-prem.

$ faraday-manage settings -a update ldap\nUpdate settings for: ldap\nenabled [False]:\nuse_local_roles [True]:\ndefault_local_role [admin]:\nadmin_group []:\nasset_owner_group []:\nclient_group []:\npentester_group []:\ndisconnect_timeout [2.0]:\nserver []:\nport [389]:\nuse_ldaps [False]:\nuse_start_tls [False]:\ndomain []:\ndomain_dn []:\nbind_format [CN]:\nbind_dn []:\nuser_class [user]:\nuser_attribute [sAMAccountName]:\ngroup_class [group]:\npaginated_fetch [False]:\nDo you confirm your changes on ldap?\n

Remember to restart the server after doing changes!

systemctl restart faraday-server\n

Warning

If use_local_roles is set to true, any user on the AD will be allowed to use Faraday.

"},{"location":"NGINX-Setup/","title":"NGINX (SSL Config)","text":"

The recommended way to run Faraday is using SSL via Nginx

If you use NGINX you need to generate swagger config to let it work over the domain

faraday-manage openapi-swagger --server https://your-fqdn-for-faraday.com

"},{"location":"NGINX-Setup/#nginx","title":"Nginx","text":"

New Faraday release 4.1.0 can generate a ngnix configuration for you

"},{"location":"NGINX-Setup/#installing-nginx","title":"Installing Nginx","text":"

You can find a detailed guide on how to install nginx in the official Nginx documentation

"},{"location":"NGINX-Setup/#configure-nginx","title":"Configure NGINX","text":"

After installing and configuring NGINX, Faraday's setup should be as follows:

Faraday Server on port 5985 using HTTP. You can find this configuration inside the file ~/.faraday/config/server.ini in section [faraday_server].\nWeb UI using https://example_domain:port/\n

Note: For both cases, NGINX on port 80 redirecting to HTTPS.

"},{"location":"NGINX-Setup/#generating-certificates","title":"Generating Certificates","text":"

In order to generate self signed certificates, run the following command:

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/faraday.key -out /etc/ssl/faraday.crt\n

Be sure to type the Common Name of this certificate. If you don't type a Common Name, then Faraday will not be launched.

For further information about certificates, follow this link.

"},{"location":"NGINX-Setup/#sample-configuration-files","title":"Sample Configuration Files","text":"

Below you can find a sample config files for NGINX. You can use this same configuration by pasting it inside the folder /etc/nginx/sites-enabled/ or in conf.d and naming the file as you want.

faraday-manage generate-nginx-config --fqdn faraday.mydomain.com --port 5985 --ws-port 9000 --ssl-certificate /etc/ssl/faraday.crt --ssl-key /etc/ssl/faraday.key\n
Generating Faraday nginx config for server: faraday.mydomain.com\nFaraday\n- Port: 5985\n- Websocket Port: 9000\nSSL: certificate [/etc/ssl/faraday.crt] - key [/etc/ssl/faraday.key ]\nConfirm [Y/n]: y\nNGINX Config\n#####################################\n\n\n# Expires map\nmap $sent_http_content_type $expires {\n    default                    off;\n    text/html                  max;\n    text/css                   max;\n    application/javascript     max;\n    ~image/                    max;\n}\n\nserver {\n    server_name faraday.mydomain.com;\n    listen 443 ssl http2;\n\n    add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains; preload\" always;\n    add_header X-XSS-Protection \"1; mode = block\";\n    add_header X-Frame-Options \"SAMEORIGIN\";\n    add_header X-Content-Type-Options nosniff;\n    client_max_body_size 150M;\n\n    ssl on;\n    ssl_session_cache shared:SSL:50m;\n    ssl_certificate           /etc/ssl/faraday.crt;\n    ssl_certificate_key       /etc/ssl/faraday.key\n    gzip on;\n    gzip_types application/javascript text/css;\n    expires $expires;\n\n    location / {\n        alias /opt/faraday/lib/python3.8/site-packages/faraday/server/www/;\n    }\n\n    location /_api/ {\n        proxy_pass http://localhost:5985/_api/;\n        proxy_redirect http:// $scheme://;\n        proxy_read_timeout 300;\n        proxy_cookie_path / \"/; secure\";\n\n        proxy_set_header Host $host;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Ssl on;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n\n    location /websockets {\n        proxy_http_version 1.1;\n        proxy_pass http://localhost:9000/websockets;\n\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n    }\n}\n\nserver {\n    server_name faraday.mydomain.com;\n    listen 80 ;\n\n    # https redirect\n    if ($host = faraday.mydomain.com) {\n        return 301 https://$host$request_uri;\n    }\n\n    return 404;\n}\n

Now you can access to https://faraday.mydomain.com

"},{"location":"Notifications-Slack/","title":"Configure Slack Notifications","text":""},{"location":"Notifications-Slack/#getting-ready-with-slack-configuration","title":"Getting Ready with Slack Configuration","text":"
  1. Go to https://api.slack.com/apps.
  2. Click on \u201cCreate New App.\u201d
  1. Select \"From an app manifest\"
  1. Choose the Slack workspace where you want to install the app.
  1. In step 2, paste the following manifest JSON data:
{\n    \"display_information\": {\n        \"name\": \"faraday-notifications\",\n        \"description\": \"Notifications for Faraday\",\n        \"background_color\": \"#82AFD9\"\n    },\n    \"features\": {\n        \"app_home\": {\n            \"home_tab_enabled\": false,\n            \"messages_tab_enabled\": true,\n            \"messages_tab_read_only_enabled\": true\n        },\n        \"bot_user\": {\n            \"display_name\": \"Faraday Notifications\",\n            \"always_online\": true\n        }\n    },\n    \"oauth_config\": {\n        \"scopes\": {\n            \"bot\": [\n                \"app_mentions:read\",\n                \"channels:join\",\n                \"channels:read\",\n                \"chat:write\",\n                \"chat:write.customize\",\n                \"chat:write.public\",\n                \"im:write\",\n                \"links:write\",\n                \"reactions:write\",\n                \"team:read\",\n                \"usergroups:read\",\n                \"users:read\",\n                \"users:write\"\n            ]\n        }\n    },\n    \"settings\": {\n        \"event_subscriptions\": {\n            \"bot_events\": [\n                \"app_mention\"\n            ]\n        },\n        \"interactivity\": {\n            \"is_enabled\": true\n        },\n        \"org_deploy_enabled\": false,\n        \"socket_mode_enabled\": true,\n        \"token_rotation_enabled\": false\n    }\n}\n
  1. Click on \u201cCreate.\u201d
  2. Click on \u201cOAuth & Permissions.\u201d and Install it \u201cOrg-wide.\u201d

Note: Obtain the OAuth token for later use by pasting it into Faraday.

  1. Click on \u201cAdd apps,\u201d locate the faraday-notifications app, and add it.
  2. Get your Slack ID from your Slack profile and paste it into Faraday.
"},{"location":"Notifications-Slack/#configure-your-slack-integration","title":"Configure your Slack integration","text":"

Using the OAuth token and your Slack ID, you can configure Slack notifications. Use the shortcut button from the Notifications Settings to be redirected to the Slack configuration in Faraday's Preferences and paste the token and your Slack ID obtained in the steps above.

Info If your role differs from an administrator, you only need to paste your Slack ID. For the integration to work, an administrator must initially paste the OAuth token into their own Faraday account.

"},{"location":"Notifications/","title":"Notification Center","text":"

Faraday's Notification Center feature is tailored to bolster your organization's security posture by delivering timely and customizable alerts related to vulnerabilities, threats, and all other available Faraday features within your license.

"},{"location":"Notifications/#notification-settings","title":"Notification Settings","text":"

You can configure notifications through the Notifications section located in the left panel.

Currently, there are various System Notification Categories available for configuration:

  • Agents
  • Assets
  • Comments
  • Pipelines
  • Planner
  • Reports
  • Users
  • Vulnerabilities
  • Workspaces

The configuration options for each category are contingent upon your license and role.

For users with a Corporate License and Administrator role, all categories are available for configuration by default.

By default, all in-app notifications are enabled. You have the option to disable an entire category using the toggle switch on the left. Disabling a category will halt notifications within that category from reaching you.

If you enable the EMAIL option, notifications from the enabled category will be dispatched to the email address linked to your user account.

Enabling the SLACK option will direct notifications from the enabled category to your Slack workspace (please refer to the Slack integration section for details on configuring Slack).

Typically, notifications for each category are designed to keep users informed about changes in the workspace where they are assigned. Planner notifications specifically inform users about updates to tasks they are assigned or were assigned to. Notifications will not be sent to users without permissions to access the relevant workspace, regardless of whether they have enabled the category.

Though notifications are primarily designed to inform users about background activity or changes initiated by other platform users, users can tailor their notification settings to receive notifications related to their own activity. You can achieve this by toggling on the \"Notify me about my own activity\" button.

Additionally, you can temporarily pause all notifications using the pause button. This action will halt all notifications to any channel until you choose to resume them using the resume button.

"},{"location":"Notifications/#notifications-log","title":"Notifications Log","text":"

Notifications from all enabled categories will be logged. This log contains a history of all notifications.

Each row in the log represents a notification and includes a brief description, the category it belongs to, who triggered it, and the exact time it was generated.

You can mark all notifications as read using the button. Rows can be selected using the checkbox on the left of each row and deleted using the delete button.

Clicking on a notification row will redirect you to the source of the notification, such as the updated vulnerabilities or planner tasks assigned to you.

"},{"location":"Notifications/#in-app-notifications","title":"In-App Notifications","text":"

If you select the IN-APP column in the Notification Settings, notifications from the selected category will also appear in the Notifications Bell located at the top right. Clicking on the bell will display the last 4 notifications in a dropdown menu.

A red indicator shows the number of unread notifications in the notification log. You can view all unread notifications by clicking on it at the bottom of the dropdown menu. This action redirects you to the Notifications Log, where you can find both unread and read notifications.

Notifications displayed in the bell, like those in the notification log, can be clicked to be redirected to the source of the notification.

"},{"location":"Notifications/#email-notifications","title":"Email Notifications","text":"

If you select the EMAIL column in the Notification Settings, notifications from the selected category will also be sent to the email address configured in your user account.

"},{"location":"Notifications/#slack-notifications","title":"Slack Notifications","text":"

If you select the SLACK column in the Notification Settings, notifications from the selected category will be sent to your Slack account. To enable this integration, a Faraday admin user must complete the steps outlined in the following section.

"},{"location":"Pipelines/","title":"Pipelines and jobs","text":"

We were thinking on a pain solver in case of importing manually files, or working with the vulnerabilities massively in your Workspace.

Faraday created pipelines designed exclusively to automate and change vulnerabilities applying custom Job rules, according to patterns inside a name or any attribute inside a Vulnerability.

The hierarchy will be Jobs are run inside Pipelines. The first view will show in the left the pipelines, and clicking on one title, will show the configuration of each.

Jobs will run sequentially inside a Pipeline to a Target Workspace. If you click on Create New the Jobs view will be opened.

In this view is needed to setup a Name, Description and Object and Attributes.

Based on Two models, Assets and Vulnerability. it can be added Rules and Tasks

Rules are sets of attributes based on the vulnerability, such as Name, Description, Tag, etc. The operators for the rules are equal, not equal and contains, using the operators the rule can be created.

The Tasks contain Actions these can be Update, Append and Delete the object. The last option will delete the object that matches the condition, this is used to Delete the Vulnerability. The action Update will select a Field based on this condition and update it to the value selected in the Action to the desired Value. Append is useful to create an attribute such as Tag, Comment or Policy Violation. in Case of Comments a user can be addressed with a \"@\" symbol.

Click on Save on the up right Corner.

Select The Target Workspace and click on Save

From the Enable slide the pipeline can be either enabled or disabled, and from the Run Button the pipeline can be manually triggered.

"},{"location":"Planner/","title":"Planner","text":"

Organize your vulnerabilities and get work done easily and comfortably without using any extra platforms. Be more productive and share work with your team. Task assignment, status, alerts, and more: manage the progress of your vulnerabilities in one place.

The overview page can be accessed using the planner icon .

The sections are divided by Project, inside project Tasks/Milestones can be created, those can be assigned to users, and have dependencies.

The Task can be appended hovering in a project and clicking on the Add Task Button.

The task can contain values such start/end date, progress, description and Assigned users and Dependencies

Click on Create and the task will be assigned inside the Project

A task can have linked Vulnerabilities, from the Quick Planner module from Vulnerabilies view

Refer to Vulnerability view document to assign a vulnerabilty to a task from the Quick Planner view.

"},{"location":"Plugin-List-v4/","title":"Supported-Plugins","text":"

The main purpose of Faraday is to re-use the available tools in the community to take advantage of them in a multiuser way.

You break it. We keep track of the pieces!

To maximize flexibility Faraday Plugins run only on the client, which means you can have custom, private plugins all for yourself!

There are three kinds of plugins available for Faraday; console, report and API also called online. However, these are not mutually exclusive, meaning that some tools have more than one Plugin to process their output. For example, Nmap has a Console plugin which allows you to run it directly from ZSH, but it also has a Report one, in order to import scans that were run outside of Faraday.

"},{"location":"Plugin-List-v4/#console","title":"Console","text":"

Check Faraday-Cli to use this feature!

Plugins that intercept commands, fired directly when a command is detected in the console. These are transparent to you and no additional action on your part is needed.

"},{"location":"Plugin-List-v4/#report","title":"Report","text":"

Use the web UI to import reports. Check this Article!

"},{"location":"Plugin-List-v4/#api","title":"API","text":"

Plugin connectors or online (BeEF, Metasploit, Burp), these connect to external APIs or databases, or talk directly to Faraday's API.

"},{"location":"Plugin-List-v4/#custom","title":"Custom","text":"

If you think your favourite tool is missing code your own plugin or ask us to do it!

The following table contains name, id, command or report, in the case of command it is that the command can be used inside faraday-cli and it gets imported into faraday after the run, for report it means that the file can be imported in the Faraday IU.

Name ID Command Report Acunetix XML Output Plugin Acunetix No Yes Acunetix360 Output Plugin Acunetix360 No Yes Acunetix JSON Output Plugin Acunetix_Json No Yes Amap Output Plugin Amap Yes No Appscan XML Plugin Appscan No Yes Appscan CSV Output Plugin Appscan_CSV No Yes AppSpider XML Output Plugin AppSpider No Yes Arachni XML Output Plugin Arachni Yes Yes arp-scan network scanner arp-scan Yes No AWS Inspector JSON Output Plugin AWSInspector_Json No Yes Bandit XML Output Plugin Bandit No Yes BeEF Online Service Plugin Beef Yes No brutexss brutexss Yes No Burp XML Output Plugin Burp No Yes Checkmarx XML Output Plugin Checkmarx No Yes CIS XML Output Plugin CIS No Yes Cobalt CSV Output Plugin Cobalt No Yes Crowdstrike JSON Output Plugin Crowdstrike_Json No Yes DiG dig Yes No Dirb dirb Yes No dirsearch dirsearch Yes No Dnsenum XML Output Plugin Dnsenum Yes No Dnsmap Output Plugin Dnsmap Yes No Dnsrecon XML Output Plugin Dnsrecon Yes No Dnswalk XML Output Plugin Dnswalk Yes No Faraday CSV Plugin faraday_csv No Yes Faraday Json Faraday_JSON No Yes Fierce Output Plugin Fierce Yes No Fortify XML Output Plugin Fortify No Yes Ftp ftp Yes No Goohost XML Output Plugin Goohost Yes No Grype JSON Plugin grype Yes Yes hping3 Hping3 Yes No Hydra XML Output Plugin Hydra Yes No Core Impact XML Output Plugin CoreImpact No Yes Invicti XML Output Plugin Invicti No Yes Ip360 CSV Output Plugin Ip360 No No Junit XML Output Plugin Junit No Yes Kubescape Json Kubescape_JSON No Yes Lynis DAT Output Plugin Lynis Yes Yes Maltego MTGX & MTGL Output Plugin Maltego No Yes Microsoft Baseline Security Analyzer MBSA No Yes Medusa Output Plugin Medusa Yes No Metasploit XML Output Plugin Metasploit No Yes Naabu naabu Yes Yes ncrack XML Plugin ncrack No Yes ndiff Ndiff Yes No Nessus XML Output Plugin Nessus No Yes Nessus Sc Output Plugin Nessus_sc No Yes netdiscover Netdiscover Yes No Netsparker XML Output Plugin Netsparker No Yes NetsparkerCloud XML Output Plugin NetsparkerCloud No Yes Nexpose XML 2.0 Report Plugin NexposeFull No Yes nextnet nextnet Yes No Nikto XML Output Plugin Nikto Yes Yes Nipper XML Output Plugin Nipper No Yes Nmap XML Output Plugin Nmap Yes Yes Nuclei nuclei Yes Yes Nuclei nuclei_legacy Yes Yes OpenScap XML Output Plugin OpenScap No Yes Openvas XML Output Plugin Openvas No Yes pasteAnalyzer JSON Output Plugin pasteAnalyzer Yes No PeepingTom peepingtom Yes No Pentera Json Output Plugin Pentera_Json No Yes Ping ping Yes No Ping Castle XML Output Plugin PingCastle No Yes Popeye JSON Output Plugin Popeye_Json No Yes propecia port scanner propecia Yes No Prowler prowler No Yes Prowler prowler_legacy No Yes Qualysguard XML Output Plugin Qualysguard No Yes QualysWebapp XML Output Plugin QualysWebapp No Yes rdpscan rdpscan Yes No Reconng XML Output Plugin Reconng No Yes Retina XML Output Plugin Retina No Yes Reverseraider XML Output Plugin Reverseraider Yes No Sarif Plugin Sarif No Yes Semgrep Json Semgrep_JSON No Yes Shodan shodan Yes Yes Skipfish Output Plugin Skipfish Yes No Snyk Snyk No Yes SonarQube API Plugin sonarqubeAPI No Yes Sourceclear sourceclear No Yes sshdefaultscan sshdefaultscan Yes No SSL Labs ssllabs No Yes Sslyze Plugin Sslyze_XML No Yes Sslyze Json Sslyze_JSON Yes Yes Syhunt XML Plugin Syhunt No Yes Telnet Telnet Yes No Terraform Plugin JSON Output Plugin TerraformPluginJson No Yes Theharvester XML Output Plugin Theharvester Yes No Traceroute Traceroute Yes No Trivy JSON Output Plugin Trivy_Json No Yes W3af XML Output Plugin W3af Yes Yes Wapiti XML Output Plugin Wapiti Yes Yes Wcscan XML Output Plugin Wcscan Yes No Webfuzzer Output Plugin Webfuzzer Yes No Webinspect Webinspect No Yes Wfuzz Plugin Wfuzz Yes No WhatWebPlugin whatweb No Yes whitesource whitesource No Yes Whois whois Yes No Windows Defender Jsonl WindowsDefender_JSONL No Yes WPscan wpscan Yes Yes Onapsis X1 XML Output Plugin X1 Yes Yes xsssniper xsssniper Yes No Zap XML Output Plugin Zap No Yes Zap Json Output Plugin Zap_Json No Yes

References to the Tools:

  • Acunetix (REPORT) (XML)
  • Amap (CONSOLE)
  • Appscan (REPORT)
  • AppSpider (REPORT)
  • Arachni (REPORT, CONSOLE) (XML)
  • arp-scan (CONSOLE)
  • AWS Prowler (REPORT)
  • Bandit (REPORT)
  • BeEF (API)
  • Brutexss (REPORT)
  • Burp, BurpPro (REPORT, API) (XML)
  • Core Impact, Core Impact (REPORT) (XML)
  • Dig (CONSOLE)
  • Dirb (CONSOLE)
  • Dirsearch (REPORT,CONSOLE)
  • Dnsenum (CONSOLE)
  • Dnsmap (CONSOLE)
  • Dnsrecon (CONSOLE)
  • Dnswalk (CONSOLE)
  • evilgrade (API)
  • Fierce (CONSOLE, REPORT)
  • Fortify (REPORT)
  • Fruitywifi (API)
  • ftp (CONSOLE)
  • Goohost (REPORT, CONSOLE) (XML)
  • hping3 (CONSOLE)
  • Hydra (CONSOLE) (XML)
  • Ip360 (REPORT)
  • Junit (REPORT)
  • Lynis (REPORT)
  • Maltego (REPORT)
  • Microsoft Baseline Security Analyzer (REPORT)
  • Medusa (CONSOLE)
  • Metasploit, (REPORT, API) (XML) XML report
  • Naabu (CONSOLE) (REPORT)
  • Ncrack (REPORT)
  • Ndiff (REPORT, CONSOLE)
  • Nessus, (REPORT) (XML .nessus)
  • Netdiscover (CONSOLE)
  • Netsparker (REPORT) (XML)
  • Netsparker Cloud (REPORT)
  • Nexpose, Nexpose Enterprise, (REPORT) (simple XML, XML Export plugin (2.0))
  • NextNet (CONSOLE)
  • Nikto (REPORT, CONSOLE) (XML)
  • Nipper (REPORT)
  • Nmap (REPORT, CONSOLE) (XML)
  • Nuclei (REPORT)
  • OpenScap (REPORT)
  • Openvas (REPORT) (XML)
  • PasteAnalyzer (CONSOLE)
  • Peeping Tom (CONSOLE)
  • ping (CONSOLE)
  • propecia (CONSOLE)
  • Qualysguard (REPORT) (XML)
  • QualysWebApp (REPORT)
  • rdpscan (CONSOLE)
  • Recon-NG (REPORT)
  • Retina (REPORT) (XML)
  • Reverseraider (CONSOLE)
  • Shodan (API)
  • Skipfish (CONSOLE)
  • SonarQube (REPORT)
  • SourceClear (REPORT)
  • SSHdefaultscan (CONSOLE)
  • SSL Labs (REPORT)
  • SSLyze (REPORT, CONSOLE) (XML)
  • Sublist3r (REPORT,CONSOLE)
  • Telnet (CONSOLE)
  • Theharvester (CONSOLE)
  • Traceroute (CONSOLE)
  • W3af (REPORT) (XML)
  • Wapiti (CONSOLE)
  • Wcscan (CONSOLE)
  • WebInspect (REPORT,CONSOLE)
  • Wfuzz (CONSOLE)
  • Wfuzz (CONSOLE)
  • WhatWebPlugin (REPORT)
  • WhiteSource (REPORT)
  • whois (CONSOLE)
  • WPScan (CONSOLE)
  • Xsssniper (REPORT)
  • X1, Onapsis (REPORT) (XML)
  • Zap (REPORT) (XML)
"},{"location":"RELEASE/","title":"New features in the latest update","text":""},{"location":"RELEASE/#520-mar-12th-2024","title":"5.2.0 [Mar 12th, 2024]:","text":"
  • [MOD] Remove websockets port from docker-compose. #7679
  • [FIX] Fix hosts stats when bulk delete is applied to vulns. #7676
  • [FIX] Fix agents status from database. We were not updating the agent's status on faraday-server restarts. #7677

Changes in Faraday Professional: * [ADD] Add the possibility to see and edit personal information of non Admin users. #7622 * [MOD] Improved global_host endpoint performance. #7674

Changes in Faraday Corporate: * [ADD] Add active field to ticketing tools integrations. #7555

"},{"location":"RELEASE/#511-feb-9th-2024","title":"5.1.1 [Feb 9th, 2024]:","text":"
  • [FIX] Improve of host view performance.
"},{"location":"RELEASE/#510-feb-8th-2024","title":"5.1.0 [Feb 8th, 2024]:","text":"
  • [ADD] Performance improved in assets views making several vulnerabilities stats statics in asset's model. #7634
  • [ADD] Now custom fields are available for filtering vulnerabilities. Also add date type for custom fields. #7625
  • [MOD] Modify analytics type enum. #7615
  • [MOD] We changed the order in which we set the path constant of faraday_home in order to fix a bug with faraday_manage when is installed by deb/rpm. #7653
  • [FIX] Fix references. #7648

Changes in Faraday Professional: * [ADD] Add commit to recalculate risk API call. #7575 * [ADD] Add split function to jinja sandboxed environment. #7590 * [FIX] Now the pattern of grouped templates is searched also inside tables. #7637

  • Changes in Faraday Corporate:
  • [ADD] Advanced notifications. #7549
  • [FIX] There was a bug when adding references through the enrichment modules. #7647
"},{"location":"RELEASE/#501-jan-2nd-2024","title":"5.0.1 [Jan 2nd, 2024]:","text":"
  • [MOD] Code refactor.

Changes in Faraday Professional: * [FIX] Restore websockets notifications logic. #7640 * [FIX] Command status update fixed when no hosts parsed. #7636 * [FIX] Exception handler added in order to check malformed cvss vector strings. #7638

Changes in Faraday Corporate: * [FIX] Now current flask context is valid for faraday-manage integrations rsa commands. #7639

"},{"location":"RELEASE/#500-dec-13th-2023","title":"5.0.0 [Dec 13th, 2023]:","text":"
  • [ADD] Breaking change We now use Celery as the main way to import reports. In addition, we have removed twisted and replaced raw websockets with socket.io. #7352
  • [ADD] Added option to faraday-server to run workers. #7623

Changes in Faraday Professional: * [FIX] Update the pypandoc arguments to eliminate deprecation warnings. #7536

"},{"location":"RELEASE/#462-nov-10th-2023","title":"4.6.2 [Nov 10th, 2023]:","text":"
  • [ADD] Exclude unnecessary fields from VulnerabilitySchema in filter endpoint. #7608

Changes in Faraday Professional: * [FIX] Bug fixed when attribute_identifier was defined but not present in saml. #7618

"},{"location":"RELEASE/#461-oct-19th-2023","title":"4.6.1 [Oct 19th, 2023]:","text":"
  • [ADD] New exclude_stats query param in workspace endpoint. #7595
  • [MOD] Optimize hosts API when stats aren't needed. #7596
  • [FIX] Filter .webp files in vulns attachment endpoint because CVE-2023-4863. #7603

Changes in Faraday Professional: * [FIX] Improve the way that CSRF token errors are showed. #7553 * [FIX] object_type for report custom logo. #7464

Changes in Faraday Corporate: * [ADD] Add new analytics endpoint vulnerabilities_by_risk_score. #7412 * [ADD] Add option in saml settings to search for roles when creating new users. #7428

"},{"location":"RELEASE/#460-sep-6th-2023","title":"4.6.0 [Sep 6th, 2023]:","text":"
  • [FIX] Delete Cascade from KB. #7569

Changes in Faraday Professional: * [MOD] New notification center. #7385

Changes in Faraday Corporate: * [FIX] Allow multiple tags per job. #7530 * [MOD] Added tags as job action. #7520 * [MOD] Allow more user roles to use the enrichment API. #7517

"},{"location":"RELEASE/#452-jul-26th-2023","title":"4.5.2 [Jul 26th, 2023]:","text":"
  • [FIX] Add pango as an external requirement for nix to fix compatibility issues. #7535
"},{"location":"RELEASE/#451-jul-15th-2023","title":"4.5.1 [Jul 15th, 2023]:","text":"
  • [FIX] Fix pillow version to 9.4.0. #7531
"},{"location":"RELEASE/#450-jul-7th-2023","title":"4.5.0 [Jul 7th, 2023]:","text":"
  • [MOD] Upgrade nixpkgs version to 23.05. Also update version of packages in requirements. #7518
  • [FIX] Add missing scope cvss3 field. #7493
  • [FIX] Improve performance in hosts and hosts/filter views. #7501

Changes in Faraday Professional: * [MOD] Now the users that are used in the jira integration needs to be added manually. Also add endpoint to add and remove jira users for jira integrations. #7512 * [FIX] Now Schedule will require and use timezone. #7485

"},{"location":"RELEASE/#440-may-29th-2023","title":"4.4.0 [May 29th, 2023]:","text":"
  • [ADD] Now it's possible to modify the host or service assigned of a vulnerability. #7476
  • [MOD] Now /get_manifest separates the optional environment variables from the rest. #7481
  • [FIX] Add not_any filter operator which will retrieve results that not contains the value requested. #7394
  • [FIX] Make get_manifest compatible with all versions of dispatcher. #7500

Changes in Faraday Professional: * [FIX] Now we show the correct import license url when no installed license was found. #7402 * [FIX] ThreadFix Api export. #7489 * [FIX] Now when uploading a report faraday will check if the host is already on the database. #7495

Changes in Faraday Corporate: * [ADD] Add upload executive report templates. #7250 * [ADD] Add new logic for sn_vul_app_vulnerable_item table. #7429

"},{"location":"RELEASE/#435-apr-12th-2023","title":"4.3.5 [Apr 12th, 2023]:","text":"
  • [FIX] Modify migration with autocommit. #7487
"},{"location":"RELEASE/#434-apr-3rd-2023","title":"4.3.4 [Apr 3rd, 2023]:","text":"
  • [FIX] Fix bandit vulns. #7430
  • [FIX] Return public IP when behind a proxy. #7417
  • [ADD] Add report_template as an object type. #7463 Changes in Faraday Professional:

  • [ADD] Add set_tags method to service and host views and add service_tags and host_tags to tag view. #7451

  • [MOD] Check if tag is empty string in set_tags. #7469 Changes in Faraday Corporate:

  • [MOD] Rollback jira integrations to use faraday users. #7467

  • [MOD] Change permission for Jira endpoint to allow pentesters users connect and send issues to jira. #7403
  • [MOD] Refactor jira integration into jira_cloud_integration and jira_prem_integration. #7244
  • [FIX] Clone and update now gets the correct markdown value of old executive report. #7413
"},{"location":"RELEASE/#433-feb-9th-2023","title":"4.3.3 [Feb 9th, 2023]:","text":"
  • [FIX] Add tags columns in AgentSchedule model in white version. #7341
  • [FIX] Now sending a patching a vuln with empty list will remove all the relationships with all references. #7405
  • [FIX] Migration cascade on KB #7396
  • [FIX] Migration cascade on KB #7396 [Changes in Faraday Professional:]
  • [FIX] add nested sessions in concurrency process. #7329
  • [ADD] Now set tags accepts filters if no vulns ids are passed. #7357 [Changes in Faraday Corporate:]
  • [FIX] Adapt get_jira_users for jira cloud. #7406
  • [MOD] Now the users list when sending a vuln to jira are jira's users with CREATE_ISSUE and ASSIGNABLE_USER permission #7177
  • [ADD] Attachment's type validation addition in pdf executive reports generation. #7364
  • [ADD] Add mkdir for ticketing tools directories of custom templates. #7401
  • [MOD] Modify context of references for integrations templates. #7397
"},{"location":"RELEASE/#432-jan-3rd-2023","title":"4.3.2 [Jan 3rd, 2023]:","text":"
  • Change column type of advanced field in executive reports
  • Change column type of advanced field in executive reports
  • [MOD] Modify empty fields comparison criteria in Executive Reports
  • [FIX] Fix memory use when generating executive reports
  • [MOD] Modify empty fields comparison criteria in Executive Reports
  • [ADD] Use of the trending enrichment field to tag vulnerabilities and also calculate risk.
  • [ADD] Total risk average and counters of vulnerabilities that have their risk below/above average.
  • [FIX] Risk calculation execution inside vulnerabilities pipeline.
"},{"location":"RELEASE/#431-dec-15th-2022","title":"4.3.1 [Dec 15th, 2022]:","text":"
  • [ADD] Workspace api stats refactor
"},{"location":"RELEASE/#430-dec-1st-2022","title":"4.3.0 [Dec 1st, 2022]:","text":"
  • [FIX] Update the associated command when a agent execution return empty
  • [ADD] cvss3 scope field to vulnerability schema
  • [ADD] Add cvss\u2154 and cwe to export_csv
  • Improve command object creation in bulk create.
  • Fix open and closed stats in ws filter endpoint.
  • Add error command status in every validation of reports upload process
  • [ADD] BulkDelete with filters
  • Change filter logic on numeric fields.
  • Fix order of vulnerabilities in executive reports. Also add some graphics in templates.
  • [MOD] For security disable custom plugins on cloud
  • [MOD] Add an optional custom logo to executive reports
  • [ADD] Add command to load configuration samples
  • Added vuln history to bulk create
  • [FIX] severity description in risk schema when risk is 0 or null.
  • Added cve, cwe, cvss score and risk score to conditions
  • Add enrichment database key with creation date information in config api
  • [ADD] risk stats in workspace endpoint.
  • Add risk score field into Corporate Executive Reports
"},{"location":"RELEASE/#420-oct-27th-2022","title":"4.2.0 [Oct 27th, 2022]:","text":"
  • Add stats param in hosts endpoint.
  • [FIX] Now get agents dosent returns tokens
  • [FIX] Now when a constrain is violated faraday use the actual object to query if there is another object
  • [MOD] Improve agents logs
  • Add global commands and summary field in command's model Changes in Faraday Professional:
  • [FIX] Check if AgentScheduler has tags before running
  • [FIX] Fix agents_schedule/id/run endpoint adding user_id to get_command_and_agent_execution function Changes in Faraday Corporate:
  • Add vulnerability enrichment and risk calculation
  • [ADD] Settings to enable enrichment
  • Fix executive reports template for grouped vulnerabilities with markdown.
  • Upload new executive report templates
"},{"location":"RELEASE/#410-sep-12th-2022","title":"4.1.0 [Sep 12th, 2022]:","text":"
  • Improve the speed of bulk create by adding multiprocessing.
  • Abort with status_code 503 when try to send vulns with ticketing tools with a template that not exists
  • [MOD] Asset owners now can tag vulns
  • Fix showing data of vulns with same parent in grouped executive reports. Also separate website and path on templates.
  • Add create_date to possible fields on conditions of workflow
  • Add tool and external_id to pipelines
"},{"location":"RELEASE/#404-jul-28th-2022","title":"4.0.4 [Jul 28th, 2022]:","text":"
  • Remove workspaces agents relationship an now agent can run to multiple workspaces
  • Fix migration f82a9136c408 checking if index and constrains exist before deleting
  • Added count to vulns closed
  • Fix order_by cve_instances__name when no filter was provided
  • Add index into vulnerability Changes in Faraday Professional:

  • Add user_type field to the return of users API Changes in Faraday Corporate:

  • Improved regex of username for notifs

  • User cant delete self
  • Add list_usernames endpoint to users
"},{"location":"RELEASE/#403-jun-16th-2022","title":"4.0.3 [Jun 16th, 2022]:","text":"
  • Replace usage of strings for user_types enumerator constants
  • Increase the default duration of faraday token
  • Fix order by Role in Filters API
  • Refactor of bulk create API
  • Remove attachments and attachments_count properties from vulnerability. This improves performance.
  • Get token from user model
  • Ignore info and dns resolution as params when uploading report
  • Replace usage of is_ldap field of User model for user_type
  • Add user type enumerator
  • Add weight in role model to sort arbitrarily
  • Move export CSV from its own endpoint to /filter endpoint as a request's argument
  • Fix count in filter
  • Add endpoint to get top 10 most repeated vulns' name
  • Prevent Admin from changing role of self
  • Fix bug with grouped report using markdown
  • Add top ten most affected hosts analytics
  • Add analytics clone
  • Add analytics monthly reports
  • Add endpoint to get vulnerabilities' severities per hosts
  • Fix pipelines creating empty comments
  • Add Analytics vulnerabilities by status and by severity
  • Allow numeric users to be created
  • Change the date to epoch in planner task api
"},{"location":"RELEASE/#402-apr-4th-2022","title":"4.0.2 [Apr 4th, 2022]:","text":"
  • models.py refactor
  • add check to see if workspace name is longer than 250 characters. In that case raises an error
  • Generate token with pyjwt
  • allow to use email as username
  • User filter api only show LDAP users if enabled
  • Change 'user' data type field parser in order to use Faraday's usernames
  • Added planner feature
  • Fix last_login for saml login
"},{"location":"RELEASE/#401-mar-18th-2022","title":"4.0.1 [Mar 18th, 2022]:","text":"
  • Improve the logs Changes in Faraday Professional:
  • Remove comments' column from CSV exporter
  • Add a piechart of status of vulns to reports
"},{"location":"RELEASE/#400-feb-25th-2022","title":"4.0.0 [Feb 25th, 2022]:","text":"
  • Add a None limit and 0 offset to GET queries.
  • Truncate response and requests in reports
  • Full refactor of Workflows
"},{"location":"RELEASE/#3190-dec-27th-2021","title":"3.19.0 [Dec 27th, 2021]:","text":"
  • ADD v3 bulks endpoints DELETE and EDIT (PATCH)
  • Add logs of login, logout and log error to main log
  • Fix bug in bulk update for m2m fields
  • ADD clear settings command
  • Add open medium, high and critical vulns histogram
  • Fix integrity constraint error on cve update
  • FIX static content for react
  • Add cvss within vulnerability model
  • add check to see if workspace name is longer than 250 characters. In that case raises an error
  • change concat in urlstrings for join or urljoin
  • Add cve to csv export
  • limited the version of Weasyprint to <53
  • review of the reports code
  • Add workspace data to comment notification. Also fix agentexecution notification.
  • ADD save in history if vuln is re-opened
  • FIX vuln description in grouped reports
  • add auth to preference endpoint
  • FIX notification data fields with None value
  • Add notification websocket server
  • filter users field in ws endpoint
  • Change the hardcoded roles for the roles defined in faraday/server/models.py User
  • Change warning log to debug
  • add endpoint for getting Jira public key
  • clean not used imports
  • Fixes in workflows
  • ADD cache to integration configuration
  • ADD SAML Auth
"},{"location":"RELEASE/#3181-nov-5th-2021","title":"3.18.1 [Nov 5th, 2021]:","text":"

Fix CVE issue

"},{"location":"RELEASE/#3180-oct-21st-2021","title":"3.18.0 [Oct 21st, 2021]:","text":"
  • Remove attachments in vulns filter endpoint
  • Add open and confirmed vulns in workspace stats
  • Add migration disabling several notifications.
  • Add user id to session API endpoint
  • Add cve to vulnerability model
  • Change funcs to views
  • FIX report import
  • Add last_run_agent_date field to workspace endpoint
  • Fix cve parsing in vulnerability create and bulk create
  • ADD check if postgres db is running during server start
  • Fix order_by in filters api
  • Fix 500 status code with invalid executor arguments

Changes in Faraday Professional:

  • Add vuln stats in reports within hosts and workspace entities
  • create user validates if users_limit is reached
  • return 'null date' if pass to method a null or timestamp == 0
  • remove unused code, dont inform if hosts used are > 4000
  • Add obj history into notification data payload
  • FIX issue with images and markdown
  • Fix agent token api auth
  • Fix use of notification_enabled config variable in notifier logic
  • Update report templates to new logo
  • Add object and event types cache for notification event creation
  • Fix logs and validation. Also add try/catch in notification event creation.
  • Fix comments in filtered executive reports
  • Disable render request and response in PDF templates
  • Filter schedulers by workspace and executors to prevent remove all workspace's schedulers
  • add statics to avoid a crash when dont has a valid licence
  • Fix issue with second jinja rendering

Changes in Faraday Corporate:

  • Add vuln's link in Jira's issue description
  • MOD Search filter API is now usable by all roles
  • change whoami to view
  • FIX error creating workflow
  • Add option to merge multiple vulnerabilities into one Jira issue
  • Improve Jira's custom fields
  • Set required key to a Jira custom field
  • FIX ldap group issue
  • Replace Jira templates with fields text that accepts Jinja2 syntax for the issue's name and description
"},{"location":"RELEASE/#3172-aug-27th-2021","title":"3.17.2 [Aug 27th, 2021]:","text":"

Changes in Faraday Professional:

  • FIX ignore for now the notification functions as it's only v4 feature

Changes in Faraday Corporate:

  • FIX asset owner is again allowed to edit vulnerabilities' status
"},{"location":"RELEASE/#3171-aug-20th-2021","title":"3.17.1 [Aug 20th, 2021]:","text":"
  • FIX bug when starting the server, creates a pool for reporting that breaks.
"},{"location":"RELEASE/#3170-aug-10th-2021","title":"3.17.0 [Aug 10th, 2021]:","text":"
  • ADD --data parameter to faraday-manage settings
  • MOD Process report files in a separate process
  • MOD Make bulk_create requests asynchronous

Changes in Faraday Professional:

  • ADD All features are now controlled by license with more granularity
  • ADD --mail parameter to faraday-manage initdb
  • MOD Limit creation of hosts when licence limit is reached
  • MOD Improve in API filters
  • MOD Improve logs role reading
  • FIX Can't alter role when trying to modify the last admin

Changes in Faraday Corporate:

  • FIX various bugs in Jira's issue types API
  • MOD Internal improvement in integrations api
"},{"location":"RELEASE/#3162-jul-2nd-2021","title":"3.16.2 [Jul 2nd, 2021]:","text":"

Changes in Faraday Professional:

  • FIX bug where workspaces are not updatable by UI
"},{"location":"RELEASE/#3161-jul-2nd-2021","title":"3.16.1 [Jul 2nd, 2021]:","text":"
  • MOD only show settings of this version in faraday-manage settings
  • FIX update minimum version of click dependency
"},{"location":"RELEASE/#3160-jun-29th-2021","title":"3.16.0 [Jun 29th, 2021]:","text":"
  • BREAKING CHANGE: API V2 discontinued
  • BREAKING CHANGE: Changed minimum version of python to 3.7
  • ADD agent parameters has types (protocol with agent and its APIs)
  • ADD move settings from server.in to a db model
  • ADD (optional) query logs
  • MOD new threads management
  • MOD vulnerabilities' endpoint no longer loads evidence unless requested with get_evidence=true
  • FIX now it is not possible to create workspace of name \"filter\"
  • FIX bug with dates in the future
  • FIX bug with click 8
  • FIX bug using --port command
  • FIX endpoints returning 500 as status code
  • REMOVE the need tom CSRF token from evidence upload api

Changes in Faraday Professional:

  • ADD reports can contain user comments
  • ADD special characters restrictions to faraday-manage create-superuser
  • ADD randomized id within the generated executive reports
  • ADD API limited by license presence
  • ADD redis support as session storage.
  • ADD server configuration by API
  • MOD Roles now works with the security library, making API and database changes
  • MOD code style improvements
  • FIX endpoints returning 500 as status code

Changes in Faraday Corporate:

  • ADD improved regex for scheduled agents
  • ADD issue types gotten from directly from the user Jira instance's API
  • MOD match ServiceNow OAuth endpoint's URL with the same format as Jira
  • FIX typo when running faraday-manage database-schema
  • FIX error downloading logs using LDAP
  • REMOVE unnecessary data sent to integrations endpoints
"},{"location":"RELEASE/#3151-may-31st-2021","title":"3.15.1 [May 31st, 2021]:","text":"

Changes in Faraday Corporate:

  • FIX workspace comparison
"},{"location":"RELEASE/#3150-may-18th-2021","title":"3.15.0 [May 18th, 2021]:","text":"
  • ADD Basic Auth support
  • ADD support for GET method in websocket_tokens, POST will be deprecated in the future
  • ADD CVSS(String), CWE(String), CVE(relationship) columns to vulnerability model and API
  • ADD agent token's API says the renewal cycling duration
  • MOD Improve database model to be able to delete workspaces fastly
  • MOD Improve code style and uses (less flake8 exceptions, py3 super style, Flask app as singleton, etc)
  • MOD workspaces' names regex to verify they cannot contain forward slash (/)
  • MOD Improve bulk create logs
  • FIX Own schema breaking Marshmallow 3.11.0+
  • UPD flask_security_too to version 4.0.0+

Changes in Faraday Professional:

  • ADD reading feature flags from the license. (Feature flags are InProgress)
  • ADD mult_websocket_token API GET method, POSTwill be deprecated.
  • MOD improve regex for agent scheduling
  • MOD improve code stability (more testing, less flake8 exceptions)

Changes in Faraday Corporate:

  • ADD OAuth2.0 to ServiceNow integration
  • MOD Actions API return which model is from that action
  • MOD Save issuetracker from backend instead of from frontend
  • MOD ServiceNow OAuth endpoint's URL to the same format as Jira
  • FIX Role change with LDAP login
  • FIX serviceNow integration bug when the configuration is empty
  • FIX bug when using in Jira's custom field
"},{"location":"RELEASE/#3144-apr-15th-2021","title":"3.14.4 [Apr 15th, 2021]:","text":"
  • Updated plugins package, which update appscan plugin

Changes in Faraday Corporate:

  • FIX Get list of jira templates
"},{"location":"RELEASE/#3143-mar-30th-2021","title":"3.14.3 [Mar 30th, 2021]:","text":"
  • MOD MAYOR Breaking change: Use frontend from other repository
  • ADD last_run to executors and agents
  • ADD ignore info vulns option (from faraday-plugins 1.4.3)
  • ADD invalid logins are registered in audit.log
  • ADD agent registration tokens are now 6-digit short and automatically regenerated every 30 seconds
  • MOD Fix logout redirect loop
  • REMOVE support for native SSL

Changes in Faraday Professional:

  • MOD Fix user creation when trying to use an already registered email or numeric username
  • MOD FIX API validation in /v2/2fa/confirm, which returned error
  • MOD migrate secrets from 2FA from 16 to 32 length size. WARN: if you first upgrade, and then downgrade the database, 2FA will be desactivated in some users (can't fix 32 in 16 length)

Changes in Faraday Corporate:

  • ADD validation for crontab in agent scheduling
  • ADD New workflow API, only in V3 API: /ws/<workspace_name>/workflow/. It reimplements the POST logic to only need to use one POST.
  • MOD Fix bug in generate-rsa-keys command when no integration configuration has been saved. In this case, the user must save the configuration through the Settings section of the web UI
  • MOD Fix the ticket subject in whd integration and add name and ws to detail
  • MOD Change integrations issue's URL key in response from 'self' to 'url'
"},{"location":"RELEASE/#3142-feb-26th-2021","title":"3.14.2 [Feb 26th, 2021]:","text":"
  • ADD New plugins:
    • microsoft baseline security analyzer
    • nextnet
    • openscap
  • FIX old versions of Nessus plugins bugs
"},{"location":"RELEASE/#3141-feb-17th-2021","title":"3.14.1 [Feb 17th, 2021]:","text":"
  • ADD forgot password
  • ADD update services by bulk_create
  • ADD FARADAY_DISABLE_LOGS varibale to disable logs to filesystem
  • ADD security logs in audit.log file
  • UPD security dependency Flask-Security-Too v3.4.4
  • MOD rename total_rows field in filter host response
  • MOD improved Export cvs performance by reducing the number of queries
  • MOD sanitize the content of vulns' request and response
  • MOD dont strip new line in description when exporting csv
  • MOD improved threads management on exception
  • MOD improved performance on vulnerability filter
  • MOD improved API documentation
  • FIX upload a report with invalid custom fields
  • ADD v3 API, which includes:
    • All endpoints ends without /
    • PATCH {model}/id endpoints
    • ~~Bulk update via PATCH {model} endpoints~~ In a future release
    • ~~Bulk delete via DELETE {model} endpoints~~ In a future release
    • Endpoints removed:
    • /v2/ws/<workspace_id>/activate/
    • /v2/ws/<workspace_id>/change_readonly/
    • /v2/ws/<workspace_id>/deactivate/
    • /v2/ws/<workspace_name>/hosts/bulk_delete/
    • /v2/ws/<workspace_name>/vulns/bulk_delete/
    • Endpoints updated:
    • /v2/ws/<workspace_name>/vulns/<int:vuln_id>/attachments/ => \\ /v3/ws/<workspace_name>/vulns/<int:vuln_id>/attachment

Changes in Faraday Professional:

  • ADD vuln history in comments
  • MOD Enable PDF reports by default
  • MOD List executive report by format
  • ADD v3 API, which includes:
    • All PUT 2FA methods change to POST:
      • /v3/users/{user_id}/disable2fa
      • /v3/users/{user_id}/request2fa
      • /v3/2fa/confirm
      • /v3/2fa/disable
      • /v3/2fa/enable

Changes in Faraday Corporate:

  • ADD category support and SSL to WHD
  • MOD Change integrations' endpoint for maintenance reasons
  • MOD Improve data of agent schedule properly set when agents are removed
  • FIX Run Agent schedule control less often
  • FIX cron generated with * in minutes
  • FIX error when running scheduled agents
  • FIX Agent schedule removed when a workspace is dissociated from agent
"},{"location":"RELEASE/#3140-dec-23th-2020","title":"3.14.0 [Dec 23th, 2020]:","text":"
  • ADD RESTless filter to multiples views, improving the searchs
  • ADD \"extras\" modal in options menu, linking to other Faraday resources
  • ADD import vulnerability templates command to faraday-manage
  • ADD generate nginx config command to faraday-manage
  • ADD vulnerabilities severities count to host
  • ADD Active Agent columns to workspace
  • ADD critical vulns count to workspace
  • ADD Remember me login option
  • ADD distinguish host flag
  • ADD a create_date field to comments
  • FIX to use new webargs version
  • FIX Custom Fields view in KB (Vulnerability Templates)
  • FIX bug on filter endpoint for vulnerabilities with offset and limit parameters
  • FIX bug raising 403 Forbidden HTTP error when the first workspace was not active
  • FIX bug when changing the token expiration change
  • FIX bug in Custom Fields type Choice when choice name is too long.
  • FIX Vulnerability Filter endpoint Performance improvement using joinedload. Removed several nplusone uses
  • MOD Updating the template.ini for new installations
  • MOD Improve SMTP configuration
  • MOD The agent now indicates how much time it had run (faraday-agent-dispatcher v1.4.0)
  • MOD Type \"Vulnerability Web\" cannot have \"Host\" type as a parent when creating data in bulk
  • MOD Expiration default time from 1 month to 12 hour
  • MOD Improve data reference when uploading a new report
  • MOD Refactor Knowledge Base's bulk create to take to take also multiple creation from vulns in status report.
  • MOD All HTTP OPTIONS endpoints are now public
  • MOD Change documentation and what's new links in about
  • REMOVE Flask static endpoint
  • REMOVE of our custom logger

Changes in Faraday Professional:

  • ADD workspaces to users list
  • ADD possibility to assign multiple workspaces when creating or updating users
  • ADD possibility to avoid brute force in login by configuration limiting request/time
  • ADD copy vuln link button
  • ADD users list is ordered by status by default
  • FIX bug in Executive Report's regenerate button just downloading the older file
  • FIX executive reports sorting by date
  • FIX bug that prevent using ws in https
  • FIX bug in status-check, when try to authenticate using LDAP giving bad error messages.
  • MOD Improve expired license message

Changes in Faraday Corporate:

  • ADD Gitlab integration
  • ADD OAuth authentication to JIRA integration
  • ADD LDAP Group for asset owner profile
  • ADD SolarWinds integration
  • FIX bug in Jira integration by setting 'Bug' as default issue type
  • FIX bug when saving Jira's custom fields in the database
  • FIX okta ldap integration to use roles from ldap
  • MOD Improve integrations logs
"},{"location":"RELEASE/#312-sep-3rd-2020","title":"3.12 [Sep 3rd, 2020]:","text":"
  • Now agents can upload data to multiples workspaces
  • Add agent and executor data to Activity Feed
  • Add session timeout configuration to server.ini configuration file
  • Add hostnames to already existing hosts when importing a report
  • Add new faraday background image
  • Display an error when uploading an invalid report
  • Use minimized JS libraries to improve page load time
  • Fix aspect ratio distortion in evidence tab of vulnerability preview
  • Fix broken Knowledge Base upload modal
  • Fix closing of websocket connections when communicating with Agents
  • Change Custom Fields names in exported CSV to make columns compatible with faraday_csv plugin
  • Fix import CSV for vuln template: some values were overwritten with default values.
  • Catch errors in faraday-manage commands when the connection string is not specified in the server.ini file
  • Fix bug that generated a session when using Token authentication
  • Fix bug that requested to the API when an invalid filter is used
  • Cleanup old sessions when a user logs in
  • Remove unmaintained Flask-Restless dependency
  • Remove pbkdf2_sha1 and plain password schemes. We only support bcrypt

Changes in Faraday Professional:

  • Add create_time field to the context of vulns in grouped executive reports. Its value is the oldest date in the group of vulnerabilities
  • Add group_vulns field to the context of vulns in grouped executive reports. It contains a list of the vulnerabilities included in the group.
  • Add tasks information to executive reports
  • Add hosts' and services' tags to export CSV
  • Add tags support to bulk create API
  • Fix bug in dashboard's commands history view.
  • Fix bug rendering {{vuln.description}} in markdown executive reports
  • Fix bug importing tasks with special characters
  • Fix bug running libreoffice on MacOS
  • Fix missing evidence from generic markdown report
  • Save the real ip address of the user when the server is used behind a proxy

Changes in Faraday Corporate:

  • Add Jinja2 templates to parse the vulnerability data to be sent to ticketing tools (Jira and ServiceNow)
  • Fix server errors when using workflows
  • Fix vulnerability issuetracker column bug triggered when adding tags
  • Improve error messages for LDAP authentication in the status check command
"},{"location":"RELEASE/#3112-aug-6th-2020","title":"3.11.2 [Aug 6th, 2020]:","text":"
  • Fix missing evidence from generic reports with markdown
  • Fix JPG evidence in executive reports
  • Fix workspace comparasion
"},{"location":"RELEASE/#3111-jun-3rd-2020","title":"3.11.1 [Jun 3rd, 2020]:","text":"
  • Fix missing shodan icon and invalid link in dashboard and hosts list
  • Upgrade marshmallow, webargs, werkzeug and flask-login dependencies to latest versions in order to make packaging for distros easier

Changes in Faraday Professional:

  • Fix import CSV for vuln templates (some values were overwritten with default values)
  • Add an endpoint to download logs
  • Improve password autocomplete behavior when editing users from the Web UI
  • UX improvements in users ediiton (don't close the modal then clicking out of the modal dialog)
  • UX improvements in evidence uploading

Changes in Faraday Corporate:

  • Update threadfix mappings of description, resolution, data and custom field cvss_score. Only export confirmed vulns.
"},{"location":"RELEASE/#311-apr-22nd-2020","title":"3.11 [Apr 22nd, 2020]:","text":"
  • Move GTK client to another repository to improve release times.
  • Fix formula injection vulnerability when exporting vulnerability data to CSV. This was considered a low impact vulnerability.
  • Remove \"--ssl\" parameter. Read SSL information from the config file.
  • Add OpenAPI autogenerated documentation support
  • Show agent information in command history
  • Add bulk delete endpoint for hosts API
  • Add column with information to track agent execution data
  • Add tool attribute to vulnerability to avoid incorrectly showing \"Web UI\" as creator tool
  • Add sorting by target in credentials view
  • Add creator information when uploading reports or using de bulk create api
  • Add feature to disable rules in the searcher
  • Add API endpoint to export Faraday data to Metasploit XML format
  • Change websocket url route from / to /websockets
  • Use run date instead of creation date when plugins report specifies it
  • Improve knowledge base UX
  • Improve workspace table and status report table UX.
  • Improve format of exported CSV to include more fields
  • Sort results in count API endpoint
  • Limit description width in knowledge base
  • Change log date format to ISO 8601
  • Fix parsing server port config in server.ini
  • Fix bug when _rev was send to the hosts API
  • Send JSON response when you get a 500 or 404 error
  • Fix bug parsing invalid data in NullToBlankString

Changes in plugins (only available through Web UI, not in GTK client yet):

New plugins:

  • Checkmarx
  • Faraday_csv (output of exported Faraday csv)
  • Qualyswebapp
  • Whitesource

Updated plugins:

  • Acunetix
  • AppScan
  • Arachni
  • Nessus
  • Netspaker
  • Netspaker cloud
  • Nexpose
  • Openvas
  • QualysGuard
  • Retina
  • W3af
  • WPScan
  • Webinspect
  • Zap

Changes in Faraday Professional:

  • Add methodologies API improvements
  • Add endpoint to update multiple tags on multiple vulns
  • Add new \"markdown\" custom field type
  • Disable markdown for custom fields of type \"string\" (if you need it, use \"markdown\" instead)
  • Improve hosts view styles when table is empty
  • Improve Web UI first load time
  • Improve executive reports UX.
  • Fix bug when showing \"data\" field in grouped executive reports
  • Fix showing of vulnerabilities with unclassified severity in executive reports
  • Fix bug in executive report filters when vulnerability had attachments
  • Fix ordering by date in executive reports.
  • Fix bug when importing invalid tasks CSV
  • Fix bug when creating users with \"asset owner\" role
  • Don't show disabled users when creating a workspace

Changes in Faraday Corporate:

  • Add run agent button in scheduling table
  • Add issuetracker_json vulnerability field to allow using issue tracker data inside executive reports.
  • Add legend in scheduling table when there are not elements
  • Add a descriptive sentence to the action's name in workflows
  • Remove default user's credentials from ticketing tools configuration.
  • Fix error when loading LDAP config
"},{"location":"RELEASE/#3102-jan-30th-2020","title":"3.10.2 [Jan 30th, 2020]:","text":"
  • Fix Cross-Site Request Forgery (CSRF) vulnerability in all JSON API endpoints. This was caused because a third-party library doesn't implement proper Content-Type header validation. To mitigate the vulnerability, we set the session cookie to have the SameSite: Lax property.
  • Fix Faraday Server logs were always in debug
  • Add update date column when exporting vulnerabilities to CSV
  • Fix unicode error when exporting vulnerabilities to CSV

Changes in Faraday Professional:

  • Fix download report docx was not working when the user clicked on csv before docx
  • Add vulnerability status field in grouped executive reports
"},{"location":"RELEASE/#3101-jan-10th-2020","title":"3.10.1 [Jan 10th, 2020]:","text":"
  • Fix installation with pip install --no-binary :all: faradaysec
  • Force usage of webargs 5 (webargs 6 broke backwards compatibility)
  • Use latest version of faraday-plugins
  • Fix broken \"Faraday Plugin\" menu entry in the GTK client
  • Extract export csv to reuse for reports

Changes in Faraday Professional:

  • Fix a bug when custom field is None or type int in executive reports
  • Fix new lines bug with markdown executive reports
  • Add nativeSeverity to ThreadFix export data
  • Fix reports borders in images within vulnerability description

Changes in Faraday Corporate:

  • Bugfix allow to change the roles when using ldap with use_local_roles
"},{"location":"RELEASE/#310-dec-19th-2019","title":"3.10 [Dec 19th, 2019]:","text":"
  • Use Python 3 instead of Python 2 in the Faraday Server
  • Add ability to manage agents with multiple executors
  • Agents can be run with custom arguments
  • Improved processing of uploaded reports. Now it is much faster!
  • Add custom fields of type choice
  • Fix vuln status transition in bulk create API (mark closed vulns as re-opened when they are triggered again)
  • Fix bug when using non-existent workspaces in Faraday GTK Client
  • Set service name as required in the Web UI
  • Validate the start date of a workspace is not greater than the end date
  • Fix command API when year is invalid
  • When SSL misconfigurations cause websockets to fails it doesn't block server from starting
  • Check for invalid service port number in the Web UI
  • Fix dashboard tooltips for vulnerability
  • Fix bug when GTK client lost connection to the server
  • Fix style issues in \"Hosts by Service\" modal of the dashboard
  • Add API for bulk delete of vulnerabilities
  • Add missing vuln attributes to exported CSV
  • faraday-manage support now displays the Operating System version
  • Notify when faraday-manage can't run becasue of PostgreSQL HBA config error

Changes in Faraday Professional:

  • Add faraday-manage import-license command
  • Fix issue with users with dot (.)
  • Fix second factor login
  • Fix datetimeformat parsing on executive report templates, we now support for datetime strings
  • Generate a CSV file in addition to the DOCX generated in executive reports
  • Fix executive report generation when filtering by tags
  • Grouped executive reports can use vuln counter and hostnames
  • Fix vuln sorting in grouped executive reports
  • Fix bug in dates during workspace creation/edition

Changes in Faraday Corporate:

  • Add support for OKTA LDAP interface
  • Deactivated workspaces not listed in Workspace Comparison
"},{"location":"RELEASE/#393-nov-12th-2019","title":"3.9.3 [Nov 12th, 2019]:","text":"
  • Fix unicode error when exporting vulns to CSV
  • Add vuln attributes to CSV
  • Fix hostname parsing and add external ID to Qualys plugin
  • Fix search by tags on vulnerability view
  • Fix executive report filters, add missing URL decode
"},{"location":"RELEASE/#39-oct-3th-2019","title":"3.9 [Oct 3th, 2019]:","text":"
  • Add agents feature for distributed plugin execution
  • Add an API endpoint to to perform a bulk create of many objects (hosts, services, vulns, commands and credentials). This is used to avoid doing a lot of API requests to upload data. Now one request should be enough
  • Major style and color changes to the Web UI
  • Add API token authentication method
  • Use server side stored sessions to properly invalidate cookies of logged out users
  • Add \"New\" button to create credentials without host or service assigned yet
  • Allow filtering hosts by its service's ports in the Web UI
  • Performance improvements in vulnerabilities and vulnerability templates API (they were doing a lot of SQL queries because of a programming bug)
  • Require being in the faraday-manage group when running faraday from a .deb or .rpm package
  • Change the first page shown after the user logs in. Now it displays a workspace selection dialog
  • Add API endpoint to import Vuln Templates from a CSV file
  • Create the exported CSV of the status report in the backend instead of in the problem, which was much slower
  • Add API endpoint to import hosts from a CSV file
  • Add faraday-manage rename-user command to change a user's username
  • Allow resizing columns in Vulnerability Templates view
  • Avoid copying technical details when a vuln template is generated from the status report
  • Use exact matches when searching vulns by target
  • Add API endpoint to get which tools impacted in a host
  • Add pagination to activity feed
  • Add ordering for date and creator to vuln templates view
  • Modify tabs in vuln template, add Details tab
  • Add copy IP to clipboard button in hosts view
  • Add creator and create date columns to vuln template view
  • When a plugin creates a host with its IP set to a domain name, resolve the IP address of that domain
  • Add support for logging in RFC5254 format
  • Add active filter in workspaces view. Only show active workspaces in other parts of the Web UI
  • Enforce end date to be greater than start date in workspaces API
  • Fix bug in faraday-manage create-tables that incorrectly marked schema migrations as applied
  • Fix bug in many plugins that loaded hostnames incorrectly (one hostname per chararcter)
  • Improve references parsing in OpenVAS plugin
  • Fix a bug in Nessus plugin when parsing reports without host_start
  • Fix bug hostname search is now working in status-report
  • Fix showing of services with large names in the Web UI
  • Fix broken select all hosts checkbox
  • Fix bug viewing an attachment/evidence when its filename contained whitespaces
  • Fix \"Are you sure you want to quit Faraday?\" dialog showing twice in GTK

Changes in Faraday Professional:

  • Add new license schema checks
  • Add agents scheduling feature
  • Add new role asset owner
  • Markdown is enabled for new installs
  • Only require pandoc install when markdown is enabled
  • Add border size configuration for executive reports
  • Improve user table style
  • Improve UX for public workspaces in the Web UI
  • Allow filtering vulns when generating executive reports
  • Fix a bug on report generation that caused a broken .docx file and it was not possible to open with MS word
  • Fix bug when SIGTERM was send to the GTK client, one thread was not stopped
  • Fix content type when downloading vuln evidence
  • Fix reactivate user option
  • Fix severity dropdown display in vulnerability template modal
  • Refactor timeline stats generation

Changes in Faraday Corporate:

  • Add new charts in Workspace Comparison
  • Improve pagination view of tables in the section Most Vulnerable Hosts of Workspace Comparison
  • Add vuln information through the issue description of ticketing tools
  • Add smtp setting
  • Fix bug in tags creation when no service was selected
"},{"location":"RELEASE/#381-jun-19th-2019","title":"3.8.1 [Jun 19th, 2019]:","text":"
  • Add configurations for websocket ssl
  • Fix a bug on report generation that caused a broken .docx file and it was not possible to open with MS word
  • Add session timeout configuration to server.ini
  • Add configurations for websocket ssl
"},{"location":"RELEASE/#38-jun-4th-2019","title":"3.8 [Jun 4th, 2019]:","text":"
  • Refactor the project to use absolute imports to make the installation easier (with a setup.py file). This also was a first step to make our codebase compatible with python 3.
  • Change the commands used to run faraday. ./faraday-server.py, ./manage.py, ./faraday.py and bin/flugin are replaced for faraday-server, faraday-manage, faraday-client and fplugin respectively
  • Changed suggested installation method. Now we provide binary executables with all python dependencies embedded into them
  • Add admin panel to the Web UI to manage custom fields
  • Fix slow host list when creating vulns in a workspace with many hosts
  • Usability improvements in status report: change the way vulns are selected and confirmed
  • Improve workspace workspace creation from the Web UI
  • Fix attachment api when file was not found in .faraday/storage
  • Fix visualization of the fields Policy Violations and References.
  • Add a setting in server.ini to display the Vulnerability Cost widget of the Dashboard
  • Fix status report resize when the browser console closes.
  • Fix severity dropdown when creating vulnerability templates
  • Update OS icons in the Web UI.
  • Fix bug when using custom fields, we must use the field_name instead of the display_name
  • Prevent creation of custom fields with the same name
  • Add custom fields to vuln templates.
  • Fix user's menu visibily when vuln detail is open
  • Remove \"show all\" option in the status report pagination
  • The activity feed widget of the dashboard now displays the hostname of the machine that runned each command
  • Add loading spinner in hosts report.
  • Fix \"invalid dsn\" bug in sql-shell
  • Fix hostnames bug in Nikto and Core Impact plugins
  • Change Openvas plugin: Low and Debug threats are not taken as vulnerabilities.
  • Add fplugin command to close vulns created after a certain time
  • Add list-plugins command to faraday-manage to see all available plugins
  • Fix a logging error in PluginBase class
  • Fix an error when using NexposePlugin from command line.
  • Add CSV parser to Dnsmap Plugin
  • Fix bug when creating web vulnerabilities in dirb plugin
  • Change Nexpose Severity Mappings.

Changes in Faraday Professional:

  • Add feature to create comments and notifications in Faraday
  • Fix a bug that incorrectly cleared the tags of a vuln when it was being edited
  • Redesign account settings modal
  • Add template preview to executive reports view.
  • Add alert before closing executive report popup.
  • Fix validation on executive reporte when popup opens.
  • Skip adding images to executive reports if the image is invalid
  • Fix \"Unknown\" vuln count in executive reports view
  • Fix bug logging in users with role client
  • Add API token authentication method
  • Fix group by in status report
  • Fix tags vuln edit
  • Fix user assignation to tasks
  • Fix bug when changing the state of tasks

Changes in Faraday Corporate:

  • Add --no_ldap option when running command \"faraday-manage status_check\" for skipping LDAP check
  • Fix bug when clicking in vulns in the \"last vulns\" dashboard widget
"},{"location":"RELEASE/#373-may-3rd-2019","title":"3.7.3 [May 3rd, 2019]:","text":"
  • Add parser for connection string at PGCli connection
  • Fix bug when using custom fields, we must use the field_name instead of the display_name
  • Fix user's menu visibily when vuln detail is open.
  • Fix bug in status report that incorrectly showed standard vulns like if they were vulnwebs
  • Fix group by in status report.
  • Fix task state change.
"},{"location":"RELEASE/#372-apr-15th-2019","title":"3.7.2 [Apr 15th, 2019]:","text":"
  • Fix status-report load when user clicks dashboard links.
  • Fix role client can't access status-report.
"},{"location":"RELEASE/#37-apr-3rd-2019","title":"3.7 [Apr 3rd, 2019]:","text":"
  • Add vulnerability preview to status report
  • Update Fierce Plugin. Import can be done from GTK console.
  • Update Goohost plugin and now Faraday imports Goohost .txt report.
  • Update plugin for support WPScan v-3.4.5
  • Update Qualysguard plugin to its 8.17.1.0.2 version
  • Update custom fields with Searcher
  • Update Recon-ng Plugin so that it accepts XML reports
  • Add postres version to status-change command
  • Couchdb configuration section will not be added anymore
  • Add unit test for config/default.xml
  • Add markdown in executive reports.
  • Add border to images. Improves images with white background in executive reports
  • Add datetime format of start date and end date from a workspace in Executive Report
  • Add error message when port is being used
  • Fix bug in vuln.type comparison inside the grouped report template
  • Hide icons and menus from the Web UI for role client
  • Fix bug in JIRA test cases
"},{"location":"RELEASE/#36-feb-21th-2019","title":"3.6 [Feb 21th, 2019]:","text":"
  • Fix CSRF (Cross-Site Request Forgery) vulnerability in vulnerability attachments API. This allowed an attacker to upload evidence to vulns. He/she required to know the desired workspace name and vulnerability id so it complicated the things a bit. We classified this vuln as a low impact one.
  • Readonly and disabled workspaces
  • Add fields 'impact', 'easeofresolution' and 'policyviolations' to vulnerability_template
  • Add pagination in 'Command history', 'Last Vulnerabilities', 'Activity logs' into dashboard
  • Add status_code field to web vulnerability
  • Preserve selection after bulk edition of vulnerabilities in the Web UI
  • Faraday's database will be created using UTF-8 encoding
  • Fix bug of \"select a different workspace\" from an empty list loop.
  • Fix bug when creating duplicate custom fields
  • Fix bug when loading in server.ini with extra configs
  • Fix ./manage.py command. It wasn't working since the last schema migration
  • ./manage.py createsuperuser command renamed to ./manage.py create-superuser
  • Fix bug when non-numeric vulnerability IDs were passed to the attachments API
  • Fix logic in search exploits
  • Add ability to 'Searcher' to execute rules in loop with dynamic variables
  • Send searcher alert with custom mail
  • Add gitlab-ci.yml file to execute test and pylint on gitlab runner
  • Fix 500 error when updating services and vulns with specific read-only parameters set
  • Fix SQLMap plugin to support newer versions of the tool
  • Improve service's parser for Lynis plugin
  • Fix bug when parsing URLs in Acunetix reports
  • Fix and update NetSparker Plugin
  • Fix bug in nessus plugin. It was trying to create a host without IP. Enabled logs on the server for plugin processing (use --debug)
  • Fix bug when parsing hostnames in Nessus reports
  • Fix SSLyze report automatic detection, so reports can be imported from the web ui
  • Update Dnsmap Plugin

Changes in Faraday Professional:

  • Add workspace attributes to the available elements for executive reports
  • Solve incompatibility between docxtpl and python-docx
  • Fix bug that didn't list public workspaces to pentesters and clients when the user didn't have permissions for any private workspace
  • Fix bug with case insensitive logins
  • When showing evidence on the executive report you will no longer have the name of the image bellow the picture
  • Fix 'Coverparagraph' error in Executire Report
  • Manage the availability of workspaces taking into account their associated users.

Changes in Faraday Corporate:

  • Changes in Jira Integration
  • ServiceNow Integration
  • Use pagination for ldap to avoid memory errors
"},{"location":"RELEASE/#35-jan-16th-2019","title":"3.5 [Jan 16th, 2019]:","text":"
  • Redesgin of new/edit vulnerability forms
  • Add new custom fields feature to vulnerabilities
  • Add ./manage.py migrate to perform alembic migrations
  • Faraday will use webargs==4.4.1 because webargs==5.0.0 fails with Python2
  • New system for online plugins using Threads, a few fixes for metasploit plugin online also.
  • Fix Command \"python manage.py process-reports\" now stops once all reports have been processed
  • Fix bug in query when it checks if a vulnerability or a workspace exists
  • Fix Once a workspace is created through the web UI, a folder with its name is created inside ~/.faraday/report/
  • The manage.py now has a new support funtionality that creates a .zip file with all the information faraday's support team will need to throubleshoot your issue
  • Status-check checks PostgreSQL encoding
  • Fix a bug when fail importation of reports, command duration say \"In Progress\" forever.
  • Fix confirmed bug in vulns API
  • Update websockets code to use latest lib version
  • bootstrap updated to v3.4.0
  • Manage.py support now throws a message once it finishes the process.
  • Update Lynis to its version 2.7.1
  • Updated arp-scan plugin, added support in the Host class for mac address which was deprecated before v3.0
  • OpenVAS Plugin now supports OpenVAS v-9.0.3

Changes in Faraday Professional:

  • Add 2 Factor Authentication
  • Now you can re-activate an User in WEBUI
  • Show users \"disabled/deleted\" in WEB-UI list of users.
  • Enabled Security Tracking options for flask-security. Expanded User API and Users Frontend. Added current_ip
  • Update the GTK license check to the latest API.
  • Don't alter current selection when clicking on download or renerate buttons in executive report list
"},{"location":"RELEASE/#34-december-6th-2018","title":"3.4 [December 6th, 2018]:","text":"
  • In GTK, check active_workspace its not null
  • Add fbruteforce services fplugin
  • Attachments can be added to a vulnerability through the API.
  • Catch gaierror error on lynis plugin
  • Add OR and NOT with parenthesis support on status report search
  • Info API now is public
  • Web UI now detects Appscan plugin
  • Improve performance on the workspace using cusotm query
  • Workspaces can be set as active/disable in welcome page.
  • Change Nmap plugin, response field in VulnWeb now goes to Data field.
  • Update code to support latest SQLAlchemy version
  • Fix create_vuln fplugin bug that incorrectly reported duplicated vulns
  • Attachments on a vulnerability can be deleted through the API.
  • Improvement in the coverage of the tests.
  • The client can set a custom logo to Faraday
  • Centered checkboxes in user list page
  • Client or pentester can't activate/deactivate workspaces
  • In GTK, dialogs now check that user_info is not False
  • Add tags in Service object (Frontend and backend API)
  • Limit of users only takes the active ones
  • Improve error message when the license is not valid
  • Added new funtionality to status check, it now shows you user licence and general config information.
"},{"location":"RELEASE/#33-novemeber-14th-2018","title":"3.3 [Novemeber 14th, 2018]:","text":"
  • Add workspace disable feature
  • Add mac vendor to host and services
  • Fix typos and add sorting in workspace name (workspace list view)
  • Improve warning when you try to select hosts instead of services as targets of a Vulnerability Web
  • Deleted old Nexpose plugin. Now Faraday uses Nexpose-Full.
  • Update sqlmap plugin
  • Add updated zap plugin
  • Add hostnames to nessus plugin
  • Python interpreter in SSLCheck plugin is not hardcoded anymore.
  • Fix importer key error when some data from couchdb didn't contain the \"type\" key
  • Fix AttributeError when importing vulns without exploitation from CouchDB
  • Fix KeyError in importer.py. This issue occurred during the import of Vulnerability Templates
  • Fix error when file config.xml doesn't exist as the moment of executing initdb
  • Improve invalid credentials warning by indicating the user to run Faraday GTK with --login option
  • Fix typos in VulnDB and add two new vulnerabilities (Default Credentials, Privilege Escalation)
  • Improved tests performance with new versions of the Faker library
  • abort() calls were checked and changed to flask.abort()
  • Add tags in Host object (Frontend and backend API)
  • Improve performance of executive reports on big workspaces
  • Fplugin exports workspace's information in XLSX format
  • Add refs property to vuln parent in grouped report
  • Update license code with the new portal
  • Made the url path using urlib instead of manual
  • Fixed bug when tags in json are integers
"},{"location":"RELEASE/#32-october-17th-2018","title":"3.2 [October 17th, 2018]:","text":"
  • Added logical operator AND to status report search
  • Restkit dependency removed.
  • Improvement on manage.py change-password
  • Add feature to show only unconfirmed vulns.
  • Add ssl information to manage.py status-check
  • Update wpscan plugin to support latest version.
  • Allow workspace names starting with numbers.
"},{"location":"RELEASE/#september-21-2018","title":"September 21, 2018:","text":"
  • Fix bug: manage.py status_check
  • Fix bug: manage.py initdb
"},{"location":"RELEASE/#september-17-2018","title":"September 17, 2018:","text":"
  • Fix get exploits API
  • New searcher feature
  • Added host_os column to status report
  • Fix and error while trying to execute server with --start
  • Added option --choose-password to initdb
  • Continous scan updated for Nessus 7
  • Refactor on server.config to remove globals
  • Added a directory for custom templates for executive reports (pro and corp)
  • Activity feed shows more results and allows to filter empty results
  • Allow ot create workspace that start with numbers
  • Added more variables to executive reports (pro and corp)
  • Fixed some value checking on tasks api (date field)
  • OpenVas plugin updated
  • Appscan plugin update
  • Added no confirmed vulns to report api
  • Fixed a bug on workspace API when the workspace already exists on database
  • Fix owner filter on status report
  • Fixes on import_csv fplugin when the api returned 409
  • Fixes on status_check
  • Fixed a bug on webui when workspace permission was changed (pro and corp)
  • Update nexpose plugin
  • uigrid library updated to latest version
  • Bug fix on plugin automatic detection
  • Fixed a bug on executive reports when multiple reports were scheduled
  • Avoid closing the executive report and new vuln modal when the form has data
  • Status report open new tab for evidence
  • added change_password to manage.py
  • Update wapiti plugin
  • Fixed vuln count on executive report (pro and corp)
  • Fixed css align in some tables
  • Fixed No ports available error on the client
"},{"location":"RELEASE/#august-17-2018","title":"August 17, 2018:","text":"
  • Updated code to use Flask 1.0
  • Add threadfix integration (corp only)
  • Fix create_service fplugin
  • Executive report bug fix on tags
  • Persistence server bug fix on impact and ease of resolution
  • Fix unicode error bug on executive reports
  • Updated code to support latest Twisted version
  • Updated all requirements to use >=
  • Fix dry run on create_host fplugin
  • Fixed del_all_vulns_with and del_all_hosts
  • Improved executive reports status update refresh
  • Websocket port is configurable now
  • Change minimum font size in tag cloud
  • Fixed a problem with shodan icon on dashboard
  • Updated license check on deleted users
  • Users with role client was not able to change password, bug fixed
  • Updated code to support pip 10
  • Added ldap to status check
  • Credentials icon aligned
  • Deamon now allows to execute faraday sever in more than one port and more than one process for multiplexation
  • All views now check for permissions on workspace
  • Pull requests #229, #231, #239 and #240 are merged
  • Avoid polling deleted executive reports
  • Added documentation to project
  • Fix self xss on webshell
  • Add postgres locks check on status_check
  • Vuln counter fix when confirmed is on
"},{"location":"RELEASE/#july-26-2018","title":"July 26, 2018:","text":"
  • Interface removed from model and from persistence server lib (fplugin)
  • Performance iprovements on the backend
  • Add quick change workspace name (from all views)
  • Changed the scope field of a workspace from a free text input to a list of targets
  • New faraday styles in all webui views
  • Add search by id for vulnerabilities
  • Add new plugin sslyze
  • Add new plugin wfuzz
  • Add xsssniper plugin
  • Fix W3af, Zap plugins
  • Add brutexss plugin
  • Allow to upload report file from external tools from the web
  • Fix sshcheck import file from GTK
  • Add reconng plugin
  • Add sublist3r plugin
  • Add HP Webinspect plugin
  • Add dirsearch plugin
  • Add ip360 plugin
  • CouchDB was replaced by PostgreSQL :)
  • Host object changed, now the name property is called ip
  • Interface object was removed
  • Note object was removed and replaced with Comment
  • Communication object was removed and replaced with Comment
  • Show credentials count in summarized report on the dashboard
  • Remove vuln template CWE fields, join it with references
  • Allow to search hosts by hostname, os and service name
  • Allow the user to specify the desired fields of the host list table
  • Add optional hostnames, services, MAC and description fields to the host list
  • Workspace names can be changed from the Web UI
  • Exploitation and severity fields only allow certain values. CWE CVEs were fixed to be valid. A script to convert custom CSVs was added.
  • Web UI path changed from /_ui/ to / (_ui has now a redirection to / for keeping backwards compatibility)
  • dirb plugin creates an informational vulnerability instead of a note.
  • Add confirmed column to exported csv from webui
  • Fixes in Arachni plugin
  • Add new parameters --keep-old and --keep-new for faraday CLI
  • Add new screenshot fplugin which takes a screenshot of the ip:ports of a given protocol
  • Add fix for net sparker regular and cloud fix on severity
  • Removed Chat feature (data is kept inside notes)
  • Add CVSS score to reference field in Nessus plugin.
  • Fix unicode characters bug in Netsparker plugin.
  • Fix qualys plugin.
  • Fix bugs with MACOS and GTK.
"},{"location":"RELEASE/#april-10-2018","title":"April 10, 2018:","text":"
  • Fix bug with tornado version 5.0 and GTK client.
"},{"location":"RELEASE/#november-17-2017","title":"November 17, 2017:","text":"
  • Fix bug with tags in models.
"},{"location":"RELEASE/#november-5-2017","title":"November 5, 2017:","text":"
  • Added \"Last modified\" and \"Created\" in Hosts view
  • Fixed bug when trying to run Faraday as second process and closing the terminal (&!)
  • Fixed bug where it asked for dependencies eternally when you have a different version than the one required
  • Fixed small bug in the update_from_document method
  • Fixed bug, makes the python library dependencies specific to the desired version
  • Fixed GitHub language bar to reflect real code percentage
  • Merge PR #195: Create gentoo_requirements_extras.txt (New Github wiki page)
  • Merge PR #225: Add references to found vulnerabilities in nmap plugin
  • New plugin: Netsparker cloud
  • New plugin: Lynis (Winner of Faraday Challenge 2017)
  • New Fplugin: changes the status of all vulnerabilities of an specific workspace to closed
  • New Fplugin: combines the \"create_interface\" and \"create_host\" scripts into one (create_interface_and_host script)
  • New Fplugin: import_csv , now you can import Faraday objects from a CSV
"},{"location":"RELEASE/#august-11-2017","title":"August 11, 2017:","text":"
  • Add check to the vuln creation modal for empty targets in the Web UI
"},{"location":"RELEASE/#august-9-2017","title":"August 9, 2017:","text":"

No changes

"},{"location":"RELEASE/#august-7-2017","title":"August 7, 2017:","text":"
  • Updated Core Impact plugin to be compatible with 2016 version
  • Improved loading of fields request and website in Burp Plugin
  • Improved Nexpose Full plugin
  • Improved Acunetix plugin to avoid conflicts and missing imported data, and to correctly parse URLs and resolutions
"},{"location":"RELEASE/#july-19-2017","title":"July 19, 2017:","text":"
  • Added the ability to select more than one target when creating a vuln in the Web UI
  • Merged PR #182 - problems with zonatransfer.me
  • Fixed bug in Download CSV of Status report with old versions of Firefox.
  • Fixed formula injection vulnerability in export to CSV feature
  • Fixed DOM-based XSS in the Top Services widget of the dashboard
  • Fix in AppScan plugin.
  • Fix HTML injection in Vulnerability template.
  • Add new plugin: Junit XML
  • Improved pagination in new vuln modal of status report
  • Added \"Policy Violations\" field for Vulnerabilities
"},{"location":"RELEASE/#may-24-2017","title":"May 24, 2017:","text":"
  • Fixed bug when editing workspaces created in GTK
  • Improved host search in the WEB UI
  • Extended the config to support different searching engines in the WEB UI
  • Check that client and server versions match when connecting
  • Adds the 'v' and 'version' argument for both the server and the client
  • Fixed \"refresh\" button in the Web UI
  • Fix API on /ws/ with duration object None
  • Added a CRUD for Credentials to the Web UI
  • Bug fixes on the Burp Online Plugin
  • Added a script to connect with Reposify
  • Fixed Hostname import in Nessus Plugin
  • Make plugin methods log() and devlog() work again
  • Fixed bug in SQLMap plugin that made the client freeze
  • Improved SQLMap plugin to support more options and to show errors in GTK log console
  • Fixed bug when creating/updating Credentials
  • Improve plugins usage of vulnweb URL fields
  • Fixed order of Report Plugins in the GTK import list
  • "},{"location":"RELEASE/#march-17-2017","title":"March 17, 2017:","text":"
    • Added link to name column in Hosts list
    • Created a requirements_extras.txt file to handle optional packages for specific features
    • Fixed bug in SQLMap plugin that made the client freeze
    • Fixed bug when creating/updating Credentials
    • Fixed bug in the WEB UI - menu explanation bubbles were hidden behind inputs
    • Fixed conflict resolution when the object was deleted from another client before resolving the conflict
    • Improved fplugin
    • Improved the installation process
    • Improved SQLMap plugin to support --tables and --columns options
    • Improved navigation in Web UI
    • Merged PR #137 - CScan improvements: bug fixing, change plugin format and removed unnecessary file output
    • Merged PR #173 - Hostnames: added hostnames to plugins
    • Merged PR #105 - OSint: added the possibility of using a DB other than Shodan
    • The Status Report now remembers the sorting column and order
    "},{"location":"RELEASE/#february-8-2017","title":"February 8, 2017:","text":"
    • Fixed max amount of vulns pagination bug in Web UI
    • Fixed Maltego plugin
    "},{"location":"RELEASE/#january-30-2017","title":"January 30, 2017:","text":"
    • Added an activity feed panel in the Dashboard.
    • Added AppScan plugin.
    • Improved Burp's Online plugin. Added fields and removed HTML tags.
    • Refactor remaining modules to be compatible with JS Strict Mode.
    • Fixed bug that prevented GTK from closing when user clicked CANCEL on WS creation.
    • Fixed size of Workspace creation dialog.
    • New cwe databases: English and Spanish.
    • Added Hping plugin.
    • Enhancements to Wpscan plugin.
    "},{"location":"RELEASE/#november-10-2016","title":"November 10, 2016:","text":"
    • New library to connect with Faraday Server.
    • Fixed Fplugin, now it uses the new library to communicate with the Server.
    • New field for Vulnerabilities: plugin creator and status.
    • Refactor in Faraday Core and GTK Client.
    • Bug fixing in Faraday Client and Server.
    • Added Faraday news notifications in GTK and Web UI.
    • New plugins: Dirb, Netdiscover, FruityWifi, Sentinel.
    • Improvements on the WPscan plugin.
    • Fixed Licenses search.
    • Refactor Licenses module to be compatible with JS Strict Mode.
    "},{"location":"RELEASE/#september-19-2016","title":"September 19, 2016:","text":"
    • Major refactor of Faraday Client: now we support massive workspaces (100.000+ hosts).
    • Fixed more than 10 minor bugs on the Web UI.
    • Fixed searching with spaces character on Web UI
    • Updated URL shown when starting Faraday.
    • Dashboard is now refreshed automatically every 60 seconds.
    • Fixed Propecia plugin.
    • New plugin: WPscan
    • Host Sidebar on GTK now adds information more intelligently and will never block the application.
    • Evidence screenshots in report generation is now bigger.
    • Help menu in GTK with links to interesting links.
    • Added Help section to WEB UI.
    "},{"location":"RELEASE/#august-12-2016","title":"August 12, 2016:","text":"
    • Added Faraday Server
    • Improved performance in web UI
    • Added some basic APIs to Faraday Server
    • Added licenses management section in web UI
    • Totally removed QT3, GTK is now the only GUI
    • Deprecated FileSystem databses: now Faraday works exclusively with Faraday Server and CouchDB
    • Added a button to go to the Faraday Web directly from GTK
    • Fixed bug when deleting objects from Faraday Web
    • Fixed bug where icons where not copied to correct folder on initialization
    • Fixed bug where current workspace wouldn't correspond to selected workspace on the sidebar on GTK
    • Fixed bug in 'Refresh Workspace' button on GTK
    • Fixed bug where Host Sidebar and Statusbar information wasn't correctly updated on GTK
    • Fixed bug in service editing
    • Fixed sqlmap plugin
    • Fixed metapsloit plugin
    "},{"location":"RELEASE/#jul-1-2016","title":"Jul 1, 2016:","text":"
    • GTK is the default interface now.
    • Added new plugin : Ndiff.
    • Added new plugin : Netcat (Gnu netcat - OpenBSD netcat - Original netcat)
    • Added button to edit your host in the GTK interface.
    • Hosts sidebar now can be sorted by amout of vulnerabilities and OS.
    • Changes in installation: install.sh now installs only GTK, QT is considered deprecated.
    • Changes in installation: Faraday now runs with the last versions of Python modules.
    • Changes in installation: fixed names of packages in setup_server.sh
    • Usability: Enter key in GTK dialogs works as OK button
    • Improved handling of lost connection to CouchDB database
    • First steps towards deprecating Filesystem databases
    • Fixed a bug when workspace was changed
    • Fixed a bug with Import Reports Dialog in GTK GUI on OS X.
    • Fixed a bug with Ctrl+Shift+C and Ctrl+Shift+V in some desktops managers.
    • Fixed a bug with mapper of vulnerabilities.
    "},{"location":"RELEASE/#jun-13-2016","title":"Jun 13, 2016:","text":"
    • Added Import Report dialog to Faraday GTK
    • Added a 'Loading workspace...' dialog to Faraday GTK
    • Added host sidebar to Faraday GTK
    • Added host information dialog to Faraday GTK with the full data about a host, its interfaces, services and vulnerabilities
    • Added support for run faraday from other directories.
    • Fixed log reapparing after being disabled if user created a new tab
    • Fixed bug regarding exception handling in Faraday GTK
    • Now Faraday GTK supports Ctrl+Shift+C / Ctrl+Shift+V to Copy/Paste
    • Faraday will now not crash if you suddenly lose connection to your CouchDB
    "},{"location":"RELEASE/#may-23-2016","title":"May 23, 2016:","text":"
    • Removed description from Hosts list in WEB UI
    • Fixed sort in Hosts list in WEB UI
    • Fixed ports sorting in Host view in WEB UI
    • Added search link for OS in Hosts list in WEB UI
    • Removed description from Services list in WEB UI
    • Added version to Services list in WEB UI
    • Modified false values in Hosts list in WEB UI
    • Added search links in Services list in WEB UI
    • Added scrollbar in Gtk Terminal.
    • Added workspace status in Gtk interface
    • Added conflict resolution support for the Gtk interface
    • Added search entry for workspaces in Gtk
    • Added support for 'exit' command inside Faraday's Gtk terminal
    • Improved handling of uncaught exceptions in Gtk interface
    • Improved text formatting in Gtk's log console
    • Fixed several small bugs in Faraday GTK
    • Added support for resize workspace bar.
    • Added a quote for imported reports in WEB UI.
    • Added support for a new type of report in Qualysguard plugin.
    • Fixed bugs in plugins: Acunetix - Nmap - Nikto.
    "},{"location":"RELEASE/#apr-29-2016","title":"Apr 29, 2016:","text":"
    • Added Open services count to Hosts list in WEB UI
    • Improved zsh integration
    • Added GTK3 interface prototype
    • Added plugin detection through report name
    • Fixed an error in wcscan script
    • Fixed nikto plugin
    • Fixed openvas plugin
    "},{"location":"RELEASE/#apr-04-2016","title":"Apr 04, 2016","text":"
    • Added cli mode (see wiki for usage instructions)
    • Support for multiple Faraday instances in the same host
    • Fixed bug for editing web vulns in bulk
    • Fixed bug for select all in web UI
    • Fixed bugs in Qualys, ZAP, nikto, w3af, openVas plugins
    • Added some new scripts and helpers
    "},{"location":"RELEASE/#feb-26-2016","title":"Feb 26, 2016:","text":"
    • Fixed bug in pip debian
    • BugFix pip install.
    • Checks additionals about dependencies in installation.
    • Warning about a upgrade to experimental in debian installation.
    • Fixed small bug in CSV importing
    • Fixed styles for Status Report
    • Fixed bug on Status Report filter after editing
    • Added support for Kali Rolling Edition
    • Notify user when the current Workspace doesn't exist
    • Show all evidence files in Status Report
    • Added script to remove all vulns with a specific severity value (parameterized)
    • Fixed Arachni Plugin bugs
    • Added new version for Maltego Plugin
    • Added support for Mint 17
    "},{"location":"RELEASE/#dec-18-2015","title":"Dec 18, 2015:","text":"
    • Immunity Canvas plugin added
    • Added Dig plugin
    • Added Traceroute plugin
    • Fixed bug in first run of Faraday with log path and API errors
    • Added parametrization for port configuration on APIs
    • Refactor Plugin Base to update active WS name in var
    • Refactor Plugins to use current WS in temp filename under $HOME/.faraday/data. Affected Plugins:
      • amap
      • dnsmap
      • nmap
      • sslcheck
      • wcscan
      • webfuzzer
      • nikto
    • Fixed bug get_installed_distributions from handler exceptions
    • Added Wiki information about running Faraday without configuring CouchDB
    • Fixed Unicode bug in Nexpose-full Plugin
    • Filter false-positives in Status Report
    • Fixed bug that prevented the use of \"reports\" and \"cwe\" strings in Workspace names
    • Added port to Service type target in new vuln modal
    • Added new scripts for faraday plugin:
      • /bin/delAllVulnsWith.py - delete all vulns that match a regex
      • /bin/getAllbySrv.py - get all IP addresses that have defined open port
      • /bin/getAllIpsNotServices.py added - get all IPs from targets without services
    • Fixed bug null last workspace
    • Fixed bugs in CSV export/import in QT
    "},{"location":"RELEASE/#oct-2-2015","title":"Oct 2, 2015:","text":"
    • Continuous Scanning Tool cscan added to ./scripts/cscan
    • Fix for saving objects without parent
    • Hosts and Services views now have pagination and search
    • Updates version number on Faraday Start
    • Visual fixes on Firefox
    • Migrate graphs from D3.js to Chart.js
    • Added Services columns to Status Report
    • Added sections of Commercial versions
    • Converted references to links in Status Report. Support for CVE, CWE, Exploit Database and Open Source Vulnerability Database
    • Added Peepingtom, SSHdefaultscan and pasteAnalyzer plugins
    • Fixed Debian install
    "},{"location":"RELEASE/#sep-10-2015","title":"Sep 10, 2015:","text":"
    • Adding filename path information of report imported in history command
    • Remove old couchdb upgrade process
    • Adding Iceweasel browser > 38.2.0 support
    • Adding more navigability in differents GUI Web (Dashboard/Services/Views)
    • Fixed bug copy clipboard offline (update path of ngClip dependeces)
    • Added class to set colors to severities in new/edit vuln view
    • Medusa, Hydra & Metasploit plug-in now added discovered weak credentials as a vulnerability
    • Nmap plug-in applyies a severity depending on the result of a NSE script
    • Fixed small bug for empty ease of resolution
    • Adding more time to generation shells QT
    • Added \"Search in Shodan\" links in different views (Status Report, Host View, Service View)
    • Removed required of name field service bulk edition
    • Added ng-disabled on Edit button if select more of 1 host on Host View WEB UI
    • Refactored GUI Web: Icon added for Modal Error OS, Creator, Date for modal-services-by-host.html Fixed typo in Host Edit, the popup message was wrong First version for in estilos.css for clear mode Also, added hover to grey boxes in the Dashboard.
    • Added vulns count for Hosts in WEB UI
    • Updated w3af plugin to support report version 1.7.6
    • Ignored cwe database from updater and QT views
    • Plugin for Nexpose XML Export 2.0
    • Added masscan plugin (1.0.3)
    "},{"location":"RELEASE/#aug-19-2015","title":"Aug 19, 2015:","text":"
    • Exported CSV contains filters and columns from Status Report in WEB UI
    • Vulnerability counter on Status Report in WEB UI
    • Added quick vuln edit and delete in WEB UI
    • Expanded Unit Tests for WEB UI
    • XML Cleaner
    • Kali 2.0 support
    • Improve plugins running status log (Adding log information on report importing)
    • Clean dev log on plugins
    • w3af plugin refactoring
    • Fix Debian \u215e.1 install support
    "},{"location":"RELEASE/#aug-05-2015","title":"Aug 05, 2015:","text":"
    • Added CWE database and integration with vulns creation
    • Added ENTER shortcut on modals
    • Progress bar for workspace in the dashboard
    • Bug fixing in workspaces and status report components
    • Unit testing for vulns, status report and workspaces components
    • Debian 8.1 support
    "},{"location":"RELEASE/#jun-30-2015","title":"Jun 30, 2015:","text":"
    • Added hosts CRUD
    • Added services CRUD
    • Fix ubuntu 15.04 installation bug
    • Small bug in burp plugin \"Import new vulnerabilities\" checkbox issue
    • Added an interactive visualization to calculate the value of a Workspace
    • Fixed several bugs in WEB UI
    • Added a URL filter functionality to the status report, allowing searches by fields
    "},{"location":"RELEASE/#apr-17-2015","title":"Apr 17, 2015:","text":"
    • You can get the new version here:
    • https://github.com/infobyte/faraday/archive/v1.0.10.tar.gz

    Changes:

    • Styles changes in WEB UI: fancy component selection, improved workspaces selection.

    Bugfixes: * Date on Workspace creation * Tables in Firefox

    "},{"location":"RELEASE/#apr-7-2015","title":"Apr 7, 2015:","text":"

    You can get the new version here: * https://github.com/infobyte/faraday/archive/v1.0.9.tar.gz

    Changes:

    • Performance improvement in the dashboard
    • Fix bug OSX install
    • Bug fixes
    "},{"location":"RELEASE/#mar-9-2015","title":"Mar 9, 2015:","text":"

    You can get the new version here:

    • https://github.com/infobyte/faraday/archive/v1.0.8.tar.gz

    Changes:

    • WcScan script and plugin (scripts/wcscan.py)
    • New Dashboard D3 with AngularJS
    • Easy access to Vulnerability pages in the Status Report
    • Easy access to the Host pages on the dashboard
    • Creation and Editing capabilities for the Workspace from the UI Web
    • Support installation for the latest version of Debian/Ubuntu/Kali
    • sqlmap version 1.0-dev support updated
    • API Status Check in both ZSH & QT GUI
    • Field added for resolution of vulnerabilities classification with plug-ins updated to support the new function.
    • Field added for rating \"ease of resolution\" for vulnerabilities
    • Adjustments for Resolution field

    • New Faraday plugin for Burp. Version 1.2 -Corrections for the vulnerabilities duplication for the burp plugin -New tab section to configure the new Vulnerabilities downloads for Faraday

    • Automated backup for couch database

    • Ability to upload evidence of a vulnerability (as an attachment)
    • Ability to assign Vulnerability Impact (confidentiality, integrity, availability).
    "},{"location":"RELEASE/#dec-12-2014","title":"Dec 12, 2014:","text":"

    You can get the new version here:

    • https://github.com/infobyte/faraday/archive/v1.0.7.tar.gz

    Changes:

    • Improved Vulnerability Edition usability, selecting a vuln will load it's content.
    • ZSH UI now is showing notifications.
    • ZSH UI now is showing active workspace.
    • Faraday now asks confirmation on exit, If you have pending conflicts to solve it will show the number of each.
    • Vulnerability creation is now suported in the status report.
    • Introducing SSLCheck, a tool for verify bugs in SSL/TLS Certificates on remote hosts. This is integrated with Faraday with a plugin.
    • Shodan Plugin is now working with the new API.
    • Some cosmetic changes in the status report.

    Bugfixes:

    • Sorting collumns in the Status Report now is working.
    • Workspace icon is based on the type of the workspace.
    • Opening the reports in QT UI now opens the active workspace.
    • UI Web dates fixes, we were showing dates with a off-by-one error.
    • Vulnerability edition was missing 'critical' severity.
    • Objects merge bugfixing
    • Metadata recursive save fix
    "},{"location":"RELEASE/#nov-7-2014","title":"Nov 7, 2014:","text":"

    You can get the new version here:

    • https://github.com/infobyte/faraday/archive/v1.0.6.tar.gz

    Changes:

    • Status report modifications:
    • Web vulnerability edition support.
    • Variable columns in status report.
    • New field called \"Data\" with extra information about a vulnerability.
    • Bug fixes
    "},{"location":"RELEASE/#oct-17-2014","title":"Oct 17, 2014:","text":"
    • infobyte/faraday@a81c637

    Status report now have edition capabilities Introducing batch vulnerability edition and deletion. Now you can edit your status report.

    Lots of bug fixes

    Ubuntu 14.04 support fixes Mac support fixes

    "},{"location":"RELEASE/#sep-26-2014","title":"Sep 26, 2014:","text":"
    • infobyte/faraday@440858e

    New Dashboard design with summarized information.

    D3.js Fancy visualizations.

    Vulnerability Status report.

    Command run user/host identification.

    Vulnerability Statistics.

    Optimization Refactor.

    "},{"location":"RELEASE/#jun-06-2014","title":"Jun 06, 2014:","text":"
    • infobyte/faraday@e616bdb

    Notifications: Updating objets on faraday now results in a beautiful notification in the QT ui.

    Performance: Enhacing performance when lots of workspaces are available. We now load each workspace whe it's needed instead of loading ahead the full workspace list.

    UI: Workspace split, now you can select the workspace to visualize. We are now using bootstrap.

    API: New operations on the Rest API (this is just for the following UI modifications). Vulnerability update and delete operations.

    "},{"location":"RELEASE/#may-14-2014","title":"May 14, 2014:","text":"
    • infobyte/faraday@9dfa9ad

    Improving (web interface, vulnerability classification)

    "},{"location":"RELEASE/#apr-30-2014","title":"Apr 30, 2014:","text":"
    • infobyte/faraday@931865f

    MacOS Support

    "},{"location":"RELEASE/#apr-04-2014","title":"Apr 04, 2014:","text":"
    • infobyte/faraday@0fe6978

    We are proud to present two new features that will enhace the Faraday experience. Taking feedback from our users we took account that each of them had particular needs from their consoles (completion, size, fonts, so on so forth) and their need to be able to know what commands where run during an engagement.

    * A brand new ZSH based Terminal UI\n* The Command Run execution history\n
    "},{"location":"Remote-PostgreSQL/","title":"Remote PostgreSQL configuration","text":"

    Faraday uses a connection string stored in /home/faraday/.faraday/config/server.ini to connect to the database. You can use faraday-manage initdb to configure a localhost database (same server as Faraday Server runs). If you opt to use a remote database you will need to create a database role, database and create the schema.

    "},{"location":"Remote-PostgreSQL/#step-0-install-postgresql","title":"Step 0: Install PostgreSQL","text":"

    sudo apt install postgresql-12\n
    or
    sudo yum install postgresql-12\n

    "},{"location":"Remote-PostgreSQL/#step-1-configure-postgresql-for-remote-connection","title":"Step 1: Configure PostgreSQL for remote connection","text":"

    Warning

    Make sure you understand this step. Using the wrong settings could leave your database server insecure

    First, open the hba_config file, to locate the file execute:

    sudo -u postgres psql -c \"show hba_file\"\n

    Add a line for the faraday-server

    host    all             all             192.168.1.2/24            md5\n

    Then, open /etc/postgresql/9.X/main/postgresql.conf

    Allow to listen on the interface or use * for all interfaces:

    listen_addresses = '*'\n
    "},{"location":"Remote-PostgreSQL/#step-2-create-postgresql-role","title":"Step 2: Create PostgreSQL role","text":"

    Login into the database server and execute:

    createuser faraday_postgresql -P\n

    Now, create the database:

    createdb faraday\n
    "},{"location":"Remote-PostgreSQL/#step-3-configure-faraday-server","title":"Step 3: Configure Faraday Server","text":"

    Now on the Faraday Server instance, open the file /home/faraday/.faraday/config/server.ini and append the database configuration:

    [database]\nconnection_string = postgresql+psycopg2://faraday_postgresql:SECRET_PASSWORD@REMOTE_IP/faraday\n
    "},{"location":"Remote-PostgreSQL/#step-4-create-tables","title":"Step 4: Create tables","text":"

    Now you are ready to create the tables:

    faraday-manage create-tables\n
    "},{"location":"Report-v4/","title":"Executive Report","text":"

    The Executive Report feature lets you create (as the name implies) reports using the results obtained in each workspace. When an Executive Report is created, all the data from the Status Report is automatically processed and placed in a Word compatible document or PDF that can then be downloaded from Faraday

    "},{"location":"Report-v4/#managing-executive-reports","title":"Managing Executive Reports","text":"

    To manage your reports you need to access Faraday's Web UI and go to the report icon on the left panel and hit on Create New Report.

    All the reports will be listed, including their information, status and link to download.

    "},{"location":"Report-v4/#making-a-report","title":"Making a report","text":"

    To create a new report, click on New. A form will open asking for the following fields:

    • Title - this is the name that will be used to create the cover of the report.

    • Client Name - Client name to be used inside the report.

    • Template - select the template to use as a base for your report. Depending on the selected dataset the options will change.

    To edit a report, select it and click on the Edit button. A modal will appear allowing you to modify all the report fields. Save it and a brand new report will be generated, keeping the original version intact.

    If, instead, you want a new report that is exactly like an existing one but with the current data of your workspace, you can click on the Regenerate button in the reports list. Reports can only be regenerated one at a time, so the regeneration buttons are disabled while this action is being performed.

    "},{"location":"Report-v4/#executive-and-technical-details-tabs","title":"Executive and Technical details tabs","text":"

    The following are a sort of placeholder fields for information that's commonly added to most reports. They are text fields and can be used for any relevant information, not just for what they're named after:

    • Summary
    • Conclusions
    • Recommendations
    • Scope
    • Objectives

    Faraday processes all the information and spits out a shiny new report that is automatically available for download.

    "},{"location":"Report-v4/#filtering","title":"Filtering","text":"

    If you need a custom report that includes only some findings in the workspace, you can also use the filters to bring those specific vulnerabilities.

    These filters can be mixed to create different outcomes.

    "},{"location":"Report-v4/#deleting-a-report","title":"Deleting a Report","text":"

    From the Executive Report window, select the document and click on Delete.

    "},{"location":"Report-v4/#templates","title":"Templates","text":"

    We use Jinja2 to create Report Templates. Check this Article to get more information!

    "},{"location":"Report-v4/#datasets","title":"Datasets","text":"

    Faraday provides two different datasets to create Executive Reports - generic and grouped.

    Generic

    The generic dataset provides one entry for each individual vulnerability with all of its fields readily available as a dictionary. The field parent contains an ID corresponding to the Vulnerability's parent (either a Host or a Service).

    Grouped

    The grouped dataset groups vulnerabilities by name and description. If two or more vulnerabilities share the same name and description, they will be presented as one. The field parent contains a Python Dictionary-style object with the parent IDs as keys and a Python Dictionary-style object containing evidence_subdoc, data and target as values. Tags and references will be merged for vulnerabilities that are grouped and not separated by parent.

    "},{"location":"Report-v4/#custom-reports","title":"Custom Reports","text":"

    Faraday has the ability to use a custom report, to do so, in the create reports section, there is a selector for a template. For a uploading the report as admin user click on \"custom\" and \"upload template\".

    Select the file from your local and hit on open. A report will be generated with sample data to check on the report. Then select the report from the custom report view.

    Info

    Keep in mind that each template should be designed for a specific dataset and that these are not interchangeable. The default templates that come with your instance are located at /home/faraday/.faraday/executive_reports_templates/

    "},{"location":"SAML-Auth0/","title":"SAML with Auth0","text":"

    Here are the steps to integrate SAML to Faraday using Auth0:

    Step 1: Navigate to Auth0 website.

    Step 2: Sing in with your admin account.

    Step 3: Navigate to Applications \u2192 Applications in the left Menu.

    Step 4: Click Create Application button.

    Step 5: On the Create application page: * Enter the name of the custom app. * (Optional) Choose an application type.

    Then click Create.

    Step 6: In your new app page, go to the Addons tab and turn on the SAML2 WEB APP plugin.

    The addon configuration page will pop up.

    Step 7: On the Usage tab, you should copy the Issuer (Identity ID in Faraday settings) and the Identity Provider Login URL (SSO URL in Faraday settings). Also download the Identity Provider Certificate (IdP Certificate in Faraday settings). Paste them on Faraday's SAML configuration.

    Step 8: Click on Settings tab. Here you should enter an Application Callback URL with following format: * Application Callback URL: https:///_api/saml/acs

    Then click Save

    Step 9: Back in your new app page, go to the Settings tab and scroll down to the Application URIs section. There you should enter the Application Login URI, the Allowed Logout URLs, the Allowed Web Origins and the Allowed Origins (CORS) with the following format: * Application Login URI: https:///_api/saml/login * Allowed Logout URLs: https:///_api/saml/logout * Allowed Web Origins: https:/// * Allowed Origins (CORS): https:///

    Then scroll all the way down and click Save Changes.

    Step 10: Run this command at a Terminal:

    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem\n

    This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

    For more information about configuring a custom SAML app in Auth0, please visit their documentation page about this topic.

    "},{"location":"SAML-Azure/","title":"SAML with Auth0","text":"

    Here are the steps to integrate SAML to Faraday using Azure:

    Step 1: Navigate to Microsoft Azure.

    Step 2: Sing in with your admin account.

    Step 3: Navigate to Entrepise Applications.

    Step 4: Click New Application button.

    Step 5: Click Create your own application button.

    Step 6: On the What's the name of your app? field enter faraday.

    Step 7: On the What are you looking to do with your application? selection enter Integrate any other application you don't find in the gallery (Non-gallery).

    Then click Create.

    Step 8: In your new app page, go to the Single sign-on.

    Step 9: Click SAML button.

    Step 9: Click Edit button in Basic SAML Configuration.

    Step 10: In Identifier (Entity ID) field enter https:///_api/saml/metadata.xml and in Reply URL (Assertion Consumer Service URL) enter https:///_api/saml/acs.

    Step 11: Click Save button.

    Step 12: In the SAML Certificates download the Certificate (Base64).

    Step 13: Now in faraday->settings->saml and follow the fields in the next way:

    * Display Name = 'Farady'\n* Identity ID = The Microsoft Entra Identifier, ej https://sts.windows.net/xxxxx/\n* Attribute Identifier = The field of wicht you want to use as username in faraday\n* SSO URL = The login URL ej https://login.microsoftonline.com/xxxx/saml2\n* IDP Certificate = The content of the SAML Cetificate downloaded in step 12\n

    Step 14: Run this command at a Terminal:

    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem\n

    This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

    "},{"location":"SAML-Google/","title":"SAML with Google","text":"

    Here are the steps to integrate SAML to Faraday using Google:

    Step 1: Navigate to Google admin website.

    Step 2: Sign in using an account with super administrator privileges.

    Step 3: In the Admin console go to Menu \u2192 Apps \u2192 Web and mobile apps.

    Step 4: Click Add app \u2192 Add custom SAML app.

    Step 5: On the App Details page: * Enter the name of the custom app. * (Optional) Upload an app icon.

    Then click Continue.

    Step 6: From the Google Identity Provider details page copy the SSO URL, the Entity ID (Identity ID on Faraday's SAML configuration) and the IDP Certificate. Paste them on Faraday's SAML configuration.

    Click on Continue.

    Step 7: Run this command at a Terminal:

    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem\n

    This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

    Step 8: In the Service Provider Details, enter an ASC URL, Entity ID and Start URL with following format: * ASC URL: https:///_api/saml/acs * Entity ID: https:///_api/saml/metadata.xml * Start URL: https:///_api/saml/login

    Finally, check the Signed response checkbox. Then configure your Name ID and click Continue.

    Step 9: In Attributes mapping page you should select Primary email and define the App attribute as username.

    Then click Finish.

    Step 10: In the Admin console go to Menu \u2192 Apps \u2192 Web and mobile apps. Select your SAML app and click User access.

    Step 11: To turn on the service for everyone in your organization, click On for everyone, and then click Save.

    For more information about configuring a custom SAML app in Google, please visit their support page about this topic.

    "},{"location":"SAML-Okta/","title":"SAML with OKTA","text":"

    Here are the steps to integrate SAML to Faraday using OKTA:

    Step 1: Navigate to OKTA's website.

    Step 2: Log in into your developer account as a user with administrative privileges.

    Step 3: In the Admin console go to Applications \u2192 Applications.

    Step 4: Click Create App Integration.

    Step 5: Select SAML 2.0 in the Sign-in method section. Click Next.

    Step 6: On the General Settings page: * Enter the name of your integration (e.g. Faraday). * (Optional) Upload a logo.

    Then click Next.

    Step 7: On the Configure SAML tab, enter the Assertion Consumer Service (ACS) URL into the Single Sign On URL field and the Entity ID into the Audience Restriction field with the following format: * Single Sign On URL: https:///_api/saml/acs * Audience Restriction: https:///_api/saml/metadata.xml

    After that, in the Attribute Statements section, define the Name of the attribute as username and the Value as user.email.

    Then click Next.

    Step 8: In the final creation step, you should select the options that suits your company and click Finish.

    Step 9: On the General tab, in the Application area, you can access to the Identity Provider Configuration. There you should copy the Identity Provider Single Sign-On URL (SSO URL in Faraday settings), the Identity Provider Issuer (Identity ID in Faraday settings) and the X.509 Certificate (IdP Certificate in Faraday settings). Paste them on Faraday's SAML configuration.

    Click on Save.

    Step 10: Run this command at a Terminal:

    openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 1825 -out certificate.pem\n

    This command will return a key that goes into SP Private Key field and a certificate that goes into SP Certificate field on Faraday's SAML configuration.

    For more information about configuring a custom SAML app in Okta, please visit their documentation page about this topic.

    "},{"location":"SAML/","title":"SAML","text":"

    You can configure SAML single sing-on and keep using local users. But you can't use both LDAP and SAML users at the same time.

    "},{"location":"SAML/#configuration-by-command-line","title":"Configuration by command line","text":"

    In order to configure SAML, run the following command:

    faraday-manage settings -a update saml\n

    Then update every field according to the configuration on-prem.

    $ faraday-manage settings -a update saml\nUpdate settings for: saml\nenabled [False]:\ndisplay_name [Identity Provider]:\nuser_role [admin]:\nadmin_group []:\nattribute_identifier []:\nsso_url [http://localhost/saml/login]:\nsp_certificate []:\nsp_private_key []:\nidp_certificate []:\nDo you confirm your changes on saml?\n[Y/n]:\n

    Remember to restart the server after doing changes!

    systemctl restart faraday-server\n
    "},{"location":"SAML/#configuration-by-ui-preferences","title":"Configuration by UI Preferences","text":"

    You can access to SAML configuration on the Authentication section in the menu of your Preferences.

    "},{"location":"SAML/#services-available-to-integrate-saml-to-faraday","title":"Services available to integrate SAML to Faraday","text":"

    Here is a list of services with a link to its articles:

    • Integrate SAML with Google
    • Integrate SAML with Auth0
    • Integrate SAML with Okta
    "},{"location":"Scheduling/","title":"Scheduler","text":""},{"location":"Scheduling/#scheduling","title":"Scheduling","text":"

    In order to arrange or plan an event to take place at a particular time we've created Scheduler, it will allow to use the POSIX local format, the execution will be made by an agent.

    To configure a schedule click on Automation button on the left navigation and then click on scheduler, to do a new schedule click on Create Schedule.

    Provide a description, interval pattern, select a Tool to run, destination Workspace and click on the Accept button.

    The POSIX cron format is the below:

    Field Possible Values Syntax Description a - Minute 0-59 7 * * * * The cron job is initiated every time the system clock shows 7 in the minute\u2019s position. b - Hour 0-23 0 7 * * * The cron job runs any time the system clock shows 7am (7pm would be coded as 19). c - Day 0-31 0 0 7 * * The day of the month is 7 which means that the job runs every 7th day of the month. d - Month 0 = none and 12 = December 0 0 0 7 * The numerical month is 7 which determines that the job runs only in July.

    In addition to running the agents manually with their \"Run\" button, you can also schedule them to run periodically. This can be done from the web if you have our Corporate/Pro version:

    or with simple cronjobs using faraday-cli if you are using the Community version

    create an script.sh with this contents:

    #!/bin/bash\necho '{\"target\": \"www.google.com\"}' | faraday-cli agent run -a 1 -e nmap --stdin\n

    Edit your crontab using the bellow command

    crontab -e \n1 0 * * 0 /pathtoyourscript/script.sh > /dev/null 2>&1\n
    "},{"location":"Settings-v4/","title":"Settings","text":"

    In order to make Faraday's usage smoother, we have created the Settings section. Here, you can create new Custom Fields, change the account settings, customize the output of the reports and edit Ticketing tools configuration.

    To go into Settings, click on User's menu and then click on Settings:

    As you can see, for now we have two sections: Custom Fields and Preferences.

    "},{"location":"Settings-v4/#custom-fields","title":"Custom Fields","text":"

    You can create/edit/delete a Custom Field from Settings. Let's create one as an example:

    You must fill the following fields in order to create a Custom Field:

    • Name: the name of the field (must be unique).

    • Type: data type of the field, it can be: Integer, List, String, Markdown, Choice.

    Inside the Custom Fields menu you can view the list of all custom fields

    "},{"location":"Settings-v4/#preferences","title":"Preferences","text":"

    Within the Preferences menu you will be able to modify the configuration of different tabs, such asAccount, Report and Ticketing Tools

    "},{"location":"Settings-v4/#account","title":"Account","text":"

    Inside account menu you would be able to modify your password, enable Two Factor Authentification and log in into the last used Workspace

    "},{"location":"Settings-v4/#report","title":"Report","text":"

    On the Report menu you can customize the output of your reports

    "},{"location":"Settings-v4/#ticketing-tools","title":"Ticketing Tools","text":"

    Inside this menu you would be able to choose your preferred Ticketing Tool, this will provide you an extended follow up capabilities

    Each Ticketing Tools has different configurations.

    • Jira
    • Gitlab
    • ServiceNow
    • SolarWinds
    "},{"location":"Tasks/","title":"Tasks","text":"

    You can create your own custom Methodologies, add Tasks, tag them and keep track of your whole project directly from Faraday.

    Faraday comes with Methodologies loaded by default that allow you to get to work quickly without having to create your own.

    A few of our default Methodologies:

    PCI DSS 11.2 Hardware Top 10 Mobile Security Network Pentest Owasp Top 10 Loading a default Methodology All default Methodology files are available at the bottom of this page. Download them, then use the \"New\" button and select the option \"From template\", give this new methodology a name and that's it!

    You can download the methodologies at the bottom of this article.

    "},{"location":"Tasks/#creating-you-own-methodology","title":"Creating you own Methodology","text":"

    Create a .csv file with the following fields:

    name description Then, use the \"Import\" button and select your new .csv to load your custom Methodology to Faraday.

    "},{"location":"Tasks/#downloading-your-preferred-methodology","title":"Downloading your preferred Methodology","text":"

    Do you have a custom Methodology created from scratch? Click in \"Download CSV for current Methodology\" and you will download a .csv file with the information for it!

    "},{"location":"Tasks/#kanban-view","title":"Kanban View","text":"

    If you click on the Methodology name, you'll access the Kanban view for it.

    You can use drag and drop to change the status of the different Tasks, or you can create a new one. You can also edit or delete a task.

    "},{"location":"Tasks/#task","title":"Task","text":"

    Methodologies contain Tasks, which include the following fields:

    • Name
    • Description
    • Due date
    • Status
    • Users assigned
    • Tags

    With that, you can assign a specific Task with a due date to a pentester. Also, tag a chunk of Tasks for a better appreciation in the Kanban view.

    "},{"location":"Tasks/#download-links","title":"Download links","text":"

    Methodology Hardware Top 10

    Methodology Mobile Security

    Methodology Network Pentest

    Methodology OWASP Top 10

    Methodology PCI DSS 6.5

    Methodology PCI DSS 11.2

    "},{"location":"Troubleshooting/","title":"Troubleshooting","text":""},{"location":"Troubleshooting/#intro","title":"Intro","text":"

    This guide is intended to provide solutions for common problems. If your problem is not listed below, make sure to contact us!

    Before moving on, verify that you are using the latest available version running the Client and the Server using --version or -v.

    To get the latest available version visit GitHub

    We recommend upgrading to the latest version before proceeding.

    Also, to get a better understanding of most problems you can run the Faraday Client using --debug or -d option.

    "},{"location":"Troubleshooting/#traceback-troubleshooting","title":"Traceback Troubleshooting","text":"

    For traceback troubleshooting you need to open the Faraday logs and search for the string ERROR. Logs are located on /home/faraday/.faraday/logs.

    In this section we will show common errors and possible solutions. We recommend to search part of the error in this page and try to match the error with possible solutions.

    "},{"location":"Troubleshooting/#index","title":"Index","text":"
    • I can't access the Web GUI
    • Faraday is not importing my report
    • A plugin added too much information to my database
    • How to reset Faraday Server password
    • Can't access Faraday Server remotely
    • [Errno 2] No such file or directory: '/home/USERNAME/.faraday/config/config.xml'
    • Updating Nginx Configuration
    • Error while backing up the database
    • No ports available
    • UnicodeEncodeError: 'ascii' codec can't encode character
    • Database encoding incompatibility executing initdb
    "},{"location":"Troubleshooting/#answers","title":"Answers","text":""},{"location":"Troubleshooting/#i-cant-access-the-web-gui","title":"I can't access the Web GUI","text":"

    Is Faraday Server running? Try running:

    $ faraday-manage status-check\n
    That will give some information about the state Faraday is in at the moment. If the Server is not running try:
    $ faraday-server\n

    "},{"location":"Troubleshooting/#faraday-is-not-importing-my-report","title":"Faraday is not importing my report","text":"

    First let's make sure there is a Plugin to parse it so make sure your tool is listed in our Plugin List. Not there? Code your own or ask us to do it Community, Pro and Corp users

    You can also try to force Faraday to process a report with a certain plugin. For example, let's say you have a Metasploit report that Faraday is not detecting. You can change the report so that it ends with _faraday_Metasploit (first letter of the plugin in uppercase), so it ends up as myreport_faraday_Metasploit.xml, and then copy it to /home/faraday/.faraday/reports/{workspacename} in the Client. This of course works for any plugin, not only Metasploit.

    Keep in mind that Plugins don't run on the Server, so if you're trying to copy the report file, make sure you're doint it on the Client.

    "},{"location":"Troubleshooting/#a-plugin-added-too-much-information-to-my-database","title":"A plugin added too much information to my database","text":"

    You can go to your Activity Feed in the Web GUI, filter the vulnerabilities by whichever parameter you'd like, select them all and then click on Delete to remove them form the database.

    "},{"location":"Troubleshooting/#how-to-reset-faraday-server-password","title":"How to reset Faraday Server password","text":"

    If you forgot the password, or you don't know your Faraday Server password, you can use the command faraday-manage to change it:

    $ faraday-manage change-password\n
    "},{"location":"Troubleshooting/#cant-access-faraday-server-remotely","title":"Can't access Faraday Server remotely","text":"

    In your Server machine, go to /home/faraday/.faraday/config/server.ini and check if you're listening only on the localhost. You should see something like this:

    [faraday_server]\nport=5985\nbind_address=localhost\n

    If your Clients are on different machines than the Server, then you'll need to change the bind_address to your private IP (or all your interfaces). For example:

    bind_address=0.0.0.0\n
    "},{"location":"Troubleshooting/#updating-nginx-configuration","title":"Updating Nginx configuration","text":"

    Note: This only applies if you are using Nginx and https.

    Please, make sure you have this settings on your Nginx config:

    proxy_pass http://localhost:5985/;\nproxy_redirect http:// $scheme://;\n
    "},{"location":"Troubleshooting/#error-while-backing-up-the-database","title":"Error while backing up the database","text":"

    If you get this error:

    \u201cpci_q1\u201d failed: FATAL: role \u201croot\u201d does not exist

    while trying to execute:

    pg_dump <name of workspace> > <name of what I want the backup file to be>

    Run:

    sudo -u postgres -i

    And then try again.

    "},{"location":"Troubleshooting/#no-ports-available","title":"No ports available","text":"

    If you see this traceback:

    Traceback (most recent call last): File \"/usr/share/python-faraday/model/application.py\", line 145, in start CONF.getApiRestfulConInfoPort() File \"/usr/share/python-faraday/apis/rest/api.py\", line 67, in startAPIs raise Exception(\"No ports available!\") Exception: No ports available!

    Go into the file user.xml locates in /home/USERNAME/.faraday/config/

    ~localhost~ 127.0.0.1 9876 9977

    Change localhost for 127.0.0.1 and try again.

    "},{"location":"Troubleshooting/#unicodeencodeerror-ascii-codec-cant-encode-character","title":"UnicodeEncodeError: 'ascii' codec can't encode character","text":"

    If you see a Traceback that ends something like this:

    UnicodeEncodeError: 'ascii' codec can't encode character u'\\xf3' in position 1: ordinal not in range(128)

    Go into your Faraday folder and run the following command:

    $ faraday-manage sql-shell\n

    Once inside the shell execute:

    SHOW SERVER_ENCODING

    If you are using symbols not supported by ASCII, you need to change database's encoding to UTF-8. 1. Dump your database 2. Drop your database, 3. Create new database with the different encoding 4. Reload your data.

    Make sure the client encoding is set correctly during this process.

    "},{"location":"Troubleshooting/#database-encoding-incompatibility-executing-initdb","title":"Database encoding incompatibility executing initdb","text":"

    If you got the following error when running the command faraday-manage initdb:

    ERROR: createdb: database creation failed: ERROR:  new encoding (UTF8) is incompatible with the encoding of the template database (SQL_ASCII)\nHINT:  Use the same encoding as in the template database, or use template0 as template.\n

    You can follow the instructions provided in this link.

    Once you get the solution above, you can try to initialize the database once more:

    faraday-manage initdb\n

    Is your question not listed here? Contact us

    "},{"location":"Troubleshooting/#smtp-is-not-being-saved-from-the-ui","title":"SMTP is not being saved from the UI","text":"

    For this is needed to update manually the configuration on the server side.

    faraday-manage settings -a update smtp\n

    properly set the configuration needed, actually faraday doesn't support accounts without password/user.

    "},{"location":"Troubleshooting/#ldap-reconfigure-after-faraday-3150","title":"LDAP reconfigure after Faraday 3.15.0","text":"

    As part of the constant grow there were introduced new security rules on LDAP and as a consequence when upgrading Faraday to 3.16 it LDAP needs to be reconfigured.

    Steps to do it:

    faraday-manage settings -a update ldap\n

    Then update every field according to the on-prem configuration .

    $ faraday-manage settings -a update ldap\nUpdate settings for: ldap\nenabled [False]:\nuse_local_roles [True]:\ndefault_local_role [admin]:\nadmin_group []:\nasset_owner_group []:\nclient_group []:\npentester_group []:\ndisconnect_timeout [2.0]:\nserver []:\nport [389]:\nuse_ldaps [False]:\nuse_start_tls [False]:\ndomain []:\ndomain_dn []:\nbind_format [CN]:\nbind_dn []:\nuser_class [user]:\nuser_attribute [sAMAccountName]:\ngroup_class [group]:\npaginated_fetch [False]:\nDo you confirm your changes on ldap?\n----------------------\nenabled: False\nuse_local_roles: True\ndefault_local_role: admin\nadmin_group:\nasset_owner_group:\nclient_group:\npentester_group:\ndisconnect_timeout: 2.0\nserver:\nport: 389\nuse_ldaps: False\nuse_start_tls: False\ndomain:\ndomain_dn:\nbind_format: CN\nbind_dn:\nuser_class: user\nuser_attribute: sAMAccountName\ngroup_class: group\npaginated_fetch: False\n[Y/n]:\n

    "},{"location":"Troubleshooting/#my-reports-disappeaered-after-activating-markdown","title":"my reports disappeaered after activating markdown","text":"

    remember that markdown reports are stored at:

    Generic:

    ~/.faraday/executive_reports_templates/markdown_generic\n
    Grouped
    /.faraday/executive_reports_templates/markdown_grouped\n

    "},{"location":"Update/","title":"Update Guide for Ubuntu/Debian/Kali","text":""},{"location":"Update/#requirements","title":"Requirements:","text":"
    • Previous install of Faraday 4.6.2 or bellow
    • Redis
    • Postgres
    "},{"location":"Update/#upgrading-faraday","title":"Upgrading Faraday","text":""},{"location":"Update/#step-1-downloading-faraday-installer","title":"Step 1 - Downloading Faraday Installer","text":"

    Download the Faraday installer (.deb or .rpm) from:

    • Faraday Portal
    "},{"location":"Update/#step-2-upgrading-the-package","title":"Step 2 - Upgrading the package","text":"

    Go to your Download directory and run the following command:

    # For .deb\nsudo apt-get install ./faraday-server_amd64.deb\n

    This process will take charge of installing and migrating all the data to the new version of Faraday.

    "},{"location":"Update/#step-3-migrating-references-from-previous-versions-to-500-only","title":"Step 3 - Migrating References (from previous versions to 5.0.0 only)","text":"

    As part of migrating the data on references faraday run:

    faraday-manage move-references -a true\n
    "},{"location":"Update/#step-4-migrating-host-stats-from-previous-versions-to-511-only","title":"Step 4 - Migrating Host Stats (from previous versions to 5.1.1 only)","text":"

    As part of migrating the data on references faraday run:

    faraday-manage sync-hosts-stats\n
    "},{"location":"Update/#importing-license","title":"Importing License","text":"
    faraday-manage import-license\n

    Or, in isolated servers, download the license file from the portal and place it in /home/faraday/.faraday/doc/. Remove old license files from the doc folder when renewing the license:

    tar xvf {license file}.tar.gz\n
    "},{"location":"Update/#post-upgrade","title":"Post Upgrade","text":"

    Check process and status:

    sudo systemctl status faraday-server\nsudo systemctl enable faraday-server\n\nsudo systemctl status faraday-worker\nsudo systemctl enable faraday-worker\n\nsudo systemctl status faraday-worker-reports\nsudo systemctl enable faraday-worker-reports\n
    "},{"location":"Upload-Report/","title":"Upload Report","text":"

    This wiki will help you to learn the different ways that Faraday has to import a report.

    "},{"location":"Upload-Report/#through-the-web-ui","title":"Through the Web UI.","text":"
    • Go to the tab Status Report and click on the button:
    • Click on Select File in order to select the report that you are going to upload.
    • Once you have selected the report, click on Upload File and your file will be uploaded.
    "},{"location":"Upload-Report/#through-faraday-cli","title":"Through Faraday-Cli","text":"

    Faraday-Cli must be running in each case.

    "},{"location":"Upload-Report/#faraday-cli-community","title":"Faraday-Cli (Community)","text":"

    It's possible to use Faraday in Command-Line Interface (CLI) mode, allowing you to process your reports in batch. So lets say you want to process the XML output of an nmap scan located in /tmp/nmap_scan.xml and send the results to a workspace called project_one. The way to do it using CLI mode would be to run:

    $ faraday-client --cli --workspace project_one --report /tmp/nmap_scan.xml\n
    "},{"location":"Upload-Report/#cli-professional-and-corporate-versions","title":"Cli (Professional and Corporate versions)","text":"

    If you're using a Professional or Corporate version, you'll probably need to run Faraday as a certain user, with permissions to access your workspaces. You can pass your credentials using a simple json file that contains both your username and password. You have a template in the directory of your Faraday installation called credentials.json, but you are allowed to use any path and filename for this json file. The structure is this:

    {\n    \"username\": \"your_user_here\",\n    \"password\": \"your_password_here\"\n}\n

    And then run Faraday:

    $ faraday-client --cli --workspace project_one --report /tmp/nmap_scan.xml --creds-file /path/to/file/credentials.json\n
    "},{"location":"Upload-Report/#through-the-api","title":"Through the API","text":"

    In order to see information about uploading a report through the API, follow this link.

    "},{"location":"Users/","title":"Users","text":"

    As part of the Faraday Server setup procedure, an administrator user is automatically generated. The default username for this administrator account is \"faraday,\" and a random password is generated during the setup process. Make sure to securely store this randomly generated password to facilitate any future password changes if required.

    Info

    In case you intend to modify your password, you can execute the command \"faraday-manage change-password.\"

    For user management tasks, initiate a session in the Faraday Web UI. Subsequently, click on the Faraday slider menu situated on the left pane on the users icon. From there a users section will be displayed.

    "},{"location":"Users/#roles","title":"Roles","text":"

    Faraday supports four types of Roles with different levels of access to the application.

    • Admin: This role lets the administrator manipulate options regarding users, workspaces, vulnerabilities, reports, etc.

    • Pentester: This role is allowed to access permitted workspaces and create, edit or erase vulnerabilities.

    • Asset Owner: This role is similar to the Client role, but can modify Vulnerabilities' Status and add Comments, so it's useful for people working in remediation.

    • Client: This role is allowed to access permitted workspaces without being able to modify anything.

    "},{"location":"Users/#ldapad-integration","title":"LDAP/AD Integration","text":"

    You can also enhance your User management inside Faraday with our LDAP/Active Directory integration. More information available here.

    "},{"location":"Using-custom-fields-from-the-API/","title":"Custom Attributes usage with Faraday API","text":"

    Custom Attributes allows you to extend the vulnerability's model by adding more fields. Custom Attributes type can be int, str or list. You can learn more about Custom Attributes creation on this wiki page.

    In this small tutorial, we are going to use Python's library Requests and Faraday's API to authenticate, create a vulnerability and modify its Custom Attributes.

    "},{"location":"Using-custom-fields-from-the-API/#step-1-authentication","title":"Step 1: Authentication","text":"

    To authenticate in Faraday, we are going to use a function called faraday_authentication(). This function will return an authenticated request session.

    def faraday_authentication(host, username, password):\n    \"\"\"\n       @host: Faraday server host, e.g: http://127.0.0.1:5985\n       @username: Faraday username\n       @password: username's password\n\n       Return requests session object\n    \"\"\"\n    session = requests.Session()\n    headers = {\n        'Content-Type': 'application/json', # Very important! send this content-type header!!\n    }\n    data = '{\"email\":username,\"password\": password}'\n    response = s.post('{0}/_api/login'.format(host), headers=headers, data=data)\n    assert response.status_code == 200\n    return session\n
    "},{"location":"Using-custom-fields-from-the-API/#step-2-create-custom-attributes","title":"Step 2: Create Custom Attributes","text":"

    In order to create a new Custom Attribute, follow the steps specified in this wiki page.

    "},{"location":"Using-custom-fields-from-the-API/#step-3-create-a-vulnerability-from-the-api","title":"Step 3: Create a vulnerability from the API","text":"

    Before using the API, you need to understand how to send the data to the server. Faraday Server accepts JSON. Assuming that you created a custom attribute with the following data: Field name: cvss, Display name: CVSS and assuming that this vulnerability has as CVSS, the score \"4\", the JSON format for creating this vulnerability is the following:

    {\n  \"metadata\": {\n    \"update_time\": 1549569790.632,\n    \"update_user\": \"\",\n    \"update_action\": 0,\n    \"creator\": \"UI Web\",\n    \"create_time\": 1549569790.632,\n    \"update_controller_action\": \"UI Web New\",\n    \"owner\": \"faraday\"\n  },\n  \"obj_id\": \"\",\n  \"owner\": \"faraday\",\n  \"parent\": 24,\n  \"parent_type\": \"Host\",\n  \"type\": \"Vulnerability\",\n  \"ws\": \"demo_workspace\",\n  \"confirmed\": true,\n  \"data\": \"\",\n  \"desc\": \"Test\",\n  \"easeofresolution\": null,\n  \"impact\": {\n    \"accountability\": false,\n    \"availability\": false,\n    \"confidentiality\": false,\n    \"integrity\": false\n  },\n  \"name\": \"dsadsadsa\",\n  \"owned\": false,\n  \"policyviolations\": [],\n  \"refs\": [],\n  \"resolution\": \"\",\n  \"severity\": \"unclassified\",\n  \"issuetracker\": \"\",\n  \"status\": \"opened\",\n  \"custom_fields\": {\n    \"CVSS\" : \"4\"\n  },\n  \"_attachments\": {},\n  \"description\": \"\",\n  \"protocol\": \"\",\n  \"version\": \"\"\n}\n

    Important * Note that we have a key called \"custom_fields\" (which contains our custom attributes) with its display name and its value:

    \"custom_fields\": {\n  \"CVSS\" : \"4\"\n}\n

    • Two important fields that we need to understand are parent_id and parent_type. In the JSON above, we specified them as follow:
       \"parent_type\" : \"Host\"\n \"parent_id\" : \"24\" \n
      This mean that in our database we have a Host with id 24. If you don't specify this two fields, you will get an invalid response.

    You can learn more about the API Server by following this link

    "},{"location":"Using-custom-fields-from-the-API/#code-sample-for-creating-a-vulnerability","title":"Code sample for creating a vulnerability","text":"

    Now, let's see a code sample that will create a new vulnerability called Test inside a workspace named demo_workspace. As vuln_payload we will use the JSON that we specified above:

    faraday_host = 'http://127.0.0.1:5985'\nsession = faraday_authentication(faraday_host, 'faraday', 'secret')\nvulnerability_url = '{0}//_api/v3/ws/demo_workspace/vulns/386/'.format(faraday_host)\nvuln_payload = '{\"metadata\":{\"update_time\":1549569790.632,\"update_user\":\"\",\"update_action\":0,\"creator\":\"UI Web\",\"create_time\":1549569790.632,\"update_controller_action\":\"UI Web New\",\"owner\":\"faraday\"},\"obj_id\":\"\",\"owner\":\"faraday\",\"parent\":24,\"parent_type\":\"Host\",\"type\":\"Vulnerability\",\"ws\":\"demo_workspace\",\"confirmed\":true,\"data\":\"\",\"desc\":\"dsadsadsa\",\"easeofresolution\":null,\"impact\":{\"accountability\":false,\"availability\":false,\"confidentiality\":false,\"integrity\":false},\"name\":\"Test\",\"owned\":false,\"policyviolations\":[],\"refs\":[],\"resolution\":\"\",\"severity\":\"unclassified\",\"issuetracker\":\"\",\"status\":\"opened\",\"custom_fields\":{\"CVSS\" : \"4\"},\"_attachments\":{},\"description\":\"\",\"protocol\":\"\",\"version\":\"\"}'\nresponse = session.post(vulnerability_url, json=vuln_payload)\n

    The server is going to answer with the created vulnerability and it will return status code \"201\" (if the creation was successfull) or \"409\" (if there was any conflict). In our case it returned the status code \"201\" and a JSON with the response.

    We can get the vulnerability id by getting the key \"id\" from the JSON response. In this case, the vulnerability id is _386.

    Important: If you didn't create the Custom Attribute (see step 2), it will not be seen in the vulnerability. Remember to create the custom attribute first.

    "},{"location":"Using-custom-fields-from-the-API/#getting-the-vulnerability-by-its-id-using-the-api","title":"Getting the vulnerability by its ID using the API","text":"

    Now you can do a GET request on the following url to see the vulnerability in JSON format. Note that we are using the same id as the one we get above (386):

    http://localhost:5985/_api/v3/ws/demo_workspace/vulns/386/

    "},{"location":"Using-custom-fields-from-the-API/#step-4-update-custom-attributes","title":"Step 4: Update Custom Attributes","text":"

    In the next example, we are going to update the Custom Attribute \"CVSS\" located in the vulnerability 386. The new value will be \"5\".

    Note: When you update a vulnerability, you need to send the full JSON body of the vulnerability.

    faraday_host = 'http://127.0.0.1:5985'\nsession = faraday_authentication(faraday_host, 'faraday', 'secret')\nvulnerability_url = '{0}/_api/v3/ws/demo_workspace/vulns/386/'.format(faraday_host)\nvuln_payload = '{\"metadata\":{\"update_time\":1549569790.632,\"update_user\":\"\",\"update_action\":0,\"creator\":\"UI Web\",\"create_time\":1549569790.632,\"update_controller_action\":\"UI Web New\",\"owner\":\"faraday\"},\"obj_id\":\"\",\"owner\":\"faraday\",\"parent\":24,\"parent_type\":\"Host\",\"type\":\"Vulnerability\",\"ws\":\"demo_workspace\",\"confirmed\":true,\"data\":\"\",\"desc\":\"dsadsadsa\",\"easeofresolution\":null,\"impact\":{\"accountability\":false,\"availability\":false,\"confidentiality\":false,\"integrity\":false},\"name\":\"Test\",\"owned\":false,\"policyviolations\":[],\"refs\":[],\"resolution\":\"\",\"severity\":\"unclassified\",\"issuetracker\":\"\",\"status\":\"opened\",\"custom_fields\":\"CVSS\": \"5\",\"_attachments\":{},\"description\":\"\",\"protocol\":\"\",\"version\":\"\"}'\nresponse = session.put(vulnerability_url, json=vuln_payload)\n

    Note that we have changed the value of \"CVSS\" on the JSON: ``` \"custom_fields\": { \"CVSS\" : \"5\" }

    "},{"location":"Vulnerability-Templates-KB/","title":"KB Vulnerability Templates","text":"

    Find yourself writing the same descriptions over and over again? Tired of typos coming up in your reports? Faraday provides a simple solution: unify criteria for naming vulnerabilities and save time and effort to yourself and your team.

    Write vulns once and use them forever!

    Faraday Server allows you to import your own CWE Vulnerabilities DB for you to use as templates. Is a simple CSV made using Open Source projects based in the CWE standard and allows you to create vulnerabilities without worrying about finding references, description, etc.

    "},{"location":"Vulnerability-Templates-KB/#populate-your-kb","title":"Populate your KB","text":""},{"location":"Vulnerability-Templates-KB/#import-csv-file","title":"Import csv file","text":"

    Download our CWE example:

    • CWE EN

    • CWE ES

    Navigate into Vulnerability > Vuln Template tab in your Faraday Instance Web UI and click on the Add Template Button:

    A dropdown will appear and select Import From File.

    "},{"location":"Vulnerability-Templates-KB/#adding-a-template-from-vuln","title":"Adding a Template from Vuln","text":"

    You can also create templates manually from a vuln. In the Web UI, select a vuln and select Create template from the dropdown menu.

    You will get a list of the existing templates in your installation

    "},{"location":"Vulnerability-Templates-KB/#adding-a-template-manually","title":"Adding a Template manually","text":"

    Navigate into Vulenrabilty > Vuln Template tab in your Faraday Instance Web UI and click on the Add Template button:

    You will get a form to generate the template.

    "},{"location":"Vulnerability-Templates-KB/#usage","title":"Usage","text":""},{"location":"Vulnerability-Templates-KB/#creating-vuln-from-template","title":"Creating Vuln from Template","text":"

    Click on new Vulnerability, on the name parameter Templates can be selected easily to select a Template form the name search.

    You can also duplicate vulnerabilities easily by saving them as a template and later on importing the template.

    Note

    Name, Description and Resolution fields are replaced with the information stored in the templates database.

    "},{"location":"Vulns/","title":"Vulnerability Management","text":"

    To view a full list of yours findings you can access the Vulns view by clicking the Vulnerabilities button on the left menu.

    The Vulns View provides several options including vulnerability search, filtering and management.

    Personalize this view by adding or removing columns in the Edit Column Order view, where you can select or deselect them from their checkboxes. You can access this view by clicking this button in the top right corner.

    Also, you can drag & drop some labels of columns and change their order on the table.

    These changes will be persisted in your browser from session to session, so you only have to apply them once.

    There are many ways to add vulnerabilities into Faraday, create them manually, import scan reports, with supported tools, Faraday Agents or using Faraday API.

    "},{"location":"Vulns/#import-scan-reports","title":"Import Scan Reports","text":"

    You can upload a scan report of your favorite tool to Faraday and have a nice look at your findings through the Vulns View. You can see a list of the tools that Faraday supports by clicking on this link

    In order to upload a report to Faraday, follow these instructions:

    • Click on the button + Add Vulnerability.
    • Click on the button Import from file and a prompt will be displayed.
    • Click on Browse in order to select the report that you are going to upload, or just drag and drop the file into the box.
    • Once you have selected the report, click on Upload and your file will be uploaded.
    • Refresh the view with the top bar refresh icon.
    "},{"location":"Vulns/#create-a-vulnerability","title":"Create a Vulnerability","text":"

    To create vulnerabilities manually, you can go to the Vulns View page and click the + Add Vulnerability button and then click on Manual Creation. You should see a dialog similar to this:

    The image above shows the tab General that allows you to specify the name, description and severity of your vulnerability. Also, you can specify the ease of resolution, an external ID, its impact, a resolution, its policy violations and references.

    You also have another tabs in order to add more information to your vulnerability:

    • Technical Details: allows you to add the field data to your vulnerability. If you're creating a web vulnerability, you add information about request and response.

    • Custom Fields: allows you to add information to a field that you have created. For more information about Custom Fields, you can check it here.

    • Assets: when you fill at least the three mandatory fields of the General tab (name, description and severity), the Assets tab becomes available. Here you can select from a select box 1 to N targets (in order to create 1 to N vulnerabilities), or type a new target if it's not yet in the list.

    • Evidence: allows you to add an evidence to the vulnerability. It can be a PNG or JPG image.

    Make sure you select a host (and a service if the vulnerability applies to it), a name and a description. These fields are mandatory to create a vulnerability

    "},{"location":"Vulns/#edit-vulnerabilities","title":"Edit Vulnerabilities","text":"

    You can edit the vulnerabilities that you have created or imported. You have multiple ways to edit them.

    "},{"location":"Vulns/#from-vuln-preview","title":"From Vuln Preview","text":"

    You can see a preview of the vulnerability by click on the vuln's name. From here you can edit your vulnerability, and it will be saved automatically.

    As you can see in the image above, there is a new tab named Comments where you can leave comments and mention other users to notify them about important events in real time. For more information about Comments, you can check it here

    "},{"location":"Vulns/#edit-button","title":"Edit Button","text":"

    If you click on the Edit icon, the vulnerability edit mode will open

    Once you finish updating click on SAVE at the end of the section you are changing.

    "},{"location":"Vulns/#edit-multiple-vulnerabilities","title":"Edit Multiple Vulnerabilities","text":"

    You can select and edit multiple vulnerabilities with just one click. Next to the edit button, you will find a three dotted button that will show a dropdown with the multiple values that you can edit at once or actions like, Create vulnerability templates (KB)

    "},{"location":"Vulns/#delete-vulnerabilities","title":"Delete Vulnerabilities","text":"

    Select one or more vulnerabilities and click Delete icon

    "},{"location":"Vulns/#confirmed-vulnerabilities","title":"Confirmed Vulnerabilities","text":"

    You can filter your vulnerabilities by confirmed, unconfirmed by clicking on the Flag icon button:

    "},{"location":"Vulns/#tags","title":"Tags","text":"

    Tags allow you to organize your vulnerabilities by letting you make and edit categories: environment, technology, state, language, projects, etc. You can also use Tags for Reports, allowing you to filter which vulnerabilities you want to generate a report for.

    "},{"location":"Vulns/#how-to-tag-vulnerabilities","title":"How to Tag Vulnerabilities","text":"

    Select the vulnerabilities that you want to tag.

    Click on the \"Tags\" icon and select if you have a preset tag or Create tag button if you need a new one.

    If you are going to create one just put a relevant name and a dialogue will be displayed.

    Now the vulnerability has tags that you can use for filtering, searching or reporting

    "},{"location":"Vulns/#search-and-filter-vulnerabilities","title":"Search and Filter Vulnerabilities","text":"

    Vulns View allows you to filter vulnerabilities, so you can have a better workflow.

    You can search or filter your data by specifying a keyword or multiple keywords.

    Field values are not case-sensitive

    "},{"location":"Vulns/#how-to-filter","title":"How To Filter","text":"

    In order to perform a search, first click on the search bar and follow these steps:

    1. Select if you want to filter by Vulnerabilities or Assets.
    2. Enter the name of the field (e.g. severity) and select from the list displayed.
    3. Select the connector type that you need to perform the wanted filter (these connectors vary according to the field selected).
    4. Finally, type your query or select an option from the list displayed, according to the field and connector selected.
    5. Repeat steps 2 to 4 if you want to filter by more than one field.

    Examples:

    You can also click on blue fields of the vulnerability like Service, Hostnames, Target, Owner, etc. to trigger a search on the specific field

    "},{"location":"Vulns/#filter-fields","title":"Filter Fields","text":"

    Now, let's take a look at which fields are available for filtering with an example. All of them are searched through the search field

    • Name | = | TCP timestamps
    • Description | contains | Vulnerability testing
    • Severity | = | Medium
    • Target | = | 127.0.0.1
    • Service name | contains | https
    • Service port | >= | 5000
    • Ease of Resolution | = | Moderate
    • Status | != | Closed
    • Resolution | contains | Resolution for testing vuln
    • Data | contains | Search and filter
    • Request | contains | json
    • Response | = | OK
    • Method | = | POST
    • Path | = | Vulnerability Path
    • Creator command id | != | 1
    • Type | = | Vulnerability Web
    • Confirmed | = | True
    • ID | = | 57448
    • Tag | = | my_tag

    From the Vulns view you will be able to find the information using the tags parameter For example: tags:\"MY TAG\" as shown in the image below

    "},{"location":"Vulns/#saved-filters-and-quick-filters","title":"Saved Filters and Quick Filters","text":"

    The filters that you create from the search bar, you can save them in order to use them in other opportunities.

    You can access to these saved filters from the filters button in the top right corner.

    When you click that button, a dialog opens, in addition to selecting a saved filter, you will be able to select from a varied list of quick filters, as shown in the image below.

    "},{"location":"Vulns/#download-a-filtered-workspace","title":"Download a Filtered Workspace","text":"

    You can download a csv file of the filtered workspace (or the full workspace if no filters applied). In order to do so, you have to click on the Download Filtered Workspace button located next to the filters button in the top right corner.

    "},{"location":"Vulns/#context-menu","title":"Context Menu","text":"

    A new feature in Faraday is the Context Menu, which you can access by right-clicking on the Vulns view.

    "},{"location":"Vulns/#single-selection-context-menu","title":"Single selection context menu","text":"

    If you have a single vulnerability selected you will access to the single selection context menu. It should be noted that if you don't have any vulnerability selected yet, the vulnerability of the row where you perform the right click will be selected in order to be used by the context menu.

    This menu allows the user to execute some actions in a faster manner, such as:

    • Filter By
    • Name: creates and executes a filter of the form Name | contains | {name_of_selected_vuln}.
    • Service name: creates and executes a filter of the form Service name | = | {service_name_of_selected_vuln}.
    • Target: creates and executes a filter of the form Target | = | {target_of_selected_vuln}.
    • Date: creates and executes a filter of the form Creation Date | = | {creation_date_of_selected_vuln}.
    • Status: creates and executes a filter of the form Status | = | {status_of_selected_vuln}.
    • Tags: creates and executes a filter for each tag the selected vulnerability has, of the form Tag | = | {tag_of_selected_vuln}.
    • Copy Link: copies to the clipboard the link of the detailed view of the selected vulnerability.
    • Copy Api Call Link: copies to the clipboard the path of the selected vulnerability in order to be managed through Faraday API.
    • Edit: enables the edition of some fields of the selected vulnerability:
    • Name
    • Data
    • Description
    • Resolution
    • References
    • Impact
    • Policy violation
    • Ease of resolution
    • Tag: enables the addition of a created tag to the selected vulnerability and the creation of a new tag.
    • Severity: allows you to select a new severity for the selected vulnerability.
    • Status: allows you to select a new status for the selected vulnerability.
    • Add Comment: allows you to add a comment on the selected vulnerability.
    • Add Evidence: allows you to add an evidence on the selected vulnerability.
    • Create Template: allows you to create a vulnerability template from the selected vulnerability.
    • Delete: deletes the selected vulnerability.
    "},{"location":"Vulns/#multiple-selection-context-menu","title":"Multiple selection context menu","text":"

    If you selected more than one vulnerability, you will access to the multiple selection context menu. It's a shortened version of the regular context menu:

    • Edit: enables the bulk edition of some fields of the selected vulnerabilities:
    • Name
    • Data
    • Description
    • Resolution
    • References
    • Impact
    • Policy violation
    • Confirm/False positive
    • Ease of resolution
    • Tag: enables the addition of a created tag to the selected vulnerabilities and the creation of a new tag.
    • Severity: allows you to select a new severity for the selected vulnerabilities.
    • Status: allows you to select a new status for the selected vulnerabilities.
    • Create Template: allows you to create a vulnerability template from each of the selected vulnerabilities.
    • Bulk Delete: performs a bulk delete of the selected vulnerabilities.
    "},{"location":"Workspaces/","title":"Workspaces","text":"

    Information is organized into various Workspaces. Each Workspace contains a pentest team's assignments and all the intel that is discovered.

    The workspaces are used to hold the information re-collected from the different tools and/ or commands used in the \"actions\" for each Penetration Test. Each workspace integrates all the results from pentesters from a given project in the Web console allowing you to identify and manage your information in one place.

    "},{"location":"Workspaces/#how-to-manage-workspaces","title":"How to Manage Workspaces","text":"

    To manage your workspaces you need to access your Faraday Web UI and click on the Faraday Logo on the left top of the screen and then on Wokspaces

    A list of workspaces and summary are displayed where you can create, edit or delete them

    "},{"location":"Workspaces/#create-a-workspace","title":"Create a Workspace","text":"

    From the workspaces window click on + Add Workspace button and complete below

    • Workspace Name
    • Start Date/ End Date
    • Description
    • Make Workspace public (all users can see it)
    • Assign Users

    "},{"location":"Workspaces/#edit-a-workspace","title":"Edit a Workspace","text":"

    From the workspace window select the workspace and click on Edit icon

    "},{"location":"Workspaces/#delete-a-workspace","title":"Delete a Workspace","text":"

    From the workspaces window select the workspace and click on Delete trash icon

    "},{"location":"Workspaces/#read-only-workspaces","title":"Read Only Workspaces","text":"

    You can make a workspace READ ONLY from the Workspace View (padlock icon) When the padlock icon is closed, the workspace became READ ONLY Once a workspace is READ ONLY, you can't add/modify/delete Vulnerablities, Hosts or Services. You need click on the padlock (padlock open) to put the Workspace in write mode

    The amount of Workspaces allowed will depend on your license type, workspaces in READ ONLY state has not limits.

    "},{"location":"Workspaces/#active-workspaces","title":"Active Workspaces","text":"

    Note: If you click on the green ACTIVE icon of a workspace, it will disapear from the list, basically making it Archived You need to click Show archived to displayed them, click on ACTIVE icon again to work on them

    "},{"location":"agents-v4/","title":"Agents","text":""},{"location":"agents-v4/#easier-integrations-with-faraday-agents","title":"Easier integrations with Faraday Agents","text":"

    Integrating systems is a challenging yet essential task in the lifecycle of any software product. Developers often encounter unfamiliar languages, undocumented APIs, or new paradigms when attempting to integrate with external tools. Consequently, many product teams opt not to offer integration capabilities.

    In the case of Faraday, we recognize that seamless integrations with other security tools are crucial for our product. However, we realized that our existing Plugin system didn't provide the expected ease of use for developing integrations. It required a certain level of interactivity, such as executing commands from the console or importing a report, which made it cumbersome for periodic usage. Additionally, the reliance on our Python API posed difficulties for developers when integrating with tools that weren't programmed in Python.

    To address this challenge, we made the decision to introduce the Agents feature in the latest release of Faraday (v3.9). Recognizing its significance as a core feature, we are thrilled to offer it in both the Community and commercial versions of our product.

    "},{"location":"agents-v4/#architecture","title":"Architecture","text":""},{"location":"agents-v4/#overview-of-the-agents-feature","title":"Overview of the Agents Feature","text":"

    An Agent represents a process running continuously in a machine (not necessary the same running the Faraday Server). When a user decides to run an Agent (typically done through the Faraday Web UI), it will execute a code and send data back to a Workspace.

    The image displayed showcases a workspace featuring several customized agents. These agents perform various tasks, such as utilizing nmap to discover hosts within the network, employing sublist3r to identify subdomains, and retrieving data from our services hosted on Heroku.

    Beyond manually executing the agents using their respective \"Run\" buttons, it is also possible to schedule them for periodic execution. However, please note that this scheduling capability is exclusively available through the web interface for users of our Corporate version.

    Now you can Run an Agent for a single use!

    or with simple cronjobs if you are using the Community or Paid version.

    "},{"location":"agents-v4/#agents-technical-details","title":"Agents technical details","text":"

    To simplify integrations with Faraday, we have developed the Faraday Agent Dispatcher. This project acts as a communication middleware between the Faraday Server and your custom agents.

    To create integrations, you can build an Executor script that outputs data in JSON format to the standard output. This script handles tasks like retrieving host information, vulnerabilities, and more. The Dispatcher abstracts the complexities of APIs and communication protocols, allowing you to focus on generating the necessary JSON data. By leveraging the standard output for data transfer, the Dispatcher seamlessly handles the integration process. For further insight into the project's concept, you can refer to the explanation provided by one of our developers here.

    This flexible approach enables you to employ a wide range of programming languages for your integrations. As long as the language supports standard output printing, you can develop agents in languages like Python, Bash, or even unconventional choices like Brainfuck.

    We offer official executors that are pre-configured and require minimal setup. Alternatively, you have the option to create and execute custom executors tailored to your specific requirements. For detailed instructions on developing and running custom executors, refer to our custom executor documentation!

    "},{"location":"agents-v4/#how-to-start-using-agents","title":"How to start using agents","text":"

    Lets try with an example with Nmap to check the Faraday Agents capabilities both as a custom executor, and run an official one.

    First of all you must install the Faraday Dispatcher inside the server you want to run the Agent on. You can do so running one of the following commands:

    $ git clone https://github.com/infobyte/faraday_agent_dispatcher\n
    $ git clone https://github.com/infobyte/faraday_agent_parameter__types\n

    $ pip3 install faraday_agent_dispatcher\n
    After this, you can setup the agent through the Web UI by clicking the tab Create Agent, a windows like this will be displayed

    Once you choose your desired configuration, you'll be able to select the tools that need to be run

    After selecting the tools, you'll be able to download the dispatcher.yaml

    Please follow the instruccions depending on what you are working with, in this case we are using Python, so in order to make this work the dispatcher.yaml must be placed in the following folder

    $HOME/.faraday/config\n

    Now you would be able to run the agent in your server

    If you have done this correctly, the new agent will be displayed in the Agent view

    Or you can just do it in the manual way running the configuration wizard:

    $ faraday-dispatcher config-wizard\n
    Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: A\nSection: server\nhost [127.0.0.1]: server.faradaysec.com\nssl [True]:\nssl_port [443]:\nssl_cert []:\nTrying to save with empty value\nworkspace [workspace]:\nSection: tokens\nregistration [ACorrectTokenHas25CharLen]: ImalA8Cg1L6Z5Qbx2u9CFAsob\nSection: agent\nagent_name [agent]: nmap\nDo you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: E\nThe actual configured executors are: []\nDo you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nName: nmap\nIs a custom executor? (Y, N) [N]: Y\nCommand to execute [exit 1]: python3 /home/faraday/faraday_agent_dispatcher/static/executors/official/nmap.py\nMax data sent to server [65536]:\nThe actual nmap executor's environment variables are: []\nDo you want to [A]dd, [M]odify or [D]elete an environment variable? Do you want to [Q]uit? (A, M, D, Q) [Q]:\nThe actual nmap executor's arguments are: []\nDo you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nArgument name: port_list\nIs mandatory? (Y, N): Y\nThe actual nmap executor's arguments are: ['port_list']\nDo you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nArgument name: target\nIs mandatory? (Y, N): Y\nThe actual nmap executor's arguments are: ['port_list', 'target']\nDo you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: Q\nThe actual configured executors are: ['nmap']\nDo you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nName: nmapOfficial\nIs a custom executor? (Y, N) [N]:\nThe executors are:\n1: wpscan.py\n2: sublist3r.sh\n3: nmap.py\n4: nikto2.py\n5: nessus.py\n+: Next page\nQ: Don't choose\nChoose one: 3\nMax data sent to server [65536]:\nThe actual configured executors are: ['nmap', 'nmapOfficial']\nDo you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]:\nDo you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]:\n

    All the information you added with the configuration wizard should appear on a new dispatcher.ini file at your /.faraday/config/ directory:

    $ cat  $HOME/.faraday/config/dispatcher.yaml\n[server]\nhost = server.faradaysec.com\nssl = True\napi_port = 443\nwebsocket_port = 443\nssl_cert =\nworkspace = agent_workspaces\n[tokens]\nregistration = ImalA8Cg1L6Z5Qbx2u9CFAsob\n[agent]\nagent_name = nmap\nexecutors = nmap,nmapOfficial\n[nmap]\ncmd = python3 /Users/famato/dev/faraday_agent_dispatcher/contrib/nmap.py\nmax_size = 65536\n[nmap_params]\nport_list = True\ntarget = True\n[nmap_varenvs]\n[nmapOfficial]\nmax_size = 65536\nrepo_executor = nmap.py\n[nmapOfficial_params]\nport_list = True\ntarget = True\n[nmapOfficial_varenvs]\n

    Now you have to run the dispatcher to register the Agent on your Faraday Server:

    $ faraday-dispatcher run\n
    2020-05-11 21:14:01,061 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:91 - register()]  token_registration_url: https://server.faradaysec.com:443/_api/v2/ws/agent_workspaces/agent_registration/\n2020-05-11 21:14:01,977 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:115 - register()]  Registered successfully\n2020-05-11 21:14:02,639 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:150 - connect()]  Connection to Faraday server succeeded\n

    After this, you\u2019ll see your new Agent on the Web UI. The last step is that you just run the nmap Agent:

    And the Dispatcher log will give you details about this action:

    2022-02-03 15:59:29,676 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:153 - register()]  token_registration_url: https://pro-staging.app3.faradaysec.com:443/_api/v3/agent_registration\n2022-02-03 15:59:30,479 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:192 - register()]  Registered successfully\n2022-02-03 15:59:31,434 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:235 - connect()]  Connection to Faraday server succeeded\n2022-02-03 16:10:11,385 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:256 - run_once()]  Parsing data: {\"execution_id\": 9, \"agent_id\": 3, \"workspace\": \"my_workspace\", \"action\": \"RUN\", \"executor\": \"nmap\", \"args\": {\"TARGET\": \"127.0.0.1\"}}\n2022-02-03 16:10:11,419 - faraday_agent_dispatcher - INFO {MainThread} [metadata_utils.py:59 - check_commands()]  Dependency check ended. Ready to go\n2022-02-03 16:10:11,419 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:415 - run_once()]  Running nmap executor\n{\"hosts\": [{\"ip\": \"127.0.0.1\", \"os\": \"unknown\", \"hostnames\": [\"localhost\"], \"description\": \"\", \"mac\": \"00:00:00:00:00:00\", \"credentials\": [], \"services\": [], \"vulnerabilities\": [], \"tags\": []}], \"command\": {\"tool\": \"Nmap\", \"command\": \"Nmap\", \"params\": \"\", \"user\": \"\", \"hostname\": \"\", \"start_date\": \"2022-02-03T19:10:11.665787\", \"duration\": 46861, \"import_source\": \"report\"}}\nstderr sent empty data, \n2022-02-03 16:10:13,246 - faraday_agent_dispatcher - INFO {MainThread} [executor_helper.py:118 - processing()]  Data sent to bulk create\n2022-02-03 16:10:14,021 - faraday_agent_dispatcher - INFO {MainThread} [executor_helper.py:148 - end_f()]  Data sent to bulk create\nstdout sent empty data, \n2022-02-03 16:10:14,021 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:456 - run_once()]  Executor nmap finished successfully\n

    Right after the Agent executes these actions, return to your Workspace and you can review all the information that was found. Now you are ready to deploy your own Faraday Agents through your network! The Dispatcher README file has more detailed documentation to run and build your Agents. Also, we recommend you to check our examples and official executors to get an idea of what a custom integration looks like.

    "},{"location":"agents-v4/#whats-next","title":"What's Next","text":"

    Recently we added Appscan, Qualys and Tenable.io compatibility! try them out!

    We are committed to enhancing the features and usability of Agents while continuously adding new executors to the Dispatcher repository. In upcoming releases, our focus will also be on providing select Agents with read access to their Workspace. This access will enable them to leverage existing data for uncovering more valuable information.

    We hope you enjoy this feature and find it useful!

    "},{"location":"agents/","title":"Agents","text":""},{"location":"agents/#easier-integrations-with-faraday-agents","title":"Easier integrations with Faraday Agents","text":"

    Integrating systems is an elusive but mandatory job in any software product's life. Developers have to deal with languages they don't know, undocumented APIs or new paradigms. This leads to the fact that many product teams decide not to open the possibility to integrate to them.

    In Faraday\u2019s case, we are aware that integrations with other security tools are a critical part of our product. However, we\u2019ve realized that our existing Plugin system wasn\u2019t as easy as we expected to develop some integrations: it required some level of interactivity (either running a command from the console or importing a report), so it was hard to use on a periodic basis. It also forced integration developers to use our Python API, even when the tool to integrate with wasn\u2019t programmed in Python, making it harder for the developer.

    To solve this problem, we decided to implement the Agents feature in the already released Faraday v3.9. Since we expect this to be a core feature of our product, it will be available both in Community and commercial versions!.

    "},{"location":"agents/#architecture","title":"Architecture","text":""},{"location":"agents/#overview-of-the-agents-feature","title":"Overview of the Agents Feature","text":"

    An Agent represents a process running continuously in a machine (not necessary the same running the Faraday Server). When a user decides to run an Agent (typically done through the Faraday Web UI), it will execute a code and send data back to a Workspace.

    In the image above, you can see a workspace with many custom agents. They're in charge of finding hosts in the network with nmap, finding subdomains with sublist3r, and provision data from our Heroku-hosted services.

    In addition to running the agents manually with their \"Run\" button, you can also schedule them to run periodically. This can be done from the web if you have our Corporate version:

    Now you can Run an Agent for a single use!

    or with simple cronjobs if you are using the Community or Paid version.

    "},{"location":"agents/#agents-technical-details","title":"Agents technical details","text":"

    To make integrations with Faraday as easy as possible, we developed a project we called Faraday Agent Dispatcher that is in charge of handling the communication between the Faraday Server and your own agents.

    The only thing you\u2019ll need to build your own integrations is a script (we call it an Executor) that prints to standard output all the data you want to send to Faraday (hosts info, vulnerabilities, etc.) encoded in JSON. There is no need to use complex APIs or communication methods, as all of this is abstracted by the Dispatcher. You just need to print JSON to standard out, and the Dispatcher will handle the rest! If you want to know a little bit about the idea behind build this project, one of our developers explain a little about it.

    This also means that you could use virtually any programming language you want to build your integrations, as long as they support printing data to standard output. We've already made agents in Python, Bash, and even a Brainfuckone!

    We have some official executors, which are ready to go with minimum configuration. If you want to develop and run your own executor, you can configure a custom one!

    "},{"location":"agents/#how-to-start-using-agents","title":"How to start using agents","text":"

    Lets try with an example with Nmap to check the Faraday Agents\u2019 capabilities both as a custom executor, and run an official one. First of all you have to get your Agent\u2019s token. On your Web UI go to Settings > Agents.

    Your token is: ImalA8Cg1L6Z5Qbx2u9CFAsob

    Now you must install the Faraday Dispatcher inside the server you want to run the Agent on. You can do so running one of the following commands:

    $ git clone https://github.com/infobyte/faraday_agent_dispatcher\n
    $ git clone https://github.com/infobyte/faraday_agent_parameter__types\n
    $ pip3 install faraday_agent_dispatcher\n

    After this, you need to run the configuration wizard:

    $ faraday-dispatcher config-wizard\n
    Do you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: A\nSection: server\nhost [127.0.0.1]: server.faradaysec.com\nssl [True]:\nssl_port [443]:\nssl_cert []:\nTrying to save with empty value\nworkspace [workspace]:\nSection: tokens\nregistration [ACorrectTokenHas25CharLen]: ImalA8Cg1L6Z5Qbx2u9CFAsob\nSection: agent\nagent_name [agent]: nmap\nDo you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]: E\nThe actual configured executors are: []\nDo you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nName: nmap\nIs a custom executor? (Y, N) [N]: Y\nCommand to execute [exit 1]: python3 /home/faraday/faraday_agent_dispatcher/static/executors/official/nmap.py\nMax data sent to server [65536]:\nThe actual nmap executor's environment variables are: []\nDo you want to [A]dd, [M]odify or [D]elete an environment variable? Do you want to [Q]uit? (A, M, D, Q) [Q]:\nThe actual nmap executor's arguments are: []\nDo you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nArgument name: port_list\nIs mandatory? (Y, N): Y\nThe actual nmap executor's arguments are: ['port_list']\nDo you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nArgument name: target\nIs mandatory? (Y, N): Y\nThe actual nmap executor's arguments are: ['port_list', 'target']\nDo you want to [A]dd, [M]odify or [D]elete an argument? Do you want to [Q]uit? (A, M, D, Q) [Q]: Q\nThe actual configured executors are: ['nmap']\nDo you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]: A\nName: nmapOfficial\nIs a custom executor? (Y, N) [N]:\nThe executors are:\n1: wpscan.py\n2: sublist3r.sh\n3: nmap.py\n4: nikto2.py\n5: nessus.py\n+: Next page\nQ: Don't choose\nChoose one: 3\nMax data sent to server [65536]:\nThe actual configured executors are: ['nmap', 'nmapOfficial']\nDo you want to [A]dd, [M]odify or [D]elete an executor? Do you want to [Q]uit? (A, M, D, Q) [Q]:\nDo you want to edit the [A]gent or the [E]xecutors? Do you want to [Q]uit? (A, E, Q) [Q]:\n

    All the information you added with the configuration wizard should appear on a new dispatcher.ini file at your /.faraday/config/ directory:

    $ cat  $HOME/.faraday/config/dispatcher.ini\n[server]\nhost = server.faradaysec.com\nssl = True\napi_port = 443\nwebsocket_port = 443\nssl_cert =\nworkspace = agent_workspaces\n[tokens]\nregistration = ImalA8Cg1L6Z5Qbx2u9CFAsob\n[agent]\nagent_name = nmap\nexecutors = nmap,nmapOfficial\n[nmap]\ncmd = python3 /Users/famato/dev/faraday_agent_dispatcher/contrib/nmap.py\nmax_size = 65536\n[nmap_params]\nport_list = True\ntarget = True\n[nmap_varenvs]\n[nmapOfficial]\nmax_size = 65536\nrepo_executor = nmap.py\n[nmapOfficial_params]\nport_list = True\ntarget = True\n[nmapOfficial_varenvs]\n

    Now you have to run the dispatcher to register the Agent on your Faraday Server:

    $ faraday-dispatcher run\n
    2020-05-11 21:14:01,061 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:91 - register()]  token_registration_url: https://server.faradaysec.com:443/_api/v2/ws/agent_workspaces/agent_registration/\n2020-05-11 21:14:01,977 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:115 - register()]  Registered successfully\n2020-05-11 21:14:02,639 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:150 - connect()]  Connection to Faraday server succeeded\n

    After this, you\u2019ll see your new Agent on the Web UI:

    The last step is that you just run the nmap Agent:

    And the Dispatcher log will give you details about this action:

    2020-05-11 21:16:33,691 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:260 - run_once()]  Running nmap executor\n{\"hosts\": [{\"ip\": \"127.0.0.1\", \"os\": \"unknown\", \"hostnames\": [\"localhost\"], \"description\": \"\", \"mac\": \"00:00:00:00:00:00\", \"credentials\": [], \"services\": [{\"name\": \"http\", \"protocol\": \"tcp\", \"port\": 80, \"status\": \"open\", \"version\": \"\", \"description\": \"http\", \"credentials\": [], \"vulnerabilities\": []}, {\"name\": \"https\", \"protocol\": \"tcp\", \"port\": 443, \"status\": \"open\", \"version\": \"\", \"description\": \"https\", \"credentials\": [], \"vulnerabilities\": []}], \"vulnerabilities\": []}], \"command\": {\"tool\": \"Nmap\", \"command\": \"Nmap\", \"params\": \"\", \"user\": \"\", \"hostname\": \"\", \"start_date\": \"2020-05-11T21:16:33.867017\", \"duration\": 1029, \"import_source\": \"report\"}}\nstderr sent empty data,\n2020-05-11 21:16:34,596 - faraday_agent_dispatcher - INFO {MainThread} [executor_helper.py:97 - processing()]  Data sent to bulk create\nstdout sent empty data,\n2020-05-11 21:16:34,596 - faraday_agent_dispatcher - INFO {MainThread} [dispatcher.py:281 - run_once()]  Executor nmap\nfinished successfully\n

    Right after the Agent executes these actions, return to your Workspace and you can review all the information that was found. Now you are ready to deploy your own Faraday Agents through your network! The Dispatcher README file has more detailed documentation to run and build your Agents. Also, we recommend you to check our examples and official executors to get an idea of what a custom integration looks like.

    "},{"location":"agents/#whats-next","title":"What's Next","text":"

    We will continue to improve Agents\u2019 features, usability, and adding new executors into the Dispatcher repository. In the next few releases we would also like to give some Agents read access to their Workspace, so they can benefit from the existing data in order to find more valuable information.

    We hope you enjoy this feature and find it useful!

    "},{"location":"api-swagger/","title":"Openapi","text":""},{"location":"beef/","title":"Beef","text":"

    This plugin can be set from Faraday's Plugin Configuration, where the information of the BeEF's server and RESTful AuthKey:

    [AuthKey] [Host]

    By default this plugin is disabled, change the enable boolean in order to use it

    The information required for connecting to BeEF is generated when you start it:

    "},{"location":"faraday-cli/","title":"Faraday CLI","text":"

    Use Faraday directly from your favorite terminal. faraday-cli is the official client that make automating your security workflows, easier.

    Check our documentation to get more information.

    "},{"location":"faraday-dispatcher-v4/","title":"Faraday Dispatcher","text":"

    Faraday Agents Dispatcher helps user develop integrations with Faraday written in any language.

    Integrating systems is an elusive but mandatory job in any software product's life. Developers have to deal with languages they don't know, undocumented APIs or new paradigms. This leads to the fact that many product teams decide not to open the possibility to integrate to them.

    The following documentation will allow the users to integrate using agents with other tools.

    "},{"location":"faraday-dispatcher-v4/#documentation","title":"Documentation","text":"

    For more info on how to use it, check our [documentation][doc]

    • Doc

    • API

    "},{"location":"import/","title":"Importing","text":"

    There are many ways to add vulnerabilities into Faraday, create them manually, import scan reports, with supported tools, Faraday Agents or using Faraday API.

    "},{"location":"import/#import-your-tool-reports","title":"Import your tool Reports","text":"

    You can upload a scan report of your favorite tool to Faraday and have a nice look at your findings through the Vulns View. You can see a list of the tools that Faraday supports by clicking on this link

    In order to upload a report to Faraday, follow these instructions:

    • Click on the button + Add Vulnerability.
    • Click on the button Import from file and a prompt will be displayed.
    • Click on Browse in order to select the report that you are going to upload, or just drag and drop the file into the box.
    • Once you have selected the report, click on Upload and your file will be uploaded.
    • Refresh the view with the top bar refresh icon.
    "},{"location":"import/#supported-file-formats","title":"Supported File formats","text":"

    There is a variety of tools and they all have multiple export formats, to make it more simple we list the tool in order + the filetype

    Name ID Command Report Acunetix XML Output Plugin Acunetix No Yes Acunetix360 Output Plugin Acunetix360 No Yes Acunetix JSON Output Plugin Acunetix_Json No Yes Amap Output Plugin Amap Yes No Appscan XML Plugin Appscan No Yes Appscan CSV Output Plugin Appscan_CSV No Yes AppSpider XML Output Plugin AppSpider No Yes Arachni XML Output Plugin Arachni Yes Yes arp-scan network scanner arp-scan Yes No Bandit XML Output Plugin Bandit No Yes BeEF Online Service Plugin Beef Yes No brutexss brutexss Yes No Burp XML Output Plugin Burp No Yes Checkmarx XML Output Plugin Checkmarx No Yes CIS XML Output Plugin CIS No Yes Cobalt CSV Output Plugin Cobalt No Yes Crowdstrike JSON Output Plugin Crowdstrike_Json No Yes DiG dig Yes No Dirb dirb Yes No dirsearch dirsearch Yes No Dnsenum XML Output Plugin Dnsenum Yes No Dnsmap Output Plugin Dnsmap Yes No Dnsrecon XML Output Plugin Dnsrecon Yes No Dnswalk XML Output Plugin Dnswalk Yes No Faraday CSV Plugin faraday_csv No Yes Fierce Output Plugin Fierce Yes No Fortify XML Output Plugin Fortify No Yes Ftp ftp Yes No Goohost XML Output Plugin Goohost Yes No Grype JSON Plugin grype Yes Yes hping3 Hping3 Yes No Hydra XML Output Plugin Hydra Yes No Core Impact XML Output Plugin CoreImpact No Yes Invicti XML Output Plugin Invicti No Yes Ip360 CSV Output Plugin Ip360 No No Junit XML Output Plugin Junit No Yes Lynis DAT Output Plugin Lynis Yes Yes Maltego MTGX & MTGL Output Plugin Maltego No Yes Microsoft Baseline Security Analyzer MBSA No Yes Medusa Output Plugin Medusa Yes No Metasploit XML Output Plugin Metasploit No Yes Naabu naabu Yes Yes ncrack XML Plugin ncrack No Yes ndiff Ndiff Yes No Nessus XML Output Plugin Nessus No Yes Nessus Sc Output Plugin Nessus_sc No Yes netdiscover Netdiscover Yes No Netsparker XML Output Plugin Netsparker No Yes NetsparkerCloud XML Output Plugin NetsparkerCloud No Yes Nexpose XML 2.0 Report Plugin NexposeFull No Yes nextnet nextnet Yes No Nikto XML Output Plugin Nikto Yes Yes Nipper XML Output Plugin Nipper No Yes Nmap XML Output Plugin Nmap Yes Yes Nuclei nuclei Yes Yes Nuclei nuclei_legacy Yes Yes OpenScap XML Output Plugin OpenScap No Yes Openvas XML Output Plugin Openvas No Yes pasteAnalyzer JSON Output Plugin pasteAnalyzer Yes No PeepingTom peepingtom Yes No Pentera Json Output Plugin Pentera_Json No Yes Ping ping Yes No Ping Castle XML Output Plugin PingCastle No Yes Popeye JSON Output Plugin Popeye_Json No Yes propecia port scanner propecia Yes No Prowler prowler No Yes Qualysguard XML Output Plugin Qualysguard No Yes QualysWebapp XML Output Plugin QualysWebapp No Yes rdpscan rdpscan Yes No Reconng XML Output Plugin Reconng No Yes Retina XML Output Plugin Retina No Yes Reverseraider XML Output Plugin Reverseraider Yes No Sarif Plugin Sarif No Yes Semgrep Json Semgrep_JSON No Yes Shodan shodan Yes Yes Skipfish Output Plugin Skipfish Yes No SonarQube API Plugin sonarqubeAPI No Yes Sourceclear sourceclear No Yes sshdefaultscan sshdefaultscan Yes No SSL Labs ssllabs No Yes Sslyze Plugin Sslyze_XML No Yes Sslyze Json Sslyze_JSON Yes Yes Syhunt XML Plugin Syhunt No Yes Telnet Telnet Yes No Terraform Plugin JSON Output Plugin TerraformPluginJson No Yes Theharvester XML Output Plugin Theharvester Yes No Traceroute Traceroute Yes No Trivy JSON Output Plugin Trivy_Json No Yes W3af XML Output Plugin W3af Yes Yes Wapiti XML Output Plugin Wapiti Yes Yes Wcscan XML Output Plugin Wcscan Yes No Webfuzzer Output Plugin Webfuzzer Yes No Webinspect Webinspect No Yes Wfuzz Plugin Wfuzz Yes No WhatWebPlugin whatweb No Yes whitesource whitesource No Yes Whois whois Yes No Windows Defender Jsonl WindowsDefender_JSONL No Yes WPscan wpscan Yes Yes Onapsis X1 XML Output Plugin X1 Yes Yes xsssniper xsssniper Yes No Zap XML Output Plugin Zap No Yes Zap Json Output Plugin Zap_Json No Yes
    • Acunetix (REPORT) (XML, JSON)
    • Appscan (REPORT) (XML, CSV)
    • AppSpider (REPORT) (XML)
    • Arachni (REPORT) (XML)
    • AWS Prowler (REPORT) (JSON)
    • Bandit (REPORT, XML)
    • Brutexss (REPORT)
    • Burp, BurpPro (REPORT, API) (XML)
    • Core Impact, Core Impact (REPORT) (XML)
    • Dirsearch (REPORT) (JSON)
    • Fierce (REPORT, CONSOLE)
    • Fortify (REPORT, XML)
    • Goohost (REPORT) (XML)
    • Hydra (REPORT) (XML)
    • Ip360 (REPORT) (CSV)
    • Junit (REPORT) (XML)
    • Lynis (REPORT) (DAT)
    • Maltego (REPORT) (MTGX & MTGL)
    • Microsoft Baseline Security Analyzer (REPORT) (LOG)
    • Metasploit, (REPORT) (XML)
    • Naabu (REPORT) (JSON)
    • Ncrack (REPORT)
    • Nessus, (REPORT) (XML .nessus)
    • Netsparker (REPORT) (XML)
    • Netsparker Cloud (REPORT)
    • Nexpose, Nexpose Enterprise, (REPORT) (simple XML, XML Export plugin (2.0))
    • Nikto (REPORT) (XML)
    • Nipper (REPORT)
    • Nmap (REPORT) (XML)
    • Nuclei (REPORT)
    • OpenScap (REPORT)
    • Openvas (REPORT) (XML)
    • Qualysguard (REPORT) (XML)
    • QualysWebApp (REPORT)
    • Recon-NG (REPORT)
    • Retina (REPORT) (XML)
    • Shodan (API)
    • SonarQube (REPORT)
    • SourceClear (REPORT)
    • SSL Labs (REPORT)
    • SSLyze (REPORT) (XML)
    • Sublist3r (REPORT)
    • W3af (REPORT) (XML)
    • WebInspect (REPORT)
    • WhatWebPlugin (REPORT)
    • WhiteSource (REPORT)
    • Xsssniper (REPORT)
    • X1, Onapsis (REPORT) (XML)
    • Zap (REPORT) (XML)
    "},{"location":"integration-gitlab/","title":"GitLab","text":"

    This is a feature that allows you to send vulnerabilities from Faraday to GitLab.

    "},{"location":"integration-gitlab/#initial-configuration","title":"Initial Configuration","text":""},{"location":"integration-gitlab/#gitlabs-configuration","title":"GitLab's Configuration","text":"

    Login into GitLab and navigate to Settings > Access Tokens

    Create a Personal Access Token with the API Scope active:

    Copy and keep your generated personal access token

    Now, select a Project from GitLab to connect with Faraday

    "},{"location":"integration-gitlab/#faradays-configuration","title":"Faraday's Configuration","text":"

    Login into Faraday's Web UI and go to Setting clicking on your username at the top-rigth corner:

    Inside Settings, navigate to Ticketing Tools and Select GitLab from the dropdown menu:

    Now, complete those fields with your GitLab Project information.

    Access Token (example): 4WRurWXnftGRbqCbJVUG

    Project (example): TEST-PROJECT

    template : choose a template from the dropdown menu (templates should be inside Faraday's Server at /home/faraday/.faraday/integrations_templates/)

    {# This is a Template for Faraday Gitlab Integration #}\n{# Pre-Flight Adjustments #}\n{% set issuetracker_config = 'gitlab' %}\n{% set http_size_config = 4096 %}\n{% if 'med' in vuln.severity %}\n{% set corrected_severity = 'Medium' %}\n{% else %}\n{% set corrected_severity = vuln.severity %}\n{% endif %}\n{# Issue template structure should go under this comment #}\n{% if 'VulnerabilityWeb' in vuln.type %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})\n{% else %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}}\n{% endif %}\n## Description\n{{ vuln.desc }}\n#### This issue has been rated as: `{{ corrected_severity | capitalize }}`\nAffected Asset: {{vuln.target}}\n{%  if vuln.website %}\nAffected URL: {{ vuln.website }}{{ vuln.path }}\n{% endif %}\n{% if vuln.hostnames %}\n#### Hostnames\n{% for hostname in vuln.hostnames %}\n- {{hostname}}\n{% endfor %}\n{% endif %}\n## Recommendations\n{{ vuln.resolution }}\n{%for ref in vuln.refs%}\n- {{ref}}\n{%endfor%}\n{%if vuln.easeofresolution%}\n#### Estimated ease of resolution\n{{ vuln.easeofresolution | capitalize }}\n{%endif%}\n### Technical Details\n{%if vuln.data%}\n#### Proof of Concept\n{{vuln.data}}\n{%endif%}\n{%if vuln.request%}\n#### Request\n\n{{vuln.request|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n{% if vuln.response %}\n#### Response\n\n{{ vuln.response|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]\n{# A vulnerability might be associated with more tha one issuetracker id #}\n{% for key, value in vuln.issuetracker_json.items() %}\n{% if issuetracker_config in key%}\nThis issue has already been reported in this platform:\n- {{ key | capitalize}}\n{% for line in value %}\n- Issue: {{line.url}}\n{% endfor %}\n{% endif %}\nsource: created by {{vuln.owner or \"faraday\"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}\n{% endfor %}\n{# end of file #}\n

    If everything is Ok, click on the green Save button and you should see a pop-up like this:

    "},{"location":"integration-gitlab/#send-vulnerability-to-gitlab","title":"Send vulnerability to GitLab","text":"

    Access your Faraday's Web UI and go to Manage > Vulns.

    Click on the dropdown menu Add columns and add the issuetracker column.

    Now, select the vulnerability you want to export and click on Tools > Gitlab

    Click Ok.

    You should see the word Gitlab appearing on the issuetracker column at your vuln, you can click on it to see the issue that has been created on gitlab!

    "},{"location":"integration-jira/","title":"Jira","text":"

    This is a feature that allows you to send vulnerabilities from Faraday to JIRA. Through this process you will see how to

    "},{"location":"integration-jira/#jiras-configuration","title":"JIRA's Configuration","text":""},{"location":"integration-jira/#1-follow-the-instructions-based-on-you-jira-instance-on-prem-or-cloud","title":"1. Follow the instructions based on you JIRA Instance (On-prem or Cloud)","text":"JIRA On Prem Software

    Copy your instance URL and Project Key from your JIRA instance information:

    URL (example): https://localhost:8080/

    Project Key (example): FARADAYPRO

    JIRA Cloud

    Copy your JIRA Instance URL and Project Key information:

    URL (example): https://example.atlassian.net/

    Project Key (example): FARADAYPRO

    Now, we need to activate OAuth Authentication:

    Inside your JIRA Cloud click on the gear icon at the top-right corner (left side of your profile icon) and click on Products, then, on the left-side bar, click on Application links

    On the input bar at JIRA, enter your Faraday's URL (example: http://localhost:5985)

    If this message appears and the URL is correct, just click Continue

    Fill the application fields, in this case, Faraday as the Application Name, you must select the option Generic Application as the Application Type and Mark the option Create incoming link. Then, click Continue.

    Now, you will need to create a:

    • Consumer Key: you should copy and save this for after configuration at Faraday.

    • Consumer Name: In this case, we use Faraday.

    • Public Key: To create this Public Key, you will need to execute the following command on your Faraday Server: faraday-manage generate-rsa-keys --integration jira you will receive something like this:

      -----BEGIN PUBLIC KEY-----\n9YxXl4D/aL/iE94MsUc9t3FFoNCP97Sfel7o+1q5YOF79qlKGbP3mXgbel/LUaSj\nVd91dnpg1OS1PH0p6YMDsCQfXSVBpC2OUY2hDkEwPUT/OKeAq+XE5sqEqoUeDdrS\nOOWVuEYlWZl6ghS2TABFN5VXPgWg30Ne4L0nlDqJh2BD7RACa+Wpzbr2b/HmIxSf\nWOj6mu7eK7Vx38CyrnOci8u59Mv/IXsEppU6nGgMZ7/Hw1ojaeSn0W6wF0Wsk3EG\nRY/wYngdCYQEQx0rDnannBnP6EuYaqwBtNjcPpp9zvsZt+d1qmOWbii4rbqfY4BR\nn42R05zamkSNqbwdoQ1JDyv90D6lrG+JLq/BjHaIJlAhnDIWfX6DtqgUOD3VUQfC\nGQvvguRA\n-----END PUBLIC KEY-----\n
      Just copy and paste it inside your Publick Key field at JIRA.

    Then, click Continue to generate the application.

    If everything is Ok, you should see this screen:

    Faraday authenticates to Jira using OAuth 1.0 A

    "},{"location":"integration-jira/#3-faradays-configuration","title":"3. Faraday's Configuration","text":"

    Login into Faraday's Web UI and go to Setting clicking on your username in the top right corner:

    Inside Settings, navigate to Ticketing Tools and Select JIRA from the dropdown menu:

    "},{"location":"integration-jira/#jira-on-premise","title":"JIRA On-Premise","text":"
    Paste your JIRA instance information inside configuration and paste it on the correct fields.\n\nSave the instance url, project key, and generate the key to use it in the Oauth configuration.\n\nIf everything is Ok, click on the blue Save button.\n
    "},{"location":"integration-jira/#jira-cloud","title":"JIRA Cloud","text":"
    Inside the ticketing tool at Faraday, paste your instance URL and Project Key, then, add your **Consumer Key** into the OAuth Authentication field, after this, click the round button to authenticate!\n\n![](./images/integrations/jira/authorize-faraday.png)\n\nYou should see this, **click on Redirect to JIRA**, once on JIRA website, **click on Allow** and wait until receive an Access Approved message, once received, close the tab.\n\n![](./images/integrations/jira/jira-website.png)\n\n![](./images/integrations/jira/approved-message.png)\n\nOnce in Faraday, click on Authorized.\n\n![](./images/integrations/jira/oauth-succeed.png\n
    "},{"location":"integration-jira/#configure-jira-users-in-faraday","title":"Configure jira users in faraday","text":"

    Inside Preferences, navigate to Ticketing Tools and Select JIRA:

    Search Jira users from the Assign Users box and hit enter:

    If the user is added correctly, then the user will be allowed to be reporter in the \"reporters\" field.

    User added correctly!

    "},{"location":"integration-jira/#4-send-vulnerability-to-jira","title":"4. Send vulnerability to JIRA","text":"

    Navigate to the Manage > Vulns view inside Faraday's Web UI

    To send vulnerabilities to JIRA, select the desired vulnerabilities, click on the Tools button at the top-right corner and then click on JIRA.

    Click on the dropdown menu Add columns and add the issuetracker column.

    Now, select the vulnerability you want to export and click on Tools > JIRA

    Keep in mind that only confirmed vulnerabilities can be sent.

    Once the JIRA dialog opens, you have two options:

    You can use the default data saved in the Ticketing Tools section of Settings (see Save JIRA's Configuration for more information):

    You can overwrite JIRA default data by clicking on the checkbox button and then manually input your JIRA credentials. Then click OK:

    If you overwrite only one field, Faraday will fill the others fields with the default data. E.g: if you overwrite Project Key, Faraday will fill URL field with the information you have saved in Settings.

    With Basic auth.

    Click Done.

    You should see the word JIRA appearing on the issuetracker column at your vuln, you can click on it to see the issue that has been created on JIRA!

    In Jira

    Template The template is preloaded in description but you can use the fields described in our jinja2 context doc Link The template's name where you'll define the issue's description. You can call any attribute of the vulnerability object using Jinja2 syntax. E.g., if you want your issue in JIRA to have as description the target, the hostnames, and the severity of the vulnerability, the template would be as follows:

    {# This is a Template for Faraday Jira Integration #}\n{# Pre-Flight Adjustments #}\n{% set issuetracker_config = 'jira' %}\n{% set http_size_config = 4096 %}\n{% if 'med' in vuln.severity %}\n{% set corrected_severity = 'Medium' %}\n{% else %}\n{% set corrected_severity = vuln.severity %}\n{% endif %}\n{# Issue template structure should go under this comment #}\n{% if 'VulnerabilityWeb' in vuln.type %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})\n{% else %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}}\n{% endif %}\n## Description\n{{ vuln.desc }}\n#### This issue has been rated as: `{{ corrected_severity | capitalize }}`\nAffected Asset: {{vuln.target}}\n{%  if vuln.website %}\nAffected URL: {{ vuln.website }}{{ vuln.path }}\n{% endif %}\n{% if vuln.hostnames %}\n#### Hostnames\n{% for hostname in vuln.hostnames %}\n- {{hostname}}\n{% endfor %}\n{% endif %}\n## Recommendations\n{{ vuln.resolution }}\n{%for ref in vuln.refs%}\n- {{ref}}\n{%endfor%}\n{%if vuln.easeofresolution%}\n#### Estimated ease of resolution\n{{ vuln.easeofresolution | capitalize }}\n{%endif%}\n### Technical Details\n{%if vuln.data%}\n#### Proof of Concept\n{{vuln.data}}\n{%endif%}\n{%if vuln.request%}\n#### Request\n\n{{vuln.request|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n{% if vuln.response %}\n#### Response\n\n{{ vuln.response|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]\n{# A vulnerability might be associated with more tha one issuetracker id #}\n{% for key, value in vuln.issuetracker_json.items() %}\n{% if issuetracker_config in key%}\nThis issue has already been reported in this platform:\n- {{ key | capitalize}}\n{% for line in value %}\n- Issue: {{line.url}}\n{% endfor %}\n{% endif %}\nsource: created by {{vuln.owner or \"faraday\"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}\n{% endfor %}\n{# end of file #}\n

    You can also link an issue to an Epic. To do so, look after the custom field Epic Link of your instance and add it to your issue\u2019s configuration (just as the example above). Once you add it, you need to type in the input field the issue keys of the epic.

    "},{"location":"integration-servicenow/","title":"ServiceNow","text":"

    This feature allows you to send vulnerabilities from Faraday to ServiceNow as an incident (using ServiceNow's Incident table).

    "},{"location":"integration-servicenow/#send-vulnerabilities-to-servicenow","title":"Send vulnerabilities to ServiceNow","text":"

    To send vulnerabilities to ServiceNow, go into our Status Report, select the desired vulnerabilities, click on the Tools button and then click on the ServiceNow option.

    Info

    Keep in mind that only confirmed vulnerabilities can be sent.

    "},{"location":"integration-servicenow/#sending-to-servicenow","title":"Sending To ServiceNow","text":"

    Once the ServiceNow dialog opens, you have two options:

    1: You can use the default data saved in the Ticketing Tools section of Settings (see Save ServiceNow's Configuration for more information):

    2: You can overwrite ServiceNow default data by clicking on the checkbox button and then manually input your ServiceNow credentials. Then click OK:

    "},{"location":"integration-servicenow/#issuetracker","title":"Issuetracker","text":"

    Once the vulnerability has been sent to ServiceNow, add the column issuetracker, so you can see a link that will lead you to the incident in ServiceNow.

    "},{"location":"integration-servicenow/#issuetrackers-json","title":"Issuetracker's JSON","text":"

    We added the issuetracker_json field which, if you\u2019re using our ServiceNow integration, will give you details about the issue you created from Faraday to your ticketing instance. You can also use this field on your Executive Reports, and can render either the URL of your issue or just the ID for it.

    "},{"location":"integration-servicenow/#sending-vulnerabilitys-evidence","title":"Sending vulnerability\u2019s evidence","text":"

    You can send the vulnerability\u2019s evidence to ServiceNow. The evidence will be sent as an incident\u2019s attachments. Keep in mind the following considerations:

    • You should have the right permissions to add attachments to an incident.
    • The attachment size allowed by your ServiceNow\\'s instance must be greater than the size of the attachment that you want to send.
    "},{"location":"integration-servicenow/#save-servicenows-configuration","title":"Save ServiceNow's Configuration","text":"

    To save ServiceNow's configuration, go to Settings:

    Then go to the Ticketing Tools section:

    "},{"location":"integration-servicenow/#url","title":"URL","text":"

    Use this field to save the URL of the ServiceNow's instance where you want the vulnerability to be sent.

    "},{"location":"integration-servicenow/#incidents-configuration","title":"Incident's configuration","text":"

    In the Incident's Configuration section, you can set the way you want the vulnerabilities to be parsed as ServiceNow\u2019s incident. You can set the incident\u2019s category and subcategory in which the vulnerabilities will be sent or you can even use Jinja2 syntax to create your own templates to parse the vulnerabilities\u2019 information and use these templates as the incident\u2019s description in ServiceNow.

    "},{"location":"integration-servicenow/#incidents-category-and-subcategory","title":"Incident\u2019s category and subcategory","text":"

    In these dropdown menus, you can set the category and the subcategory of the incident. Once you send the vulnerability to ServiceNow, you\u2019ll see the same category and subcategory that you defined in Faraday. To check which category and subcategory you can choose, take a look at the following ServiceNow\u2019s link.

    "},{"location":"integration-servicenow/#template","title":"Template","text":"

    The template's name where you'll define the incident\u2019s description. You can call any attribute of the vulnerability object using Jinja2 syntax. E.g., if you want your incident in ServiceNow to have as description the target, the hostnames, and the severity of the vulnerability, the template would be as follows:

    "},{"location":"integration-servicenow/#simple-template","title":"Simple template","text":"
    {# Service now integration #}\nName: {{ vuln.name }}\nTarget: {{target}}\nHostnames:\n{%for hostname in hostnames%}\n    - {{hostname}}\n{%endfor%}\nSeverity: {{severity}}\n
    "},{"location":"integration-servicenow/#complex-template","title":"Complex template","text":"
    {# This is a Template for Faraday service now Integration #}\n{# Pre-Flight Adjustments #}\n{% set issuetracker_config = 'service now' %}\n{% set http_size_config = 4096 %}\n{% if 'med' in vuln.severity %}\n{% set corrected_severity = 'Medium' %}\n{% else %}\n{% set corrected_severity = vuln.severity %}\n{% endif %}\n{# Issue template structure should go under this comment #}\n{% if 'VulnerabilityWeb' in vuln.type %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})\n{% else %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}}\n{% endif %}\n## Description\n{{ vuln.desc }}\n#### This issue has been rated as: `{{ corrected_severity | capitalize }}`\nAffected Asset: {{vuln.target}}\n{%  if vuln.website %}\nAffected URL: {{ vuln.website }}{{ vuln.path }}\n{% endif %}\n{% if vuln.hostnames %}\n#### Hostnames\n{% for hostname in vuln.hostnames %}\n- {{hostname}}\n{% endfor %}\n{% endif %}\n## Recommendations\n{{ vuln.resolution }}\n{%for ref in vuln.refs%}\n- {{ref}}\n{%endfor%}\n{%if vuln.easeofresolution%}\n#### Estimated ease of resolution\n{{ vuln.easeofresolution | capitalize }}\n{%endif%}\n### Technical Details\n{%if vuln.data%}\n#### Proof of Concept\n{{vuln.data}}\n{%endif%}\n{%if vuln.request%}\n#### Request\n\n{{vuln.request|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n{% if vuln.response %}\n#### Response\n\n{{ vuln.response|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]\n{# A vulnerability might be associated with more tha one issuetracker id #}\n{% for key, value in vuln.issuetracker_json.items() %}\n{% if issuetracker_config in key%}\nThis issue has already been reported in this platform:\n- {{ key | capitalize}}\n{% for line in value %}\n- Issue: {{line.url}}\n{% endfor %}\n{% endif %}\nsource: created by {{vuln.owner or \"faraday\"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}\n{% endfor %}\n{# end of file #}\n

    This template must be located inside the folder

    /home/faraday/.faraday/integrations_templates/*\n
    "},{"location":"integration-solarwinds/","title":"WHD - SolarWinds","text":"

    This feature allows you to send vulnerabilities from Faraday to Web Help Desk from Solar Winds as an incident (using Web Help Desk from Solar Winds's Incident table).

    "},{"location":"integration-solarwinds/#send-vulnerabilities-to-web-help-desk-from-solar-winds","title":"Send vulnerabilities to Web Help Desk from Solar Winds","text":"

    To send vulnerabilities to Web Help Desk from Solar Winds, go into our Vulnerability View, select the desired vulnerabilities, click on the Tools button and then click on the Web Help Desk from Solar Winds option.

    Info

    Keep in mind that only confirmed vulnerabilities can be sent.

    "},{"location":"integration-solarwinds/#sending-to-web-help-desk-from-solar-winds","title":"Sending To Web Help Desk from Solar Winds","text":"

    Once the Web Help Desk from Solar Winds dialog opens, you have two options:

    1: You can use the default data saved in the Ticketing Tools section of Settings (see Save Web Help Desk from Solar Winds's Configuration for more information):

    2: You can overwrite Web Help Desk from Solar Winds default data by clicking on the checkbox button and then manually input your Web Help Desk from Solar Winds credentials. Then click OK:

    "},{"location":"integration-solarwinds/#issuetracker","title":"Issuetracker","text":"

    Once the vulnerability has been sent to Web Help Desk from Solar Winds, add the column issuetracker, so you can see a link that will lead you to the incident in Web Help Desk.

    "},{"location":"integration-solarwinds/#issuetrackers-json","title":"Issuetracker's JSON","text":"

    We added the issuetracker_json field which, if you\u2019re using our Web Help Desk from Solar Winds integration, will give you details about the issue you created from Faraday to your ticketing instance. You can also use this field on your Executive Reports, and can render either the URL of your issue or just the ID for it.

    "},{"location":"integration-solarwinds/#save-web-help-desk-from-solar-windss-configuration","title":"Save Web Help Desk from Solar Winds's Configuration","text":"

    To save Web Help Desk from Solar Winds's configuration, go to Settings:

    Then go to the Ticketing Tools section:

    "},{"location":"integration-solarwinds/#url","title":"URL","text":"

    Use this field to save the URL of the Web Help Desk from Solar Winds's instance where you want the vulnerability to be sent.

    "},{"location":"integration-solarwinds/#api-key","title":"API Key","text":"

    Use the field to fill the Api key created in Solar Winds instance.

    "},{"location":"integration-solarwinds/#template","title":"Template","text":"

    Select The first Template, there is a default template already loaded in your faraday instance.

    {# This is a Template for Faraday solar winds Integration #}\n{# Pre-Flight Adjustments #}\n{% set issuetracker_config = 'solar winds' %}\n{% set http_size_config = 4096 %}\n{% if 'med' in vuln.severity %}\n{% set corrected_severity = 'Medium' %}\n{% else %}\n{% set corrected_severity = vuln.severity %}\n{% endif %}\n{# Issue template structure should go under this comment #}\n{% if 'VulnerabilityWeb' in vuln.type %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}} - ({{vuln.path}})\n{% else %}\n# [{{ corrected_severity | capitalize}}] {{vuln.name}}\n{% endif %}\n## Description\n{{ vuln.desc }}\n#### This issue has been rated as: `{{ corrected_severity | capitalize }}`\nAffected Asset: {{vuln.target}}\n{%  if vuln.website %}\nAffected URL: {{ vuln.website }}{{ vuln.path }}\n{% endif %}\n{% if vuln.hostnames %}\n#### Hostnames\n{% for hostname in vuln.hostnames %}\n- {{hostname}}\n{% endfor %}\n{% endif %}\n## Recommendations\n{{ vuln.resolution }}\n{%for ref in vuln.refs%}\n- {{ref}}\n{%endfor%}\n{%if vuln.easeofresolution%}\n#### Estimated ease of resolution\n{{ vuln.easeofresolution | capitalize }}\n{%endif%}\n### Technical Details\n{%if vuln.data%}\n#### Proof of Concept\n{{vuln.data}}\n{%endif%}\n{%if vuln.request%}\n#### Request\n\n{{vuln.request|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n{% if vuln.response %}\n#### Response\n\n{{ vuln.response|truncate(http_size_config, False, '...', 0) }}\n\n{%endif%}\n## Issue [{{ vuln.id }}] {{vuln.name}} [{{vuln.status}}]\n{# A vulnerability might be associated with more tha one issuetracker id #}\n{% for key, value in vuln.issuetracker_json.items() %}\n{% if issuetracker_config in key%}\nThis issue has already been reported in this platform:\n- {{ key | capitalize}}\n{% for line in value %}\n- Issue: {{line.url}}\n{% endfor %}\n{% endif %}\nsource: created by {{vuln.owner or \"faraday\"}} using {{vuln.tool}} - {{vuln.external_id}} - {{vuln.date}}\n{% endfor %}\n{# end of file #}\n
    "},{"location":"requirements/","title":"Hardware Requirements for Faraday","text":"

    Faraday is a powerful vulnerability management tool that allows you to easily identify, track, and manage vulnerabilities in your network. To get the most out of Faraday, it's important to have the right hardware in place. In this article, we'll take a look at the hardware requirements for Faraday and how to ensure that your system is set up to run Faraday smoothly and efficiently.

    "},{"location":"requirements/#operating-system","title":"Operating System","text":"

    Faraday requires a 64-bit operating system. This can be Linux, Ubuntu-based, or Red Hat-based. The operating system should also be up-to-date and have the latest security patches installed.

    Requirement Recommended Operating System 64-bit Operating System Type Linux, Ubuntu-based, or Red Hat-based Operating System Version Up-to-date with latest security patches"},{"location":"requirements/#processor-and-memory","title":"Processor and Memory","text":"

    Faraday requires at least a 2GHz quad-core processor and 8GB of RAM. However, for larger networks and more complex environments, it is recommended to have an octa-core processor and 16GB of RAM. This will ensure that Faraday runs smoothly and can handle large amounts of data without any performance issues.

    Requirement Recommended Processor 2GHz quad-core Memory 8GB RAM Processor (for larger networks) Octa-core Memory (for larger networks) 16GB RAM"},{"location":"requirements/#disk-space","title":"Disk Space","text":"

    Faraday also requires a minimum of 10GB of free disk space. This includes space for the Faraday server, the database, and any other files that Faraday may need to store. For larger networks and more complex environments, it is recommended to have at least 20GB of free disk space.

    Requirement Recommended Disk Space 10GB Disk Space (for larger networks) 20GB"},{"location":"requirements/#network-connectivity","title":"Network Connectivity","text":"

    Faraday requires a stable internet connection. This is necessary for Faraday to communicate with the Faraday server and to access any necessary updates or patches. Faraday also requires a stable and fast connection to the network that it is scanning. This will ensure that Faraday can quickly and efficiently scan the network and identify any vulnerabilities.

    Requirement Description Internet Connection Stable Network Connectivity Stable and fast connection to the network being scanned"},{"location":"requirements/#database","title":"Database","text":"

    For the database, it is required PostgreSQL 9.6 or higher.

    Requirement Description Database PostgreSQL 9.6 or higher"},{"location":"requirements/#python","title":"Python","text":"

    Faraday requires Python 3.7 or higher to be installed. Python is a programming language that Faraday uses to communicate with the Faraday server and to run various scripts and plugins. It is important to ensure that the correct version of Python is installed and that it is up-to-date.

    Requirement Description Python 3.7 or higher Minimum Requirements Processor quadcore 2Ghz Intel/AMD CPU Operating System We recommend using Ubuntu Server 18.04 (LTS) RAM 4 GB or more (8 GB recommended) Hard Disk Space 40 GB (depends on usage, PostgreSQL could consume up to 80 GB) Internet Internet connection is necessary for installation and license (Commercial)"}]} \ No newline at end of file diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 00000000000..4fe6163f6fe --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,348 @@ + + + + https://faradaysec.com/ + 2024-03-25 + daily + + + https://faradaysec.com/2-Factor-Authentication/ + 2024-03-25 + daily + + + https://faradaysec.com/API-Server/ + 2024-03-25 + daily + + + https://faradaysec.com/API-Token/ + 2024-03-25 + daily + + + https://faradaysec.com/Activity-Dashboard/ + 2024-03-25 + daily + + + https://faradaysec.com/Architecture/ + 2024-03-25 + daily + + + https://faradaysec.com/Assets-and-Services-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/Backup-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/Basic-plugin-development/ + 2024-03-25 + daily + + + https://faradaysec.com/Burp-proxy-extender/ + 2024-03-25 + daily + + + https://faradaysec.com/Comments/ + 2024-03-25 + daily + + + https://faradaysec.com/Contact-us/ + 2024-03-25 + daily + + + https://faradaysec.com/Custom-Fields-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/Dashboard-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/Development-setup/ + 2024-03-25 + daily + + + https://faradaysec.com/FAQ/ + 2024-03-25 + daily + + + https://faradaysec.com/Faraday-Manage-Settings-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/Faraday-Manage/ + 2024-03-25 + daily + + + https://faradaysec.com/Faraday-Zap-extension/ + 2024-03-25 + daily + + + https://faradaysec.com/Filters/ + 2024-03-25 + daily + + + https://faradaysec.com/First-Steps/ + 2024-03-25 + daily + + + https://faradaysec.com/Getting-started/ + 2024-03-25 + daily + + + https://faradaysec.com/How-to-build-your-template/ + 2024-03-25 + daily + + + https://faradaysec.com/Install-guide-Advanced/ + 2024-03-25 + daily + + + https://faradaysec.com/Install-guide-Docker/ + 2024-03-25 + daily + + + https://faradaysec.com/Install-guide-Linux/ + 2024-03-25 + daily + + + https://faradaysec.com/Install-guide-Redhat-8/ + 2024-03-25 + daily + + + https://faradaysec.com/Install-guide-Troubleshooting/ + 2024-03-25 + daily + + + https://faradaysec.com/Install-guide-community/ + 2024-03-25 + daily + + + https://faradaysec.com/Jinja2-context/ + 2024-03-25 + daily + + + https://faradaysec.com/LDAP-OKTA/ + 2024-03-25 + daily + + + https://faradaysec.com/LDAP/ + 2024-03-25 + daily + + + https://faradaysec.com/NGINX-Setup/ + 2024-03-25 + daily + + + https://faradaysec.com/Notifications-Slack/ + 2024-03-25 + daily + + + https://faradaysec.com/Notifications/ + 2024-03-25 + daily + + + https://faradaysec.com/Pipelines/ + 2024-03-25 + daily + + + https://faradaysec.com/Planner/ + 2024-03-25 + daily + + + https://faradaysec.com/Plugin-List-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/RELEASE/ + 2024-03-25 + daily + + + https://faradaysec.com/Remote-PostgreSQL/ + 2024-03-25 + daily + + + https://faradaysec.com/Report-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/SAML-Auth0/ + 2024-03-25 + daily + + + https://faradaysec.com/SAML-Azure/ + 2024-03-25 + daily + + + https://faradaysec.com/SAML-Google/ + 2024-03-25 + daily + + + https://faradaysec.com/SAML-Okta/ + 2024-03-25 + daily + + + https://faradaysec.com/SAML/ + 2024-03-25 + daily + + + https://faradaysec.com/Scheduling/ + 2024-03-25 + daily + + + https://faradaysec.com/Settings-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/Tasks/ + 2024-03-25 + daily + + + https://faradaysec.com/Troubleshooting/ + 2024-03-25 + daily + + + https://faradaysec.com/Update/ + 2024-03-25 + daily + + + https://faradaysec.com/Upload-Report/ + 2024-03-25 + daily + + + https://faradaysec.com/Users/ + 2024-03-25 + daily + + + https://faradaysec.com/Using-custom-fields-from-the-API/ + 2024-03-25 + daily + + + https://faradaysec.com/Vulnerability-Templates-KB/ + 2024-03-25 + daily + + + https://faradaysec.com/Vulns/ + 2024-03-25 + daily + + + https://faradaysec.com/Workspaces/ + 2024-03-25 + daily + + + https://faradaysec.com/agents-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/agents/ + 2024-03-25 + daily + + + https://faradaysec.com/api-swagger/ + 2024-03-25 + daily + + + https://faradaysec.com/beef/ + 2024-03-25 + daily + + + https://faradaysec.com/faraday-cli/ + 2024-03-25 + daily + + + https://faradaysec.com/faraday-dispatcher-v4/ + 2024-03-25 + daily + + + https://faradaysec.com/import/ + 2024-03-25 + daily + + + https://faradaysec.com/integration-gitlab/ + 2024-03-25 + daily + + + https://faradaysec.com/integration-jira/ + 2024-03-25 + daily + + + https://faradaysec.com/integration-servicenow/ + 2024-03-25 + daily + + + https://faradaysec.com/integration-solarwinds/ + 2024-03-25 + daily + + + https://faradaysec.com/requirements/ + 2024-03-25 + daily + + \ No newline at end of file diff --git a/sitemap.xml.gz b/sitemap.xml.gz new file mode 100644 index 00000000000..cdb5c94f979 Binary files /dev/null and b/sitemap.xml.gz differ diff --git a/stylesheets/faraday_doc.css b/stylesheets/faraday_doc.css new file mode 100644 index 00000000000..13ca0577759 --- /dev/null +++ b/stylesheets/faraday_doc.css @@ -0,0 +1,4 @@ +:root{ + --md-primary-fg-color: hsla(195.2,100%,44.1%,1); + --md-accent-fg-color: hsla(195.2,100%,44.1%,1); +} \ No newline at end of file diff --git a/stylesheets/hover.css b/stylesheets/hover.css new file mode 100644 index 00000000000..1cf9d2480fa --- /dev/null +++ b/stylesheets/hover.css @@ -0,0 +1,60 @@ +.professional { + display: inline; + position: relative; + overflow: hidden; + color: pink; + font-size: 15px; + font-family: var(--md-text-font-family,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif; + font-weight: bold; + } + +.professional:after { + content: ""; + position: absolute; + z-index: -1; + right: 0; + width: 0; + bottom: -2px; + background: pink; + height: 2px; + transition-property: width; + transition-duration: 0.3s; + transition-timing-function: ease-out; + } +.professional:hover:after, +.professional:focus:after, +.professional:active:after { + left: 0; + right: auto; + width: 100%; +} + +.corporate { + display: inline; + position: relative; + overflow: hidden; + color: black; + font-size: 15px; + font-family: var(--md-text-font-family,_),-apple-system,BlinkMacSystemFont,Helvetica,Arial,sans-serif; + font-weight: bold; + } +.corporate:after { + content: ""; + position: absolute; + z-index: -1; + right: 0; + width: 0; + bottom: -2px; + background: black; + height: 2px; + transition-property: width; + transition-duration: 0.3s; + transition-timing-function: ease-out; + } +.corporate:hover:after, +.corporate:focus:after, +.corporate:active:after { + left: 0; + right: auto; + width: 100%; + } \ No newline at end of file diff --git a/videos/faraday_vulnerabilitymanagement-1.mp4 b/videos/faraday_vulnerabilitymanagement-1.mp4 new file mode 100644 index 00000000000..c84f25d6236 Binary files /dev/null and b/videos/faraday_vulnerabilitymanagement-1.mp4 differ
+ +