Create Initial Developer Documentation

This commit targets WiFi Pineapple Mark VII Firmware 1.1.0
pull/2/head
Marc Egerton 2021-01-13 23:52:52 +00:00 committed by Marc
commit fd08cc190f
No known key found for this signature in database
GPG Key ID: 0657563F705ACAAE
39 changed files with 5518 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.bundle/
_site/
vendor/

34
Gemfile Normal file
View File

@ -0,0 +1,34 @@
source "https://rubygems.org"
# Hello! This is where you manage which Jekyll version is used to run.
# When you want to use a different version, change it below, save the
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
#
# bundle exec jekyll serve
#
# This will help ensure the proper Jekyll version is running.
# Happy Jekylling!
gem "jekyll", "~> 3.8.5"
# This is the default theme for new Jekyll sites. You may change this to anything you like.
#gem "minima", "~> 2.5"
#gem "just-the-docs"
gem "jekyll-remote-theme"
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
# uncomment the line below. To upgrade, run `bundle update github-pages`.
gem "github-pages", "~> 204", group: :jekyll_plugins
# If you have any plugins, put them here!
group :jekyll_plugins do
gem "jekyll-feed", "~> 0.13"
end
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
# and associated library.
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
gem "tzinfo", "~> 1.2"
gem "tzinfo-data"
end
# Performance-booster for watching directories on Windows
gem "wdm", "~> 0.1.1", :install_if => Gem.win_platform?

266
Gemfile.lock Normal file
View File

@ -0,0 +1,266 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (6.0.3.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.2, >= 2.2.2)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.11.1)
colorator (1.1.0)
commonmarker (0.17.13)
ruby-enum (~> 0.5)
concurrent-ruby (1.1.7)
dnsruby (1.61.5)
simpleidn (~> 0.1)
em-websocket (0.5.2)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
ethon (0.12.0)
ffi (>= 1.3.0)
eventmachine (1.2.7)
execjs (2.7.0)
faraday (1.3.0)
faraday-net_http (~> 1.0)
multipart-post (>= 1.2, < 3)
ruby2_keywords
faraday-net_http (1.0.1)
ffi (1.14.2)
forwardable-extended (2.6.0)
gemoji (3.0.1)
github-pages (204)
github-pages-health-check (= 1.16.1)
jekyll (= 3.8.5)
jekyll-avatar (= 0.7.0)
jekyll-coffeescript (= 1.1.1)
jekyll-commonmark-ghpages (= 0.1.6)
jekyll-default-layout (= 0.1.4)
jekyll-feed (= 0.13.0)
jekyll-gist (= 1.5.0)
jekyll-github-metadata (= 2.13.0)
jekyll-mentions (= 1.5.1)
jekyll-optional-front-matter (= 0.3.2)
jekyll-paginate (= 1.1.0)
jekyll-readme-index (= 0.3.0)
jekyll-redirect-from (= 0.15.0)
jekyll-relative-links (= 0.6.1)
jekyll-remote-theme (= 0.4.1)
jekyll-sass-converter (= 1.5.2)
jekyll-seo-tag (= 2.6.1)
jekyll-sitemap (= 1.4.0)
jekyll-swiss (= 1.0.0)
jekyll-theme-architect (= 0.1.1)
jekyll-theme-cayman (= 0.1.1)
jekyll-theme-dinky (= 0.1.1)
jekyll-theme-hacker (= 0.1.1)
jekyll-theme-leap-day (= 0.1.1)
jekyll-theme-merlot (= 0.1.1)
jekyll-theme-midnight (= 0.1.1)
jekyll-theme-minimal (= 0.1.1)
jekyll-theme-modernist (= 0.1.1)
jekyll-theme-primer (= 0.5.4)
jekyll-theme-slate (= 0.1.1)
jekyll-theme-tactile (= 0.1.1)
jekyll-theme-time-machine (= 0.1.1)
jekyll-titles-from-headings (= 0.5.3)
jemoji (= 0.11.1)
kramdown (= 1.17.0)
liquid (= 4.0.3)
mercenary (~> 0.3)
minima (= 2.5.1)
nokogiri (>= 1.10.4, < 2.0)
rouge (= 3.13.0)
terminal-table (~> 1.4)
github-pages-health-check (1.16.1)
addressable (~> 2.3)
dnsruby (~> 1.60)
octokit (~> 4.0)
public_suffix (~> 3.0)
typhoeus (~> 1.3)
html-pipeline (2.14.0)
activesupport (>= 2)
nokogiri (>= 1.4)
http_parser.rb (0.6.0)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
jekyll (3.8.5)
addressable (~> 2.4)
colorator (~> 1.0)
em-websocket (~> 0.5)
i18n (~> 0.7)
jekyll-sass-converter (~> 1.0)
jekyll-watch (~> 2.0)
kramdown (~> 1.14)
liquid (~> 4.0)
mercenary (~> 0.3.3)
pathutil (~> 0.9)
rouge (>= 1.7, < 4)
safe_yaml (~> 1.0)
jekyll-avatar (0.7.0)
jekyll (>= 3.0, < 5.0)
jekyll-coffeescript (1.1.1)
coffee-script (~> 2.2)
coffee-script-source (~> 1.11.1)
jekyll-commonmark (1.3.1)
commonmarker (~> 0.14)
jekyll (>= 3.7, < 5.0)
jekyll-commonmark-ghpages (0.1.6)
commonmarker (~> 0.17.6)
jekyll-commonmark (~> 1.2)
rouge (>= 2.0, < 4.0)
jekyll-default-layout (0.1.4)
jekyll (~> 3.0)
jekyll-feed (0.13.0)
jekyll (>= 3.7, < 5.0)
jekyll-gist (1.5.0)
octokit (~> 4.2)
jekyll-github-metadata (2.13.0)
jekyll (>= 3.4, < 5.0)
octokit (~> 4.0, != 4.4.0)
jekyll-mentions (1.5.1)
html-pipeline (~> 2.3)
jekyll (>= 3.7, < 5.0)
jekyll-optional-front-matter (0.3.2)
jekyll (>= 3.0, < 5.0)
jekyll-paginate (1.1.0)
jekyll-readme-index (0.3.0)
jekyll (>= 3.0, < 5.0)
jekyll-redirect-from (0.15.0)
jekyll (>= 3.3, < 5.0)
jekyll-relative-links (0.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-remote-theme (0.4.1)
addressable (~> 2.0)
jekyll (>= 3.5, < 5.0)
rubyzip (>= 1.3.0)
jekyll-sass-converter (1.5.2)
sass (~> 3.4)
jekyll-seo-tag (2.6.1)
jekyll (>= 3.3, < 5.0)
jekyll-sitemap (1.4.0)
jekyll (>= 3.7, < 5.0)
jekyll-swiss (1.0.0)
jekyll-theme-architect (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-cayman (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-dinky (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-hacker (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-leap-day (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-merlot (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-midnight (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-minimal (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-modernist (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-primer (0.5.4)
jekyll (> 3.5, < 5.0)
jekyll-github-metadata (~> 2.9)
jekyll-seo-tag (~> 2.0)
jekyll-theme-slate (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-tactile (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-theme-time-machine (0.1.1)
jekyll (~> 3.5)
jekyll-seo-tag (~> 2.0)
jekyll-titles-from-headings (0.5.3)
jekyll (>= 3.3, < 5.0)
jekyll-watch (2.2.1)
listen (~> 3.0)
jemoji (0.11.1)
gemoji (~> 3.0)
html-pipeline (~> 2.2)
jekyll (>= 3.0, < 5.0)
kramdown (1.17.0)
liquid (4.0.3)
listen (3.4.1)
rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10)
mercenary (0.3.6)
minima (2.5.1)
jekyll (>= 3.5, < 5.0)
jekyll-feed (~> 0.9)
jekyll-seo-tag (~> 2.1)
minitest (5.14.3)
multipart-post (2.1.1)
nokogiri (1.11.1-x86_64-linux)
racc (~> 1.4)
octokit (4.20.0)
faraday (>= 0.9)
sawyer (~> 0.8.0, >= 0.5.3)
pathutil (0.16.2)
forwardable-extended (~> 2.6)
public_suffix (3.1.1)
racc (1.5.2)
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
rouge (3.13.0)
ruby-enum (0.8.0)
i18n
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
safe_yaml (1.0.5)
sass (3.7.4)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
simpleidn (0.2.1)
unf (~> 0.1.4)
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
typhoeus (1.4.0)
ethon (>= 0.9.0)
tzinfo (1.2.9)
thread_safe (~> 0.1)
tzinfo-data (1.2020.6)
tzinfo (>= 1.0.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
wdm (0.1.1)
zeitwerk (2.4.2)
PLATFORMS
x86_64-linux
DEPENDENCIES
github-pages (~> 204)
jekyll (~> 3.8.5)
jekyll-feed (~> 0.13)
jekyll-remote-theme
tzinfo (~> 1.2)
tzinfo-data
wdm (~> 0.1.1)
BUNDLED WITH
2.2.5

45
_config.yml Normal file
View File

@ -0,0 +1,45 @@
remote_theme: pmarsceill/just-the-docs@v0.3.3
title: WiFi Pineapple Mark 7 Developer Docs
description: Developer Documentation for the Hak5 WiFi Pineapple Mark 7
baseurl: "/mk7-docs"
url: "https://hak5.github.io"
permalink: pretty
exclude: ["vendor", ".gem", "Gemfile"]
search_enabled: true
search:
heading_level: 2
previews: 2
preview_words_before: 3
preview_words_after: 3
tokenizer_seperator: /[\s/\+/
rel_url: true
button: false
heading_achors: true
aux_links:
"View on GitHub":
- "//github.com/hak5/mk7-docs"
aux_links_new_tab: true
nav_sort: case_sensitive
back_to_top: true
back_to_top_text: "Back to Top"
footer_content: "Hak5"
last_edit_timestamp: true
last_edit_time_format: "%b %e %Y at %I:%M %p"
gh_edit_link: true
gh_edit_link_text: "Edit on GitHub"
gh_edit_repository: "https://github.com/hak5/mk7-docs"
gh_edit_branch: "gh-pages"
gh_edit_view_mode: "edit"
color_scheme: "light"

7
_sass/custom/custom.scss Normal file
View File

@ -0,0 +1,7 @@
@media (min-width: 50rem) {
.site-header {
height: 130px;
max-height: 120px;
border-bottom: 1px solid #eeebee;
}
}

73
assets/css/endpoints.css Normal file
View File

@ -0,0 +1,73 @@
.endpoint-collapsible, .endpoint-collapsible-non-click {
display: flex;
justify-content: space-between;
background-color: #eceff6;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.api-name {
color: #7556ed;
}
.api-rest-label {
padding: 3px 3px 3px 3px;
border-radius: 3px;
margin-right: 4px;
}
.api-rest-label-get {
background-color: #52ce0e;
}
.api-rest-label-post {
background-color: #119bdf;
}
.api-rest-label-put {
background-color: #e08f10;
}
.api-rest-label-delete {
background-color: #e02a10;
}
.api-label-post {
color: #119bdf;
}
.api-label-get {
color: #52ce0e;
}
.api-label-put {
color: #e08f10;
}
.api-label-delete {
color: #e02a10;
}
.endpoint-panel, .collapsible:hover {
background-color: #d3cde4;
}
.endpoint-content {
margin-top: -16px;
padding: 14px 18px 14px 18px;
display: none;
overflow: hidden;
background-color: #f5f6fa;
}
.endpoint-content-always-show {
padding: 14px 18px 14px 18px;
overflow: hidden;
background-color: #f5f6fa;
}
.code-block div {
background-color: #e2e2e2;
}
.code-block * {
background-color: #e2e2e2;
}

17
assets/js/endpoints.js Normal file
View File

@ -0,0 +1,17 @@
function togglePanel(el) {
el.classList.toggle("endpoint-panel");
var content = el.parentElement.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
}
function addHandlers() {
document.querySelectorAll('.endpoint-collapsible').forEach(item => {
item.addEventListener('click', event => {
togglePanel(item);
})
})
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

360
docs/modules/modules.md Normal file
View File

@ -0,0 +1,360 @@
---
layout: default
title: WiFi Pineapple Module Development Introduction
nav_order: 010
has_children: false
has_toc: true
---
# WiFi Pineapple Modules
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
WiFi Pineapple Mark VII Modules consist of two major pieces, a front-end and a back-end.
For the Mark VII, the front-end is written in [Angular](https://angular.io) with [Angular Material](https://material.angular.io). For those familiar with WiFi Pineapple NANO and TETRA module development which used AngularJS, you will find the code to be similar for the most part, but with some new concepts introduced. It is recommended that you become familiar with with the basics of Angular, however the examples below should be fairly easy to follow.
The back-end can be written in almost any language you would like, however we will be using Python 3 in the examples below, because it has the most mature library and comes by default in the WiFi Pineapple Mark VII firmware.
To illustrate the full development process, this article will explain how to create a basic WiFi Pineapple Mark VII module that will send and receive data from a Python 3 back-end.
## Module Development Overview
As mentioned in the introduction section, the front-end is written in Angular. Because of Angular's differences from the previous generation AngularJS, the front-end is compiled from HTML, TypeScript and CSS into a single Universal Module Definition (UMD). This UMD file is then ingested by the WiFi Pineapple's Web Interface and offers the user of your module interactive controls.
The back-end design has been further decoupled since the previous generation of the WiFi Pineapple, and it's now easier to write your module back-end in a language that you prefer instead of PHP. We have developed a Python library to make module development much easier, with libraries for other languages in the pipeline.
When the user visits your module front-end, an API request is sent to the WiFi Pineapple server that will start the back-end. This process opens a [Unix Domain Socket (UDS)](https://en.wikipedia.org/wiki/Unix_domain_socket) that allows the WiFi Pineapple server to forward front-end module requests to your desired back-end, and send the back-end response back to the front-end.
## Creating a Module
To start, make sure that you have `python3`, `nodeJS` and `npm` installed on your system. Then, fork the [WiFi Pineapple Mark VII Modules git repository](https://github.com/hak5/mk7-modules). Inside this repository, each module has it's own folder which contains the source-code for the front-end and back-end.
The repository also contains a script called `create.sh`, which will guide you through module generation.
```bash
(mk7-modules) >> ./create.sh
__ ___ ______ _ _____ _ _
\ \ / (_) ____(_) | __ (_) | |
\ \ /\ / / _| |__ _ | |__) | _ __ ___ __ _ _ __ _ __ | | ___
\ \/ \/ / | | __| | | | ___/ | '_ \ / _ \/ _` | '_ \| '_ \| |/ _ \
\ /\ / | | | | | | | | | | | | __/ (_| | |_) | |_) | | __/
\/ \/ |_|_| |_| |_| |_|_| |_|\___|\__,_| .__/| .__/|_|\___| Mark 7
Module Creation Helper | | | |
Version 1.0 |_| |_|
[*] Module Name: MyModule
[*] Module Title: My Module
[*] Module Author: foxtrot
[*] Module Short Description: This is my first module!
[*] Creating New Module (TestModule).
[!] Would you like to prepare the Angular workspace? [Y/n] y
[*] Preparing the Angular workspace.
[*] Prepared the Angular workspace.
[*] A new module has been created! Exiting.
(mk7-modules) >>
```
Once you have generated your module, change directory into it and you'll see the new Angular project that contains some skeleton code for the UI portion of your module.
There is also a helper script inside your new module directory named build.sh. This simple script will assist in building the module correctly for the WiFi Pineapple and can optionally package it for you.
```bash
(MyModule) >> ./build.sh
[*] Angular Build Succeeded
[*] Skipping Packaging (Run ./build.sh package to generate)
(MyModule) >>
```
Modules are packaged into a .tar.gz archive, which can be used to upload to the WiFi Pineapple through it's Management UI.
Alternatively, developers can build their modules without the packaging step, and upload the entire `dist/YourModuleName/` directory to to their WiFi Pineapple's `/pineapple/modules/` directory via SFTP, to speed up the development process.
## Editing Module Properties
Each module contains a JSON file (`projects/YourModuleName/src/module.json`) that contains your module's name, author, version and more.
```
───────┬────────────────────────────────────────────────────────────────────────────
│ File: projects/MyModule/src/module.json
───────┼────────────────────────────────────────────────────────────────────────────
1 │ {
2 │ "name": "MyModule",
3 │ "title": "My Module",
4 │ "description": "This is my first module!",
5 │ "version": "1.0",
6 │ "author": "foxtrot"
7 │ }
───────┴────────────────────────────────────────────────────────────────────────────
```
**Note**: It is important to bump your module's version number for every release you submit to the WiFi Pineapple Mark VII Modules Repository.
## Writing the Module Front End
For most people, the main directory of interest will be `projects/YourModuleName/src`. It contains the HTML, TypeScript and CSS for your module front-end, and will contain our back-end Python program too.
```bash
(src) >> ls
assets lib module.json module.svg public-api.ts
(src) >> ls assets/
README
(src) >> ls lib/
components modules MyModule.module.ts services
(src) >>
```
Most editing will be done in the `lib/components` and `lib/services` directory. The `components` directory contains the Angular components that can be rendered in your module's UI. The `services` directory contains services that your components can use to share data.
The assets directory contains files that will be installed alongside your module once it is packaged, such as configuration files, READMEs, etc.
By default, there is some boiler-plate example code in the `lib/components/YourModuleName.*` files.
```
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.html
──────┼────────────────────────────────────────────────────────────────────
1 │ <mat-card>
2 │ <mat-card-title>Welcome to MyModule</mat-card-title>
3 │ <mat-card-content>
4 │ This is the example module.
5 │ </mat-card-content>
6 │ </mat-card>
───────────────────────────────────────────────────────────────────────────
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.ts
──────┼────────────────────────────────────────────────────────────────────
1 │ import { Component, OnInit } from '@angular/core';
2 │ import { ApiService } from '../services/api.service';
3 │
4 │ @Component({
5 │ selector: 'lib-MyModule',
6 │ templateUrl: './MyModule.component.html',
7 │ styleUrls: ['./MyModule.component.css']
8 │ })
9 │ export class MyModuleComponent implements OnInit {
10 │ constructor(private API: ApiService) { }
11 │
12 │ ngOnInit() {
13 │ }
14 │ }
───────────────────────────────────────────────────────────────────────────
```
This boiler-plate code can be easily adapted to make an API request and display the output to the module's HTML, by using the `ApiService` service. In this example, we will get the WiFi Pineapple's firmware version from the internal 'status' API endpoint.
```
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.html
──────┼────────────────────────────────────────────────────────────────────
1 │ <mat-card>
2 │ <mat-card-title>Welcome to MyModule</mat-card-title>
3 │ <mat-card-content>
4 │ <button mat-flat-button color="accent"
5 | (click)="doAPIAction();">
6 │ Request to API
7 │ </button>
8 │ <br/>
9 │ <span>The version is: {{ apiResponse }}</span>
10 │ <br/>
11 │ </mat-card-content>
12 │ </mat-card>
───────────────────────────────────────────────────────────────────────────
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.ts
──────┼────────────────────────────────────────────────────────────────────
1 │ import { Component, OnInit } from '@angular/core';
2 │ import { ApiService } from '../services/api.service';
3 │
4 │ @Component({
5 │ selector: 'lib-MyModule',
6 │ templateUrl: './MyModule.component.html',
7 │ styleUrls: ['./MyModule.component.css']
8 │ })
9 │ export class MyModuleComponent implements OnInit {
10 │ constructor(private API: ApiService) { }
11 │
12 │ apiResponse = 'Press the button above to get the version.';
13 │
14 │ doAPIAction(): void {
15 │ this.API.APIGet('/api/status', (response) => {
16 │ this.apiResponse = response.versionString;
17 │ })
18 │ }
19 │
20 │ ngOnInit() {
21 │ }
22 │ }
───────────────────────────────────────────────────────────────────────────
```
After building, packaging and uploading the module to the WiFi Pineapple's Management UI, our module now has a button to request the version via the API.
![API Request](../assets/apireq.gif)
## Writing the Module Back End
Now that we have a working module front-end, we can focus on writing a custom API endpoint for our module. We'll be using the built-in [Python 3 library](x) to write our back-end module.
As mentioned earlier in this article, the module back-end also lives inside the `projects/YourModuleName/src` directory. **It must be named 'module.py'**.
As a basic starting point, we'll create a `module.py` with a simple function to send the words 'Hello World' back to the module UI.
```
──────┬────────────────────────────────────────────────────────────────────
│ File: module.py
──────┼────────────────────────────────────────────────────────────────────
1 │ #!/usr/bin/env python3
2 │
3 │ import logging
4 │
5 │ from pineapple.modules import Module, Request
6 │
7 │ module = Module('MyModule', logging.DEBUG)
8 │
9 │ @module.handles_action('hello_world')
10 │ def hello_world(request: Request):
11 │ return 'Hello World'
12 │
13 │ if __name__ == '__main__':
14 │ module.start()
───────────────────────────────────────────────────────────────────────────
```
Looking closer, we can see that we have registered a new module with our module's name on line 7, and defined an action called `hello_world` with a function that returns 'Hello World' on lines 9 through 11.
We can now update our UI to use our own back-end function.
```
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.html
──────┼────────────────────────────────────────────────────────────────────
1 │ <mat-card>
2 │ <mat-card-title>Welcome to MyModule</mat-card-title>
3 │ <mat-card-content>
4 │ <button mat-flat-button color="accent"
6 | (click)="doAPIAction();">
7 │ Request to Module
8 │ </button>
9 │ <br/>
10 │ <span>The API response was: {{ apiResponse }}</span>
11 │ <br/>
12 │ </mat-card-content>
13 │ </mat-card>
───────────────────────────────────────────────────────────────────────────
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.ts
──────┼────────────────────────────────────────────────────────────────────
1 │ import { Component, OnInit } from '@angular/core';
2 │ import { ApiService } from '../services/api.service';
3 │
4 │ @Component({
5 │ selector: 'lib-MyModule',
6 │ templateUrl: './MyModule.component.html',
7 │ styleUrls: ['./MyModule.component.css']
8 │ })
9 │ export class MyModuleComponent implements OnInit {
10 │ constructor(private API: ApiService) { }
11 │
12 │ apiResponse = 'Press the button above to get the response.';
13 │
14 │ doAPIAction(): void {
15 │ this.API.request({
16 │ module: 'MyModule',
17 │ action: 'hello_world',
18 │ }, (response) => {
19 │ this.apiResponse = response;
20 │ })
21 │ }
22 │
23 │ ngOnInit() {
24 │ }
25 │ }
───────────────────────────────────────────────────────────────────────────
```
Note in our `doAPIAction()` function that we are no longer using `this.API.APIGet()`, but instead are using `this.API.request()`, which takes two arguments: A JSON structure containing a minimum of `module` (our module's name), `action` (the function we defined earlier in our Python back-end), and a callback function for the module response. Read more about the [TypeScript API here.](https://hak5.github.io/mk7-docs/docs/typescript/typescript/)
After making those changes, building, packaging and re-uploading it to the WiFi Pineapple, our module now makes a request to a custom function defined in our back-end.
![Module Request](../assets/modulereq.gif)
The last step is getting data sent from your module's front-end to your module's back-end. Luckily, this is as simple as adding to the JSON structure we supply to `this.API.request()` and using the Python library to access it. In the next changes, we'll add a text input to the front-end and adapt our code to use it.
```
──────┬───────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.html
──────┼───────────────────────────────────────────────────────────────────
1 │ <mat-card>
2 │ <mat-card-title>Welcome to MyModule</mat-card-title>
3 │ <mat-card-content>
4 │ <mat-form-field>
5 │ <mat-label>Message to send to Module</mat-label>
6 │ <input matInput [(ngModel)]="userInput" />
7 │ </mat-form-field>
8 │
9 │ <button mat-flat-button color="accent"
10 │ (click)="doAPIAction();">
11 │ Request to Module
12 │ </button>
13 │ <br/>
14 │
15 │ <span>The API response was: {{ apiResponse }}</span>
16 │ <br/>
17 │ </mat-card-content>
18 │ </mat-card>
───────────────────────────────────────────────────────────────────────────
──────┬────────────────────────────────────────────────────────────────────
│ File: components/MyModule.component.ts
──────┼────────────────────────────────────────────────────────────────────
1 │ import { Component, OnInit } from '@angular/core';
2 │ import { ApiService } from '../services/api.service';
3 │
4 │ @Component({
5 │ selector: 'lib-MyModule',
6 │ templateUrl: './MyModule.component.html',
7 │ styleUrls: ['./MyModule.component.css']
8 │ })
9 │ export class MyModuleComponent implements OnInit {
10 │ constructor(private API: ApiService) { }
11 │
12 │ userInput = '';
13 │ apiResponse = 'Press the button above to get the response.';
14 │
15 │ doAPIAction(): void {
16 │ this.API.request({
17 │ module: 'MyModule',
18 │ action: 'hello_world',
19 │ user_input: this.userInput
20 │ }, (response) => {
21 │ this.apiResponse = response;
22 │ })
23 │ }
24 │
25 │ ngOnInit() {
26 │ }
27 │ }
───────────────────────────────────────────────────────────────────────────
```
Looking closer, we can see that in our HTML we've added some Material input and bound it using ngModel to our empty initialized variable in our TypeScript. We've also added the `user_input` property to our module request function, which we can access in our module back-end.
```
──────┬────────────────────────────────────────────────────────────────────
│ File: module.py
──────┼────────────────────────────────────────────────────────────────────
1 │ #!/usr/bin/env python3
2 │
3 │ import logging
4 │
5 │ from pineapple.modules import Module, Request
6 │
7 │ module = Module('MyModule', logging.DEBUG)
8 │
9 │ @module.handles_action('hello_world')
10 │ def check_dependencies(request: Request):
11 │ return 'You said: {}'.format(request.user_input)
12 │
13 │ if __name__ == '__main__':
14 │ module.start()
───────────────────────────────────────────────────────────────────────────
```
Once we build, package and re-upload this version to the WiFi Pineapple, we can test it out and make sure it's accepting our supplied data as expected.
![Module Request 2](../assets/modulereq2.gif)

View File

@ -0,0 +1,81 @@
---
layout: default
title: Command Helpers
nav_order: 302
parent: Helpers
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Command Helpers
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Functions
<button type="button" class="endpoint-collapsible">
<span class="api-name">grep_output(command, grep_text, grep_options)</span>
<span class="api-label-container">
<span class="api-label-post">bytes</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def grep_output(command: str, grep_text: str, grep_options: List[str] = None) -> bytes
```
</div>
Run a command and pipe it to grep for some output.
The output is returned.
<br/><br/>
For example this command:<br/>
ps -aux | grep pineap<br/>
Looks like this:<br/>
grep_output('ps -aux', 'pineap')<br/>
<br/>
<h3>Parameters</h3>
<ul>
<li>command: The initial command to run.</li>
<li>grep_text: The text to grep for.</li>
<li>grep_options: Any options to be passed to grep.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bytes: The output as bytes.</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">check_for_process(process_name)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def check_for_process(process_name) -> bool
```
</div>
Check if a process is running by its name.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>process_name: The name of the process to look for.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if the process is running, False if it is not.</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,52 @@
---
layout: default
title: Helpers
nav_order: 301
parent: WiFi Pineapple Python Documentation
has_children: true
has_toc: false
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Helpers Class
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Functions
<button type="button" class="endpoint-collapsible">
<span class="api-name">json_to_bytes(message)</span>
<span class="api-label-container">
<span class="api-label-post">bytes</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def json_to_bytes(message) -> bytes
```
</div>
JSON deserialize a message and then decode it.
<br/><br/>
Use this to convert your json message to bytes before publishing it over the socket.
<br/>
<h3>Parameters</h3>
<ul>
<li>message: A json serializable list or a dict.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bytes</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,73 @@
---
layout: default
title: Network Helpers
nav_order: 303
parent: Helpers
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Network Helpers
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Functions
<button type="button" class="endpoint-collapsible">
<span class="api-name">check_for_internet(url, timeout, logger)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def check_for_internet(url: str = 'https://downloads.hak5.org/internet', timout: int = 10, logger: Optional[Logger] = None) -> bool
```
</div>
Attempt to connect to a given url. If a connection was established then assume there is an internet connection.<br/>
If the connection fails to establish or times out then assume there is not internet.
Run a command and pipe it to grep for some output.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>url: The url to attempt to connect to. Default is https://downloads.hak5.org/internet.</li>
<li>timeout: The amount of time in seconds to wait before giving up. Default is 10.</li>
<li>logger: An optional instance of Logger use to log any exceptions while trying to establish a connection.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if there is an internet connection, False if there is not.</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">get_interfaces()</span>
<span class="api-label-container">
<span class="api-label-post">List[str]</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def get_interfaces() -> List[str]
```
</div>
Get a list of current network interfaces.
<br/><br/>
<h3>Returns</h3>
<ul>
<li>List[str]: A list of network interfaces available on the device.</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,70 @@
---
layout: default
title: Notification Helpers
nav_order: 304
parent: Helpers
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Notification Helpers
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Constants
<button type="button" class="endpoint-collapsible">
<span class="api-name">Log Levels</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
INFO = 0
WARN = 1
ERROR = 2
OTHER = 3
SUCCESS = 4
```
</div>
<br/><br/>
</div>
## Functions
<button type="button" class="endpoint-collapsible">
<span class="api-name">send_notification(message, module_name, level)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def send_notification(message: str, module_name: str, level: int = INFO) -> bool
```
</div>
Send a notification over the WiFi Pineapple's Notification socket
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>message: Notification message.</li>
<li>module_name: The name of the module the notification is from.</li>
<li>level: Notification level.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,182 @@
---
layout: default
title: Opkg Helpers
nav_order: 305
parent: Helpers
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Opkg Helpers
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Classes
<button type="button" class="endpoint-collapsible">
<span class="api-name">OpkgJob(Job[bool])</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
class OpkgJob(Job[bool])
```
</div>
A job to be used with the background JobManager that installs or uninstalls dependencies.
<br/><br/>
<h3>Methods</h3>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">do_work(self, logger)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def do_work(self, logger: Logger) -> bool
```
</div>
If `self.package` is a List:
Attempt to install each every package in the list. If a single package fails to install then this method will return False.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>logger: An optional instance of logger to log output from opkg as debug.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if no errors, False if error.</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">stop(self)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def stop(self)
```
</div>
Kill the opkg process if it is running.
</div>
</div>
## Functions
<button type="button" class="endpoint-collapsible">
<span class="api-name">update_repository(logger)</span>
<span class="api-label-container">
<span class="api-label-post">Tuple[bool, str]</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def update_repository(logger: Optional[Logger] = None) -> Tuple[bool, str]
```
</div>
Update the opkg package repository.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>logger: Optional instance of logger to log output from opkg as debug.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if successful, False if it was not.</li>
<li>str: Empty if successful, error message if it was not.</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">check_if_installed(package, logger)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def check_if_installed(package: str, logger: Optional[Logger] = None) -> bool
```
</div>
Check if a package is already installed via opkg.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>package: The name of the package to search for.</li>
<li>logger: An optional instance of logger to log output from opkg as debug.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if package installed, False if it is not.</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">install_dependency(package, logger, skip_repo_update)</span>
<span class="api-label-container">
<span class="api-label-post">[bool, str]</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def install_dependency(package: str, logger: Optional[Logger] = None, skip_repo_update: bool = False) -> [bool, str]
```
</div>
Install a package via opkg if its not currently installed.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>package: The name of the package to install.</li>
<li>logger: An optional instance of logger to log output from opkg as debug.</li>
<li>skip_repo_update: True to skip running `opkg update`. An internet connection will still be checked for.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if the package was installed, False if it as not.</li>
<li>str: Empty if successful, error message if it was not.</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">uninstall_dependency(package, logger)</span>
<span class="api-label-container">
<span class="api-label-post">[bool, str]</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def uninstall_dependency(package: str, logger: Optional[Logger] = None) -> [bool, str]
```
</div>
Uninstall a package via opkg if its currently installed.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>package: The name of the package to install.</li>
<li>logger: An optional instance of logger to log output from opkg as debug.</li>
</ul>
<h3>Returns</h3>
<ul>
<li>bool: True if the package was installed, False if it as not.</li>
<li>str: Empty if successful, error message if it was not.</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,80 @@
---
layout: default
title: Job
nav_order: 307
parent: Jobs
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Job
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Types
<button type="button" class="endpoint-collapsible">
<span class="api-name">TResult</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
TResult = TypeVar('TResult')
```
</div>
</div>
## Classes
<button type="button" class="endpoint-collapsible">
<span class="api-name">Job(Generic[TResult])</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
class Job(Generic[TResult])
```
</div>
A job to be used with the background JobManager that installs or uninstalls dependencies.
<br/><br/>
<h3>Properties</h3>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">was_successful(self)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def was_successful(self) -> bool
```
</div>
Checks if the job complete without an error.
If the job has not completed or if it complete with no errors return True.
If the job completed with an error then return False.
<br/><br/>
<h3>Returns</h3>
<ul>
<li>bool: True if the job completed without an error, otherwise False.</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,132 @@
---
layout: default
title: Job Manager
nav_order: 308
parent: Jobs
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Job Manager Class
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Classes
<button type="button" class="endpoint-collapsible">
<span class="api-name">JobManager</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
class JobManager
```
</div>
A job to be used with the background JobManager that installs or uninstalls dependencies.
<br/><br/>
<h3>Methods</h3>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">get_job(self, job_id, remove_if_complete)</span>
<span class="api-label-container">
<span class="api-label-post">Optional[Job]</span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def get_job(self, job_id: str, remove_if_complete: bool = True) -> Optional[Job]
```
</div>
Attempt to get a job by its id. If the job_id doesn't exist then None is returned.
If `remove_if_complete` is True the job will be deleted from memory only if it is completed.
This is the default behavior to prevent JobManager from tacking up unnecessary memory.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>job_id: The id of the job to find.</li>
<li>remove_if_complete: True to delete the job from memory after its complete. (Default: True)</li>
</ul>
<br/>
<h3>Returns</h3>
<ul>
<li>Optional[Job]: an instance of Job if found, else None</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">prune_completed_jobs</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def prune_completed_jobs(self)
```
</div>
Removes all completed jobs from memory.
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">remove_job(self, job_id)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def remove_job(self, job_id: str)
```
</div>
Remove a job from memory based on its id.
This will remove the job regardless of its completion status.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>job_id: The id of the job to delete.</li>
</ul>
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">execute_job(self, job, callbacks)</span>
<span class="api-label-container">
<span class="api-label-post">str</span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def execute_job(self, job: Job, callbacks: List[Callable[[Job], None]] = None) -> str
```
</div>
Assign an id to a job and execute it in a background thread.
The id will be returned and the job can be tracked by calling `get_job` and providing it the id.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>job: an instance of Job to start running.</li>
<li>callbacks: An optional list of functions that take `job` as a parameter to be called when completed. These will be called regardless if `job` raises an exception or not.</li>
</ul>
<br/>
<h3>Returns</h3>
<ul>
<li>str: The id of the running job.</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,72 @@
---
layout: default
title: Job Runner
nav_order: 309
parent: Jobs
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Job Runner
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Classes
<button type="button" class="endpoint-collapsible">
<span class="api-name">JobRunner</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
class JobRunner(Thread)
```
</div>
<h3>Methods</h3>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">run(self)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def run(self)
```
</div>
Call the `do_work` method on `self.job` and assign the results to `self.job.result`.
If an exception is raised by the `do_work` method, catch it and set `self.job.error` equal to it.
After `do_work` finishes set `self.job.is_complete` equal to True.
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">stop(self)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def stop(self)
```
</div>
Call the `stop` method on `self.job` if the job is running.
<br/>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

20
docs/python/jobs/jobs.md Normal file
View File

@ -0,0 +1,20 @@
---
layout: default
title: Jobs
nav_order: 306
parent: WiFi Pineapple Python Documentation
has_children: true
has_toc: false
---
# WiFi Pineapple Python Jobs Class
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API

View File

@ -0,0 +1,51 @@
---
layout: default
title: Logger
nav_order: 310
parent: WiFi Pineapple Python Documentation
has_children: true
has_toc: false
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Logger
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Functions
<button type="button" class="endpoint-collapsible">
<span class="api-name">get_logger(name, level, log_to_file, console_logger_level</span>
<span class="api-label-container">
<span class="api-label-post">Logger</span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
def get_logger(name: str, level: int, log_to_file: bool = True, console_logger_level: int = logging.DEBUG) -> Logger
```
</div>
<h3>Parameters</h3>
<ul>
<li>name: Name of Logger</li>
<li>level: Logging level.</li>
<li>log_to_file: Log to a file in /tmp/. Default: True</li>
<li>console_logger_level: Console log level Default: DEBUG</li>
</ul>
<h3>Returns</h3>
<ul>
<li>Logger</li>
</ul>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,21 @@
---
layout: default
title: Pretty Formatter
nav_order: 311
parent: Logger
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
# WiFi Pineapple Python Command Helpers
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API

View File

@ -0,0 +1,331 @@
---
layout: default
title: Module
nav_order: 314
parent: Modules
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Module
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Classes
<button type="button" class="endpoint-collapsible">
<span class="api-name">Module</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
class Module
```
</div>
A Pineapple Module
<br/><br/>
<h3>Methods</h3>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">__init__(self, name: str, log_level: int = logging.WARNING)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def __init__(self, name: str, log_level: int = logging.WARNING):
```
</div>
A WiFi Pineapple Module object in Python.
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>name: The name of the module.</li>
<li>The level of logging you wish to show. Default WARNING</li>
</ul>
<br/>
<h3>Returns</h3>
<ul>
<li>Optional[Job]: an instance of Job if found, else None</li>
</ul>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">shutdown(self, sig, frame)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def shutdown(self, sig=None, frame=None)
```
</div>
Attempt to clean shutdown the module.
If your module has anything it needs to close or otherwise cleanup upon shutdown, please override this and do what you need to here. Be sure you call `super.shutdown()` in your new implementation.
This method may also be called to handle signals such as SIGINT. If it was called as a signal handler the signal `sig` and frame `frame` will be passed into this method.
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">start()</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def start(self)
```
</div>
Main loop for the module which will run as long as `_running` is True.
This will listen for data coming over `_module_socket` and deserialize it to a `Request` object.
That object is then passed to `handle_request` for further processing.
<br/><br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">register_action_handler(action: str, handler: Callable[[Request], Union[Any, Tuple[Any, bool]]])</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def register_action_handler(self, action: str, handler: Callable[[Request], Union[Any, Tuple[Any, bool]]])
```
</div>
Manually register an function `handler` to handle an action `action`.
This function will be called anytime a request with the matching action is received.
The action handler must take a positional argument of type `Request`. This must be the first argument.
<br/>
<pre>
Usage Example:
module = Module('example')
def save_file(request: Request) -> Union[Any, Tuple[Any, bool]]:
...
module.register_action_handler(save_file)
</pre>
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>action: The request action to handle</li>
<li>handler: A function that takes `Request` that gets called when the matching `action` is received.</li>
</ul>
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">handles_action(self, action: str)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def handles_action(self, action: str)
```
</div>
A decorator that registers a function as an handler for a given action `action` in a request.
The decorated function is expected take an instance of `Request` as its first argument and can return either Any or a tuple with two values - Any, bool - in that order.
If the function does not return a tuple, The response is assumed to be successful and the returned value will be json serialized and placed into the 'payload' of the response body.
<br/>
<pre>
Example Function:
@handles_action('save_file')
def save_file(request: Request) -> str:
...
return 'Filed saved successfully!'
Example Response:
{ "payload": "File saved successfully!" }
</pre>
<br/>
If a tuple is returned, the first value in the tuple will the data sent back to the user. The second value must be a boolean that indicates whether the function was successful (True) or not (False). If this value is True, the data in the first index will be sent back in the response payload.
<br/>
<pre>
Example Function:
@handles_action('save_file')
def save_file(request: Request) -> Tuple[str, bool]:
...
return 'Filed saved successfully!', True
Example Response:
{ "payload": "File saved successfully!" }
</pre>
<br/>
However, if this value is False, The data in the first index will be sent back as an error.
<pre>
Example Function:
@handles_action('save_file')
def save_file(request: Request) -> Tuple[str, bool]:
...
return 'There was an issue saving the file.', False
Example Response:
{ "error": There was an issue saving the file." }
</pre>
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>action: The request action to handle</li>
</ul>
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">register_shutdown_handler(handler: Callable[[Optional[int]], None])</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def register_shutdown_handler(self, handler: Callable[[Optional[int]], None])
```
</div>
Manually register a function `handler` to be called on the module shutdown lifecycle event.
This handler function must take an integer as a parameter which may be the kill signal sent to the application.
Depending on how the module is shutdown, the signal value may be None.
<pre>
Example:
module = Module('example')
def stop_all_tasks(signal: int):
...
module.register_shutdown_handler(stop_all_tasks)
</pre>
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>handler: A function to be called on shutdown lifecycle event.</li>
</ul>
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">on_shutdown()</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def on_shutdown(self)
```
</div>
A decorator that registers a function as a shutdown handler to be called on the shutdown lifecycle event.
In the example below, the function `stop_all_tasks` will be called when the module process is terminated.
<pre>
Example:
@module.on_shutdown()
def stop_all_tasks(signal: int):
...
</pre>
<br/><br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">register_startup_handler(handler: Callable[[Optional[int]], None])</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def register_startup_handler(self, handler: Callable[[Optional[int]], None])
```
</div>
Manually register a function `handler` to be called on the module start lifecycle event.
This handler function most not take any arguments.
<pre>
Example:
module = Module('example')
def copy_configs():
...
module.register_startup_handler(copy_configs)
</pre>
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>handler: A function to be called on shutdown lifecycle event.</li>
</ul>
<br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">on_start()</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def on_start(self)
```
</div>
A decorator that registers a function as a startup handler to be called on the start lifecycle event. In the example below, the function `copy_configs` will be called when the modules `start` method is called.
<pre>
Example:
@module.on_start()
def copy_configs():
...
</pre>
<br/><br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">send_notification(self, message: str, level: int)</span>
<span class="api-label-container">
<span class="api-label-post">bool</span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def send_notification(self, message: str, level: int) -> bool
```
</div>
Send a notification over the WiFi Pineapples notification socket
<br/><br/>
<h3>Parameters</h3>
<ul>
<li>message: Notification message</li>
<li>level: Notification level</li>
</ul>
<br/>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,22 @@
---
layout: default
title: Modules
nav_order: 312
parent: WiFi Pineapple Python Documentation
has_children: true
has_toc: false
---
# WiFi Pineapple Python Modules
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API

View File

@ -0,0 +1,74 @@
---
layout: default
title: Request
nav_order: 313
parent: Modules
grand_parent: WiFi Pineapple Python Documentation
has_toc: false
---
<link rel="stylesheet" href="../../../../../assets/css/endpoints.css">
# WiFi Pineapple Python Requests
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API
## Classes
<button type="button" class="endpoint-collapsible">
<span class="api-name">Requests</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content">
<div markdown="1">
```python
class Module
```
</div>
A Pineapple Module
<br/><br/>
<h3>Methods</h3>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">__init__(self)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def __init__(self)
```
</div>
A WiFi Pineapple Module Request. Contains at least `self.module` and `self.action`, as well as any parameters given in a TypeScript API request.
<br/><br/>
</div>
<button type="button" class="endpoint-collapsible-non-click">
<span class="api-name">__repr__(self)</span>
<span class="api-label-container">
<span class="api-label-post"></span>
</span>
</button>
<div class="endpoint-content-always-show">
<div markdown="1">
```python
def __repr__(self)
```
</div>
Dumps the given data from the API rquest into Request.
<br/>
</div>
<script src="https://hak5.github.io/mk7-docs/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

19
docs/python/python.md Normal file
View File

@ -0,0 +1,19 @@
---
layout: default
title: WiFi Pineapple Python Documentation
nav_order: 300
has_children: true
has_toc: false
---
# WiFi Pineapple Python Documentation
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
Python API

View File

@ -0,0 +1,78 @@
---
layout: default
title: Authentication
nav_order: 102
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# REST Authentication
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
The WiFi Pineapple REST API will only accept requests that are sent with a valid token. Currently, the only way to generate a token is to login as the user. API Token generation is a planned feature.
```bash
foxtrot@intent:~$ curl -X POST http://172.16.42.1:1471/api/login -d '{"username": "root", "password": "test"}'
{"token":"eyJVc2VyIjoicm9vdCIsIkV4cGlyeSI6IjIwMjAtMDUtMTdUMTg6NDM6NTEuNjg1NjA5NTJaIn0=.VZpkUmWREeLMtKGx0wZFeWczj8hImbPnulTT5zpnQpM="}
foxtrot@intent:~$
```
The API endpoint responds with an error for invalid credentials, or a token on success. The token can then be used to make other API requests.
```bash
foxtrot@intent:~$ curl -X PUT http://172.16.42.1:1471/api/notifications -H "Authorization: Bearer eyJVc2VyIjoicm9vdCIsIkV4cGlyeSI6IjIwMjAtMDUtMTdUMTg6NDM6NTEuNjg1NjA5NTJaIn0=.VZpkUmWREeLMtKGx0wZFeWczj8hImbPnulTT5zpnQpM=" -d '{"level": 0, "message": "Hello World!"}'
{"success":true}
foxtrot@intent:~$
```
```bash
foxtrot@intent:~$ curl -X GET http://172.16.42.1:1471/api/notifications -H "Authorization: Bearer eyJVc2VyIjoicm9vdCIsIkV4cGlyeSI6IjIwMjAtMDUtMTdUMTg6NDM6NTEuNjg1NjA5NTJa
In0=.VZpkUmWREeLMtKGx0wZFeWczj8hImbPnulTT5zpnQpM="
[{"id":1,"message":"Hello World!","level":0,"time":"2020-09-18T10:30:21.031669675Z","read":false,"displayed":false,"module_name":""}]
foxtrot@intent:~$
```
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Authenticate with the WiFi Pineapple Mark 7</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/login</span>
</span>
</button>
<div class="endpoint-content">
Obtain an authentication token.<br/>
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"username": string,
"password": string,
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns authentication token:
<div class="code-block" markdown="1">
```json
{
"token": string
}
```
</div>
<b>If unsuccessful</b>: See REST Error Responses
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,260 @@
---
layout: default
title: Campaigns
nav_order: 106
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Campaigns
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Manage Campaigns
## Types
<button type="button" class="endpoint-collapsible">
<span class="api-name">Campaign</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface Campaign {
enabled?: boolean;
content?: string;
name: string;
created: number;
type: number;
timeout?: boolean;
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">CampaignReport</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface CampaignReport {
fileName: string;
fullPath: string;
}
```
</div>
</div>
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get All Campaigns</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/campaigns</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns all campaigns:
<div class="code-block" markdown="1">
```json
{
"campaigns": Campaign[]
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get All Campaign Reports</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/campaigns/reports</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns all campaign reports:
<div class="code-block" markdown="1">
```json
{
"fullPath": string,
"fileName": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete Campaign Report</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/campaigns/reports/:name</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Create New Campaign</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/campaigns/create</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"name": string,
"mode": number,
"autoRun": bool,
"interval": string,
"plainReport": bool,
"htmlReport": bool,
"storagePath": string,
"enableC2": bool,
"enableC2Exfil": bool
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete Campaign</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/campaigns/:name</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Campaign</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/campaigns/:name</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns the requested campaign:
<div class="code-block" markdown="1">
```json
{
"campaign": Campaign
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Save Campaign</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/campaigns/:name</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"name": string,
"content": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Enable Campaign</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/campaigns/:name/enable</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Disable Campaign</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/campaigns/:name/disable</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,145 @@
---
layout: default
title: Dashboard
nav_order: 105
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Dashboard
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Dashboard resources and helpers.
## Types
<button type="button" class="endpoint-collapsible">
<span class="api-name">DashboardCardData</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface DashboardCardData {
clientsConnected: string;
previousClients: string;
diskUsage: DiskUsageInterface;
mostPopularTraffic: TrafficInterface;
reconScansRan: number;
ssidsSeen: SSIDsSeenInterface;
systemStatus: SystemStatusInterface;
totalBandwidthUsed: number;
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">DiskUsageInterface</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
interface DiskUsageInterface {
rootUsage: string;
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">TrafficInterface</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
interface TrafficInterface {
first: string;
second: string;
third: string;
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">SSIDsSeenInterface</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
interface SSIDsSeenInterface {
totalSSIDs: string;
currentSSIDs: string;
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">SystemStatusInterface</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
interface SystemStatusInterface {
cpuUsage: number;
memoryUsage: number;
temperature: number;
}
```
</div>
</div>
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Dashboard Card Data</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/dashboard/cards</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
"systemStatus": SystemStatus,
"diskUsage": DiskUsage,
"clientsConnected": string,
"previousClients": string,
"ssidsSeen": SSIDsSeen
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Dashboard News</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/dashboard/news</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns latest news:
<div class="code-block" markdown="1">
```json
{
"news": NewsItem[]
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,31 @@
---
layout: default
title: REST Errors
nav_order: 101
parent: WiFi Pineapple REST Documentation
---
# REST Errors
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
The WiFi Pineapple REST API will return an error message when an error (any non-200 response) happens.
On success, API requests will return a **200 OK** response, and may include a JSON body.
On error, API requests may return a range of errors, most commonly a **500 Internal Server Error** or a **400 Bad Request**, as well as a JSON body containing an error message:
```json
{
"error": string
}
```

View File

@ -0,0 +1,172 @@
---
layout: default
title: Generic
nav_order: 104
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Generic
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Generic actions such as shutdown, reboot, and getting the device status.
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Reboot the WiFi Pineapple Mark 7</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/reboot</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Shutdown the WiFi Pineapple Mark 7</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/shutdown</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get WiFi Pineapple Mark 7 Status</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/status</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns device status:
<div class="code-block" markdown="1">
```json
{
"versionString": string,
"version": string,
"uptime": number,
"hostname": string,
"time": number
"warnings": PineappleWarnings,
"errors" PineappleErrors
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get WiFi Pineapple Mark 7 Model</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/device</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns device model:
<div class="code-block" markdown="1">
```json
{
"device": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Download File</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/download</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"filename": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns stream of specified file
<br/>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Lookup OUI Vendor</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/helpers/lookupOUI/:oui</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns an OUI vendor:
<div class="code-block" markdown="1">
```json
{
"available": true,
"vendor": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Check Internet Connection</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/helpers/checkonline</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns internet connectivity status:
<div class="code-block" markdown="1">
```json
{
"online": boolean
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,253 @@
---
layout: default
title: Modules
nav_order: 111
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Modules
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Modules are third-party extensions for the WiFi Pineapple.
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Handle Module Request</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/module/request</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Modules</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/modules</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Create Module</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/modules/create</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Install Remote Module</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/modules/install</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Sideload Module</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/modules/sideload/tar</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get list of available Modules</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/modules/available</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Remove Module</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/modules/:moduleName</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Mark Module as Favourite</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/modules/favourite/:moduleName</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
BODY
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, RETURNS:
<div class="code-block" markdown="1">
```json
{
RESPONSE
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,179 @@
---
layout: default
title: Notifications
nav_order: 103
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Notifications
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
The notifications system allows modules or other tools to communicate with the WiFi Pineapple user via the UI. You may specify a notification level, message, and optionally the name of the module that sent the notification.
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Create Notification</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/notifications</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"level": number,
"message": string,
"module_name": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Notifications</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/notifications</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns an array of notifications:
<div class="code-block" markdown="1">
```json
[{
"id": number,
"message": string,
"level": number,
"time": string,
"read": bool,
"displayed": bool,
"module_name": string
}]
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete All Notifications</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/notifications</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete Notification</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/notifications/:notificationId</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Mark All Notifications as Read</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/notifications/read</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Mark Notification as Read</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/notifications/:notificationId/read</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Mark Notification as Displayed</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/notifications/:notificationId/displayed</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

983
docs/rest/pineap/pineap.md Normal file
View File

@ -0,0 +1,983 @@
---
layout: default
title: PineAP
nav_order: 107
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# PineAP
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Manage PineAP
## Types
<button type="button" class="endpoint-collapsible">
<span class="api-name">PineAPSettings</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface PineAPSettings {
"enablePineAP": bool,
"autostartPineAP": bool,
"ap_channel": string,
"beacon_interval": string,
"beacon_response_interval": string,
"beacon_responses": bool,
"broadcast_ssid_pool": bool,
"capture_ssids": bool,
"connect_notifications": bool,
"disconnect_notifications": bool,
"karma": bool,
"logging": bool,
"pineap_mac": string,
"target_mac": string,
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">ChallengeResponse</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface ChallengeResponse {
"type": string,
"username": string,
"challenge": string,
"response": string
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">BasicResponse</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface BasicResponse {
"type": string,
"identity": string,
"password": string,
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Log</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface Log {
"type": int,
"mac": string,
"ssid": string,
"duplicates": int,
"created": int,
"updated": int,
}
```
</div>
</div>
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get PineAP Settings</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/settings</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns current PineAP settings:
<div class="code-block" markdown="1">
```json
{
"enablePineAP": bool,
"AutoStart": bool,
"ap_channel": string,
"beacon_interval": string,
"beacon_response_interval": string,
"beacon_responses": bool,
"broadcast_ssid_pool": bool,
"capture_ssids": bool,
"connect_notifications": bool,
"disconnect_notifications": bool,
"karma": bool,
"logging": bool,
"pineap_mac": string,
"target_mac": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Save PineAP Settings</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/settings</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"enablePineAP": bool,
"AutoStart": bool,
"ap_channel": string,
"beacon_interval": string,
"beacon_response_interval": string,
"beacon_responses": bool,
"broadcast_ssid_pool": bool,
"capture_ssids": bool,
"connect_notifications": bool,
"disconnect_notifications": bool,
"karma": bool,
"logging": bool,
"pineap_mac": string,
"target_mac": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get SSID Pool</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/ssids</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns a string of SSIDs seperated by newlines.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Clear SSID Pool</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/ssids</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Add SSID to Pool</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/ssids/ssid</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Remove SSID from Pool</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/ssids/ssid</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get WPA Handshakes</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/handshakes</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"handshakes": Handshake[]
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete All WPA Handshakes</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/handshakes</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Start WPA Handshake Capture</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/pineap/handshakes/start</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"bssid": string,
"channel": number,
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Stop WPA Handshake Capture</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/pineap/handshakes/stop</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Check if WPA Handshake Capture Active</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/handshakes/check</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"captureRunning": bool,
"bssid": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete WPA Handshake</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/handshakes/delete</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"type": string,
"bssid": bssid
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get PineAP Enterprise Settings</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/enterprise/settings</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"enabled": bool,
"associations": bool,
"ssid": string,
"mac": string,
"type": string,
"downgrade": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Save PineAP Enterprise Settings</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/enterprise/settings</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"enabled": bool,
"associations": bool,
"ssid": string,
"mac": string,
"type": string,
"downgrade": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Check if Enterprise Certificate available</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/enterprise/cert</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"installed": bool
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete Enterprise Certificate</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/enterprise/cert</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Generate Enterprise Certificate</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/pineap/enterprise/generatecert</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"state": string,
"country": string,
"locality": string,
"organization": string,
"email": string,
"commonname": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Basic PineAP Enterprise Data</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/enterprise/basicdata</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `BasicResponse[]`
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Clear Basic PineAP Enterprise Data</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/enterprise/basicdata</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get PineAP Enterprise Challenge Data</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/enterprise/challengedata</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `ChallengeResponse[]`.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Clear PineAP Enterprise Challenge Data</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/enterprise/challengedata</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Connected Clients</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/clients</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `Client[]`.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Connected Client Count</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/clients/count</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `number`.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Kick Connected Client</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/clients/kick</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mac": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Previously Connected Clients</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/previousclients</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `PreviousClient[]`.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Remove Previously Connected Client</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/previousclients/remove</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mac": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get PineAP Log</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/logging</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `Log[]`.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Filters Client Mode</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/filters/client/mode</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"mode": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Filters Client Mode</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/filters/client/mode</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mode": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Filters Client List</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/filters/client/list</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns MAC addresses seperated by newlines.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Filters Client List</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/filters/client/list</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mac": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Remove Client from Filter</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/filters/client/list</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mac": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Filters SSID Mode</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/filters/ssid/mode</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"mode": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Filters SSID Mode</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/filters/ssid/mode</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mode": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Filters SSID List</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/pineap/filters/ssid/list</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns a string of SSIDs seperated by newlines.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Filters SSID List</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/pineap/filters/ssid/list</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"mac": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Remove SSID from Filter</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/pineap/filters/ssid/list</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Deauthenticate AP</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/pineap/deauth/ap</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"bssid": string,
"multiplier": number,
"channel": number,
"clients": string[]
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Deauthenticate Client</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/pineap/deauth/client</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"bssid": string,
"mac": string,
"multiplier": number,
"channel": number
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

233
docs/rest/recon/recon.md Normal file
View File

@ -0,0 +1,233 @@
---
layout: default
title: Recon
nav_order: 108
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Recon
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Manage Recon
## Types
<button type="button" class="endpoint-collapsible">
<span class="api-name">ReconResult</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface ReconResult {
"APResults": []APResult
"OutOfRangeResult": []APClient
"UnassociatedResult": []APClient
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">APResult</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface APResult {
"ssid": string
"bssid": string
"encryption": number
"hidden": number
"wps": number
"channel": number
"signal": number
"data": number
"last_seen": number
"probes": number
"clients": []APClient
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">APClient</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface APClient {
"client_mac": string
"ap_mac": string
"ap_channel": number
"data": number
"broadcast_probes": number
"direct_probes": number
"last_seen": string
}
```
</div>
</div>
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Start Recon Scan</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/recon/start</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"live": bool,
"scan_time": number,
"band": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns scan status:
<div class="code-block" markdown="1">
```json
{
"scanRunning": bool,
"scanID": number
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Stop Recon Scan</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/recon/stop</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Recon Scan Status</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/recon/status</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns the current scan status:
<div class="code-block" markdown="1">
```json
{
"captureRunning": bool,
"scanRunning": bool,
"continuous": bool,
"scanPercent": number,
"scanID": number
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Recon Scans</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/recon/scans</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns array of previous scans:
<div class="code-block" markdown="1">
```json
[{
"scan_id": number,
"date": string
}]
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Recon Scan</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/recon/scans/:scan_id</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns specified scan data:
<div class="code-block" markdown="1">
```json
{
"APResults": APResult[],
"OutOfRangeClientResults": APClient[],
"UnassociatedClientResults": APClient[]
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Delete Recon Scan</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/recon/scans/:scan_id</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns success state:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Download Recon Scan</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/recon/scans/:scan_id/download/json</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns a JSON stream of the specified scan
<br/>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

29
docs/rest/rest.md Normal file
View File

@ -0,0 +1,29 @@
---
layout: default
title: WiFi Pineapple REST Documentation
nav_order: 100
has_children: true
has_toc: false
---
# WiFi Pineapple REST Documentation
{: .no_toc }
---
## Introduction
The WiFi Pineapple Mark VII exposes a powerful REST API that allows you to control aspects of the device via a WiFi Pineapple Module or independently via HTTP requests.
## Sections
- [REST Errors](errors/errors.md)
- [Authentication](authentication/authentication.md)
- [Notifications](notifications/notifications.md)
- [Generic](generic/generic.md)
- [Dashboard](dashboard/dashboard.md)
- [Campaigns](campaigns/campaigns.md)
- [PineAP](pineap/pineap.md)
- [Recon](recon/recon.md)
- [Modules](modules/modules.md)
- [Settings](settings/settings.md)

View File

@ -0,0 +1,752 @@
---
layout: default
title: Settings
nav_order: 109
parent: WiFi Pineapple REST Documentation
---
<link rel="stylesheet" href="../../../../assets/css/endpoints.css">
# Settings
{: .no_toc }
## Table of Contents
{: .no_toc .text-delta }
1. TOC
{:toc}
---
## Introduction
Manage Device Settings
## Types
<button type="button" class="endpoint-collapsible">
<span class="api-name">Handshake</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface Handshake {
"mac" string,
"type": string,
"extension" string,
"source": string
}
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">ClientModeNetwork</span>
</button>
<div class="endpoint-content" markdown="1">
<div class="code-block" markdown="1">
```typescript
export interface ClientModeNetwork {
bssid: string;
channel: string;
encryption: boolean;
password: string;
quality: string;
ssid: string;
hidden: boolean;
signal: string;
}
```
</div>
</div>
## Endpoints
<button type="button" class="endpoint-collapsible">
<span class="api-name">Change Password</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/users/password</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"old_password": string,
"new_password": string,
"confirm_password": string,
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Timezone</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/timezone</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"timezone": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Timezone</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/timezone</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"timezone": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Sync Browser Time</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/synctime</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"timestamp": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Button Script</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/button</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"button_script": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Button Script</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/button</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"button_script": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Resource Information</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/resources</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns `Resources`:
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get USB Devices</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/usb</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"devices": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Update Channel</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/update/channel</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"channel": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Set Update Channel</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/update/channel</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"channel": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Updates</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/update/refresh</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"update_found": bool,
"update_version": string,
"update_changelog": string,
"channel_closed": bool,
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Perform Update</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/settings/update/apply</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Reinstall Firmware</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/settings/update/reinstall</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Enroll in Cloud C2</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/cloudc2/config</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Form Body</h3>
<ul>
<li>`c2config`: Cloud C2 Configuration</li>
</ul>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Unenroll from Cloud C2</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-delete">DELETE</span>
<span class="api-label-delete">/api/settings/cloudc2/config</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Check Cloud C2 Enrollment</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/cloudc2/config</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"enrolled": bool
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Routing Table</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/networking/routes</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"routes": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Management AP Configuration</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/networking/ap/management</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"password": string,
"hidden": bool,
"disabled": bool
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Save Management AP Configuration</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/networking/ap/management</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"password": string,
"confirm_password": string,
"hidden": bool,
"disabled": bool
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Open AP Configuration</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/networking/ap/open</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"country": string,
"channel": number,
"hidden": bool
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Save Open AP Configuration</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/networking/ap/open</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"country": string,
"channel": number,
"hidden": bool
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Evil WPA Twin AP Configuration</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/networking/ap/wpa</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"bssid": string,
"auth": string,
"password": string,
"hidden": bool,
"disabled": bool,
"capture_handshakes": bool
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Save Evil WPA Twin AP Configuration</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-put">PUT</span>
<span class="api-label-put">/api/settings/networking/ap/wpa</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"bssid": string,
"auth": string,
"password": string,
"confirm_password": string,
"hidden": bool,
"disabled": bool,
"capture_handshakes": bool
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Client Mode Status</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/networking/clientmode/status</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"interfaces": string[],
"connected": bool,
"ssid": string,
"ip": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Scan for Client Networks</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/settings/networking/clientmode/scan</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"interface": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns `ScanResult[]`
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Connect to Network</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/settings/networking/clientmode/connect</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Request Body</h3>
<div class="code-block" markdown="1">
```json
{
"ssid": string,
"bssid": string,
"encryption": string,
"password": string,
"hidden": bool,
"interface": string
}
```
</div>
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Disconnect from Network</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/settings/networking/clientmode/disconnect</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Network Interfaces</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/networking/interfaces</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns an array of network interfaces.
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Start Diagnostics</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-post">POST</span>
<span class="api-label-post">/api/settings/diagnostics/start</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"success": true
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Get Diagnostics Status</span>
<span class="api-label-container">
<span class="api-rest-label api-rest-label-get">GET</span>
<span class="api-label-get">/api/settings/diagnostics/status</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Response</h3>
<b>If successful</b>, returns:
<div class="code-block" markdown="1">
```json
{
"completed": bool,
"output": string
}
```
</div>
<b>If unsuccessful</b>: [See REST Error Responses](../../errors/errors)
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

View File

@ -0,0 +1,306 @@
---
layout: default
title: WiFi Pineapple TypeScript Documentation
nav_order: 200
has_children: false
has_toc: true
---
<link rel="stylesheet" href="../../../assets/css/endpoints.css">
# WiFi Pineapple TypeScript Documentation
{: .no_toc }
Table of contents
{: .text-delta }
1. TOC
{:toc}
---
## Introduction
WiFi Pineapple Mark VII Module front-ends include a service named `ApiService` that offers a variety of helper functions, such as wrappers for easier interfaction with the [REST API](https://hak5.github.io/mk7-docs/docs/rest/rest/) or to communicate with [Modules](x). It is instantiated in the module component as `API`, an should always be named the same in custom components written by the module developer.
```typescript
@Component({
selector: 'lib-example-module',
templateUrl: './example-module.component.html',
styleUrls: ['./example-module.component.css']
})
export class ExampleModuleComponent implments OnInit {
constructor(private API: ApiService) { }
ngOnInit() { }
}
```
## Module Requests
Module requests are made with the `this.API.request()` function. It takes two arguments:
- `payload: any`
- `callback: any`
The `payload` must be a JSON structure that contains **at least** two properties:
- `module: string` (The name of the module you're making a request to)
- `action: string` (The action you are making a request for)
The `callback` is a function that takes a `response: any` as an argument. Extra data can be added to the request structure, and will be passwd to the module back-end where it may be processed.
```typescript
// A simple Module request
this.API.request({
module: 'ExampleModule',
action: 'some_action'
}, (response) => {
console.log(response);
});
// A module request with extra supplied data and error handling
this.API.request({
module: 'ExampleModule',
action: 'another_action',
my_data: 'My Own Data String',
other_data: could_be_a_variable
}, (response) {
if (response.error) {
// Handle Error
console.log('An error happened');
} else {
// Handle Success
console.log('Success!');
}
});
```
## REST API Requests
Regular API requests should be made with the following functions, depending on the type of request as specified in the [REST API](https://hak5.github.io/mk7-docs/docs/rest/rest/) docs.
<button type="button" class="endpoint-collapsible">
<span class="api-name">Unauthenticate User</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Example</h3>
Unauthenticate the current session.
<div class="code-block" markdown="1">
```typescript
this.API.unauth();
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Show Busy</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Example</h3>
Enables a spinner in the UI title bar to indicate a busy state.
<div class="code-block" markdown="1">
```typescript
this.API.setBusy();
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Show Not Busy</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
<h3>Example</h3>
Disables the UI title bar busy spinner.
<div class="code-block" markdown="1">
```typescript
this.API.setNotBusy();
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">API GET Request</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
this.API.APIGet(path: string, callback: (any));
```
Make a GET Request to a GET endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
this.API.APIGet('/api/status', (resp) => {
console.log(resp);
});
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Asyncronous API GET Request</span>
<span class="api-label-container">
<span class="api-label-post">Promise</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
async this.API.APIGetAsync(path: string);
```
Asynchronously make a GET Request to a GET endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
const resp: any = await this.API.APIGetAsync('/api/status');
console.log(resp);
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">API PUT Request</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
this.API.APIPut(path: string, callback: (any));
```
Make a PUT Request to a PUT endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
this.API.APIPut('/api/status', (resp) => {
console.log(resp);
});
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Asyncronous API PUT Request</span>
<span class="api-label-container">
<span class="api-label-post">Promise</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
async this.API.APIPutAsync(path: string);
```
Asynchronously make a PUT Request to a PUT endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
const resp: any = await this.API.APIPutAsync('/api/status');
console.log(resp);
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">API POST Request</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
this.API.APIPost(path: string, body: any, callback: (any));
```
Make a POST Request to a POST endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
this.API.APIPost('/api/status', { content: 'content'}, (resp) => {
console.log(resp);
});
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Asyncronous API POST Request</span>
<span class="api-label-container">
<span class="api-label-post">Promise</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
async this.API.APIGetAsync(path: string, body: any);
```
Asynchronously make a POST Request to a POST endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
const resp: any = await this.API.APIPostAsync('/api/status', { content: 'content'});
console.log(resp);
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">API DELETE Request</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
this.API.APIDelete(path: string, callback: (any));
```
Make a DELETE Request to a DELETE endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
this.API.APIDelete('/api/status', (resp) => {
console.log(resp);
});
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">Asyncronous API DELETE Request</span>
<span class="api-label-container">
<span class="api-label-post">Promise</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
async this.API.APIDeleteAsync(path: string);
```
Asynchronously make a DELETE Request to a DELETE endpoint described in the REST API documentation.
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
const resp: any = await this.API.APIDeleteAsync('/api/status');
console.log(resp);
```
</div>
</div>
<button type="button" class="endpoint-collapsible">
<span class="api-name">API File Download</span>
<span class="api-label-container">
<span class="api-label-post">void</span>
</span>
</button>
<div class="endpoint-content" markdown="1">
```typescript
this.API.APIDownload(fullpath: string, filename: string);
```
<h3>Example</h3>
<div class="code-block" markdown="1">
```typescript
this.API.APIDownload('/tmp/log.txt', 'log-output');
```
</div>
</div>
<script src="https://foxtrot.github.io/documentation/assets/js/endpoints.js"></script>
<script>addHandlers();</script>

12
index.md Normal file
View File

@ -0,0 +1,12 @@
---
layout: default
title: Home
nav_order: 1
description: "Hak5 WiFi Pineapple Mark 7 Developer Documentation"
permalink: /
---
# WiFi Pineapple Mark 7 Developer Documentation
This is the home for technical and developer documentation for the WiFi Pineapple Mark VII.