Add WiGLE module
parent
a0691e82e7
commit
25d60206e6
|
@ -0,0 +1,13 @@
|
|||
# Editor configuration, see https://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
trim_trailing_whitespace = false
|
|
@ -0,0 +1,46 @@
|
|||
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||
|
||||
# compiled output
|
||||
/dist
|
||||
/tmp
|
||||
/out-tsc
|
||||
# Only exists if Bazel was run
|
||||
/bazel-out
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
|
||||
# profiling files
|
||||
chrome-profiler-events*.json
|
||||
speed-measure-plugin*.json
|
||||
|
||||
# IDEs and editors
|
||||
/.idea
|
||||
.project
|
||||
.classpath
|
||||
.c9/
|
||||
*.launch
|
||||
.settings/
|
||||
*.sublime-workspace
|
||||
|
||||
# IDE - VSCode
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
.history/*
|
||||
|
||||
# misc
|
||||
/.sass-cache
|
||||
/connect.lock
|
||||
/coverage
|
||||
/libpeerconnection.log
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
testem.log
|
||||
/typings
|
||||
|
||||
# System Files
|
||||
.DS_Store
|
||||
Thumbs.db
|
|
@ -0,0 +1,47 @@
|
|||
{
|
||||
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
|
||||
"version": 1,
|
||||
"newProjectRoot": "projects",
|
||||
"projects": {
|
||||
"wigle": {
|
||||
"projectType": "library",
|
||||
"root": "projects/wigle",
|
||||
"sourceRoot": "projects/wigle/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/wigle/tsconfig.lib.json",
|
||||
"project": "projects/wigle/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/wigle/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/wigle/src/test.ts",
|
||||
"tsConfig": "projects/wigle/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/wigle/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/wigle/tsconfig.lib.json",
|
||||
"projects/wigle/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
"defaultProject": "wigle"
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
#!/bin/bash
|
||||
|
||||
MODULENAME=$(basename $PWD)
|
||||
|
||||
check_workspace() {
|
||||
if [[ ! -d "node_modules" ]]; then
|
||||
while true; do
|
||||
read -p "[!!] The Angular workspace has not been prepared. Would you like to do it now? [Y\n] " yn
|
||||
case $yn in
|
||||
[Yy]* ) prepare_workspace; break;;
|
||||
[Nn]* ) exit 1;;
|
||||
* ) prepare_workspace; break;;
|
||||
esac
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
prepare_workspace() {
|
||||
echo "[*] Preparing the Angular workspace."
|
||||
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo "[!] NPM does not appear to be installed on this system. Failed to create workspace."
|
||||
return
|
||||
fi
|
||||
|
||||
if ! npm install &> /dev/null; then
|
||||
echo "[!] Failed to prepare workspace. Run npm install to see why."
|
||||
return
|
||||
fi
|
||||
|
||||
echo "[*] Prepared the Angular workspace successfully."
|
||||
}
|
||||
|
||||
build_module() {
|
||||
ng build --prod > /dev/null 2>&1
|
||||
RET=$?
|
||||
|
||||
if [[ $RET -ne 0 ]]; then
|
||||
echo "[!] Angular Build Failed: Run 'ng build --prod' to figure out why."
|
||||
exit 1
|
||||
else
|
||||
echo "[*] Angular Build Succeeded"
|
||||
fi
|
||||
|
||||
# Step 2: Copy the required files to the build output
|
||||
cp -r projects/$MODULENAME/src/module.svg dist/$MODULENAME/bundles/
|
||||
cp -r projects/$MODULENAME/src/module.json dist/$MODULENAME/bundles/
|
||||
cp -r projects/$MODULENAME/src/module.py dist/$MODULENAME/bundles/ > /dev/null 2>&1
|
||||
cp -r projects/$MODULENAME/src/module.php dist/$MODULENAME/bundles/ > /dev/null 2>&1
|
||||
cp -r projects/$MODULENAME/src/assets/ dist/$MODULENAME/bundles/ > /dev/null 2>&1
|
||||
|
||||
# Step 3: Clean up
|
||||
rm -rf dist/$MODULENAME/bundles/*.map
|
||||
rm -rf dist/$MODULENAME/bundles/*.min*
|
||||
rm -rf bundletmp
|
||||
mv dist/$MODULENAME/bundles/ bundletmp
|
||||
rm -rf dist/$MODULENAME/*
|
||||
mv bundletmp/* dist/$MODULENAME/
|
||||
rm -rf bundletmp
|
||||
}
|
||||
|
||||
package() {
|
||||
VERS=$(cat dist/$MODULENAME/module.json | grep "version" | awk '{split($0, a, ": "); gsub("\"", "", a[2]); gsub(",", "", a[2]); print a[2]}')
|
||||
rm -rf $MODULENAME-$VERS.tar.gz
|
||||
echo "[*] Packaging $MODULENAME (Version $VERS)"
|
||||
cd dist/
|
||||
tar -pczf $MODULENAME-$VERS.tar.gz $MODULENAME
|
||||
mv $MODULENAME-$VERS.tar.gz ../
|
||||
cd ../
|
||||
}
|
||||
|
||||
copy_to_device() {
|
||||
echo "[*] Copying module to WiFi Pineapple via SCP"
|
||||
scp -r dist/$MODULENAME root@172.16.42.1:/pineapple/modules
|
||||
}
|
||||
|
||||
main() {
|
||||
check_workspace
|
||||
build_module
|
||||
|
||||
if [[ $1 == "package" ]]; then
|
||||
package
|
||||
elif [[ $1 == "copy" ]]; then
|
||||
copy_to_device
|
||||
fi
|
||||
|
||||
echo "[*] Success!"
|
||||
}
|
||||
|
||||
main $1
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"name": "wigle",
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"start": "ng serve",
|
||||
"build": "ng build",
|
||||
"test": "ng test",
|
||||
"lint": "ng lint",
|
||||
"e2e": "ng e2e"
|
||||
},
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@angular/animations": "~9.1.11",
|
||||
"@angular/cdk": "^9.2.4",
|
||||
"@angular/common": "~9.1.11",
|
||||
"@angular/compiler": "~9.1.11",
|
||||
"@angular/core": "~9.1.11",
|
||||
"@angular/flex-layout": "^9.0.0-beta.31",
|
||||
"@angular/forms": "~9.1.11",
|
||||
"@angular/material": "^9.2.4",
|
||||
"@angular/platform-browser": "~9.1.11",
|
||||
"@angular/platform-browser-dynamic": "~9.1.11",
|
||||
"@angular/router": "~9.1.11",
|
||||
"rxjs": "~6.5.5",
|
||||
"tslib": "^1.10.0",
|
||||
"zone.js": "~0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "~0.901.8",
|
||||
"@angular-devkit/build-ng-packagr": "~0.901.8",
|
||||
"@angular/cli": "~9.1.8",
|
||||
"@angular/compiler-cli": "~9.1.11",
|
||||
"@angular/language-service": "~9.1.11",
|
||||
"@types/jasmine": "~3.5.10",
|
||||
"@types/jasminewd2": "~2.0.3",
|
||||
"@types/node": "^12.11.1",
|
||||
"codelyzer": "^5.1.2",
|
||||
"jasmine-core": "~3.5.0",
|
||||
"jasmine-spec-reporter": "~5.0.2",
|
||||
"karma": "~5.1.0",
|
||||
"karma-chrome-launcher": "~3.1.0",
|
||||
"karma-coverage-istanbul-reporter": "~3.0.3",
|
||||
"karma-jasmine": "~3.3.1",
|
||||
"karma-jasmine-html-reporter": "^1.4.0",
|
||||
"ng-packagr": "^9.1.5",
|
||||
"protractor": "~7.0.0",
|
||||
"ts-node": "~8.10.2",
|
||||
"tslint": "~6.1.2",
|
||||
"typescript": "^3.6.5"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
|
||||
"dest": "../../dist/wigle",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "wigle",
|
||||
"version": "0.0.1",
|
||||
"peerDependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/core": "^8.2.14"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "ng build --prod"
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
This file is a placeholder for module assets that you may like to add.
|
|
@ -0,0 +1,93 @@
|
|||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<mat-card *ngIf="!hasKey" style="width: 40%;">
|
||||
<mat-card-content>
|
||||
<mat-card-title>Welcome To WiGLE</mat-card-title>
|
||||
<mat-card-subtitle>Lets get started.</mat-card-subtitle>
|
||||
<mat-divider></mat-divider>
|
||||
<br>
|
||||
<p>To request data from the WiGLE.net database on your WiFi Pineapple, you need an API token, which is generated when you create a free account at WiGLE.net
|
||||
</p>
|
||||
<br>
|
||||
<mat-form-field style="width: 100%;">
|
||||
<mat-label>Encoded Token</mat-label>
|
||||
<input class="control-input" matInput [(ngModel)]="userKey"/>
|
||||
</mat-form-field>
|
||||
<br>
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<button style="width: 45%; height: 34px; display: flex; justify-content: center; align-items: center;" mat-flat-button color="accent" (click)="saveKey()">
|
||||
<span *ngIf="!isSubmittingKey">Save</span>
|
||||
<span *ngIf="isSubmittingKey">
|
||||
<mat-spinner [diameter]="20"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<br>
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<span><small>You can find your encoded API token at <a href="https://wigle.net/account">wigle.net/account</a></small></span>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<mat-card *ngIf="hasKey" style="width: 40%;">
|
||||
<mat-card-content>
|
||||
<mat-card-title>WiGLE Lookup</mat-card-title>
|
||||
<div>
|
||||
<div style="display: flex; justify-content: space-evenly;">
|
||||
<mat-form-field style="word-break: break-word; padding: 1vw; width: 49%">
|
||||
<mat-label>Country Code</mat-label>
|
||||
<input class="control-input" matInput [(ngModel)]="userCC"/>
|
||||
</mat-form-field>
|
||||
<mat-form-field style="padding: 1vw; width: 49%;">
|
||||
<mat-label>City</mat-label>
|
||||
<input class="control-input" matInput [(ngModel)]="userCity"/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-evenly;">
|
||||
<mat-form-field style="word-break: break-word; padding: 1vw; width: 49%">
|
||||
<mat-label>SSID</mat-label>
|
||||
<input class="control-input" matInput [(ngModel)]="userSSID"/>
|
||||
</mat-form-field>
|
||||
<mat-form-field style="padding: 1vw; width: 49%;">
|
||||
<mat-label>MAC Address</mat-label>
|
||||
<input class="control-input" matInput [(ngModel)]="userMAC"/>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div *ngIf="apiResponse" style="display: flex; justify-content: space-evenly;">
|
||||
<div style="word-break: break-word; padding: 1vw; max-width: 300px;">
|
||||
<span><strong>SSID: </strong>{{ ssid }}</span>
|
||||
<br>
|
||||
<span><strong>Channel: </strong>{{ channel }}</span>
|
||||
<br>
|
||||
<span><strong>Encryption: </strong>{{ enc }}</span>
|
||||
<br>
|
||||
<span><strong>MAC Address: </strong>{{ mac }}</span>
|
||||
<br>
|
||||
<span><strong>DHCP: </strong>{{ dhcp }}</span>
|
||||
</div>
|
||||
<div style="padding: 1vw;">
|
||||
<span><strong>CC: </strong>{{ country }}</span>
|
||||
<br>
|
||||
<span><strong>City: </strong>{{ city }}</span>
|
||||
<br>
|
||||
<span><strong>Road: </strong>{{ road }}</span>
|
||||
<br>
|
||||
<span><strong>Latitude: </strong>{{ lat }}</span>
|
||||
<br>
|
||||
<span><strong>Longitude: </strong>{{ long }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span style="display: flex; justify-content: center; align-items: center;"><a href="{{ wiglenet }}"><small>{{ msg }}</small></a></span>
|
||||
<br>
|
||||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<button style="width: 45%; height: 34px; display: flex; justify-content: center; align-items: center;" mat-flat-button color="accent" (click)="fetch()">
|
||||
<span *ngIf="!isLoading">Search</span>
|
||||
<span *ngIf="isLoading">
|
||||
<mat-spinner [diameter]="20"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
|
@ -0,0 +1,106 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-wigle',
|
||||
templateUrl: './wigle.component.html',
|
||||
styleUrls: ['./wigle.component.css']
|
||||
})
|
||||
export class wigleComponent implements OnInit {
|
||||
constructor(private API: ApiService) { }
|
||||
|
||||
userSSID = "";
|
||||
userMAC = "";
|
||||
userCC = "";
|
||||
userCity = "";
|
||||
userKey = "";
|
||||
apiResponse: boolean = false;
|
||||
isLoading: boolean = false;
|
||||
isSubmittingKey: boolean = false;
|
||||
hasKey: boolean = true;
|
||||
|
||||
msg = "";
|
||||
wiglenet = "https://wigle.net/";
|
||||
ssid = "";
|
||||
channel = "";
|
||||
enc = "";
|
||||
mac = "";
|
||||
dhcp = "";
|
||||
country = "";
|
||||
city = "";
|
||||
road = "";
|
||||
lat = "";
|
||||
long = "";
|
||||
|
||||
fetch(): void {
|
||||
if ((this.userSSID == "") && (this.userMAC == "") && (this.userCC == "") && (this.userCity == "")) {
|
||||
this.msg = "Please specify at least one option...";
|
||||
this.apiResponse = false;
|
||||
} else {
|
||||
this.isLoading = true;
|
||||
this.API.request({
|
||||
module: "wigle",
|
||||
action: "search",
|
||||
user_ssid: this.userSSID,
|
||||
user_mac: this.userMAC,
|
||||
user_cc: this.userCC,
|
||||
user_city: this.userCity
|
||||
}, (response) => {
|
||||
if (response.total > 0) {
|
||||
this.msg = response.Message;
|
||||
this.wiglenet = response.Link;
|
||||
this.ssid = response.SSID;
|
||||
this.channel = response.Channel;
|
||||
this.enc = response.Encryption;
|
||||
this.mac = response.MAC;
|
||||
this.dhcp = response.DHCP;
|
||||
this.country = response.Country;
|
||||
this.city = response.City;
|
||||
this.road = response.Road;
|
||||
this.lat = response.Latitude;
|
||||
this.long = response.Longitude;
|
||||
this.apiResponse = true;
|
||||
} else {
|
||||
this.msg = response.Message;
|
||||
this.wiglenet = "https://wigle.net/";
|
||||
this.apiResponse = false;
|
||||
}
|
||||
this.isLoading = false;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
saveKey(): void {
|
||||
this.isSubmittingKey = true;
|
||||
this.API.request({
|
||||
module: 'wigle',
|
||||
action: "save",
|
||||
user_key: this.userKey
|
||||
}, (response) => {
|
||||
if (response == "Key saved") {
|
||||
this.hasKey = true;
|
||||
} else {
|
||||
this.hasKey = false;
|
||||
}
|
||||
this.isSubmittingKey = false;
|
||||
})
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
checkKey(): void {
|
||||
this.API.request({
|
||||
module: 'wigle',
|
||||
action: "check"
|
||||
}, (response) => {
|
||||
if (response == "Key specified") {
|
||||
this.hasKey = true;
|
||||
} else {
|
||||
this.hasKey = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.checkKey();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2018 Hak5 LLC.
|
||||
*/
|
||||
|
||||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { A11yModule } from '@angular/cdk/a11y';
|
||||
import { BidiModule } from '@angular/cdk/bidi';
|
||||
import { ObserversModule } from '@angular/cdk/observers';
|
||||
import { OverlayModule } from '@angular/cdk/overlay';
|
||||
import { PlatformModule } from '@angular/cdk/platform';
|
||||
import { PortalModule } from '@angular/cdk/portal';
|
||||
import { CdkStepperModule } from '@angular/cdk/stepper';
|
||||
import { CdkTableModule } from '@angular/cdk/table';
|
||||
import { CdkTreeModule } from '@angular/cdk/tree';
|
||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
||||
import { MatBadgeModule } from '@angular/material/badge';
|
||||
import { MatBottomSheetModule } from '@angular/material/bottom-sheet';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatChipsModule } from '@angular/material/chips';
|
||||
import { MatNativeDateModule, MatRippleModule } from '@angular/material/core';
|
||||
import { MatDatepickerModule } from '@angular/material/datepicker';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { MatDividerModule } from '@angular/material/divider';
|
||||
import { MatExpansionModule } from '@angular/material/expansion';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatGridListModule } from '@angular/material/grid-list';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatListModule } from '@angular/material/list';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
||||
import { MatRadioModule } from '@angular/material/radio';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSidenavModule } from '@angular/material/sidenav';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import { MatSliderModule } from '@angular/material/slider';
|
||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||
import { MatSortModule } from '@angular/material/sort';
|
||||
import { MatStepperModule } from '@angular/material/stepper';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
import { MatTabsModule } from '@angular/material/tabs';
|
||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { MatTreeModule } from '@angular/material/tree';
|
||||
|
||||
@NgModule({
|
||||
imports: [ CommonModule],
|
||||
exports: [
|
||||
// CDK
|
||||
A11yModule,
|
||||
BidiModule,
|
||||
ObserversModule,
|
||||
OverlayModule,
|
||||
PlatformModule,
|
||||
PortalModule,
|
||||
CdkStepperModule,
|
||||
CdkTableModule,
|
||||
CdkTreeModule,
|
||||
|
||||
// Material
|
||||
MatAutocompleteModule,
|
||||
MatBadgeModule,
|
||||
MatBottomSheetModule,
|
||||
MatButtonModule,
|
||||
MatButtonToggleModule,
|
||||
MatCardModule,
|
||||
MatCheckboxModule,
|
||||
MatChipsModule,
|
||||
MatDatepickerModule,
|
||||
MatDialogModule,
|
||||
MatDividerModule,
|
||||
MatExpansionModule,
|
||||
MatFormFieldModule,
|
||||
MatGridListModule,
|
||||
MatIconModule,
|
||||
MatInputModule,
|
||||
MatListModule,
|
||||
MatMenuModule,
|
||||
MatNativeDateModule,
|
||||
MatPaginatorModule,
|
||||
MatProgressBarModule,
|
||||
MatProgressSpinnerModule,
|
||||
MatRadioModule,
|
||||
MatRippleModule,
|
||||
MatSelectModule,
|
||||
MatSidenavModule,
|
||||
MatSliderModule,
|
||||
MatSlideToggleModule,
|
||||
MatSnackBarModule,
|
||||
MatSortModule,
|
||||
MatStepperModule,
|
||||
MatTableModule,
|
||||
MatTabsModule,
|
||||
MatToolbarModule,
|
||||
MatTooltipModule,
|
||||
MatTreeModule,
|
||||
],
|
||||
declarations: []
|
||||
})
|
||||
export class MaterialModule {
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
import {Injectable} from '@angular/core';
|
||||
import {HttpClient} from '@angular/common/http';
|
||||
import {Router} from '@angular/router';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class ApiService {
|
||||
public static totalRequests = 0;
|
||||
apiModuleBusy = document.getElementById('ApiModuleBusy');
|
||||
|
||||
constructor(private http: HttpClient,
|
||||
private router: Router) {}
|
||||
|
||||
emptyResponse = {error: 'Request returned empty response'};
|
||||
|
||||
unauth(): void {
|
||||
localStorage.removeItem('authToken');
|
||||
|
||||
if (this.router.url !== '/Login' && this.router.url !== '/Setup') {
|
||||
this.router.navigateByUrl('/Login');
|
||||
}
|
||||
}
|
||||
|
||||
setBusy(): void {
|
||||
this.apiModuleBusy.style.display = 'block';
|
||||
}
|
||||
setNotBusy(): void {
|
||||
this.apiModuleBusy.style.display = 'none';
|
||||
}
|
||||
|
||||
static extractBaseHref(): string {
|
||||
// Duplicated from injector because we have to be able to support
|
||||
// a static method here
|
||||
if (window['_app_base']) {
|
||||
if (window['_app_base'].endsWith('/')) {
|
||||
return window['_app_base'].slice(0, -1)
|
||||
}
|
||||
}
|
||||
return window['_app_base'] || '';
|
||||
}
|
||||
|
||||
request(payload: any, callback: (any) => void) {
|
||||
this.setBusy();
|
||||
let resp;
|
||||
|
||||
this.http.post(`${ApiService.extractBaseHref()}/api/module/request`, payload).subscribe((r: any) => {
|
||||
if (r === undefined || r === null) {
|
||||
resp = this.emptyResponse;
|
||||
} else if (r.error) {
|
||||
resp = r;
|
||||
} else {
|
||||
resp = r.payload;
|
||||
}
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
this.setNotBusy();
|
||||
callback(resp);
|
||||
}, () => {
|
||||
this.setNotBusy();
|
||||
callback(resp);
|
||||
});
|
||||
|
||||
ApiService.totalRequests++;
|
||||
}
|
||||
|
||||
APIGet(path: string, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.get(`${ApiService.extractBaseHref()}${path}`).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
r = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIGetAsync(path: string): Promise<any> {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
return await this.http.get(`${ApiService.extractBaseHref()}${path}`).toPromise();
|
||||
}
|
||||
|
||||
APIPut(path: string, body: any, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.put(`${ApiService.extractBaseHref()}${path}`, body).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
r = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIPutAsync(path: string, body: any): Promise<any> {
|
||||
return await this.http.put(`${ApiService.extractBaseHref()}/${path}`, body).toPromise();
|
||||
}
|
||||
|
||||
APIPost(path: string, body: any, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.post(`${ApiService.extractBaseHref()}${path}`, body).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
resp = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIPostAsync(path: string, body: any): Promise<any> {
|
||||
return await this.http.post(`${ApiService.extractBaseHref()}/${path}`, body).toPromise();
|
||||
}
|
||||
|
||||
APIDelete(path: string, body: any, callback: (any) => void): any {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
const opts = {
|
||||
headers: null,
|
||||
body: body
|
||||
};
|
||||
|
||||
let resp;
|
||||
|
||||
this.http.delete(`${ApiService.extractBaseHref()}/${path}`, opts).subscribe((r) => {
|
||||
if (r === undefined || r === null) {
|
||||
r = this.emptyResponse;
|
||||
}
|
||||
resp = r;
|
||||
}, (err) => {
|
||||
resp = err.error;
|
||||
if (err.status === 401) {
|
||||
this.unauth();
|
||||
}
|
||||
callback(resp);
|
||||
}, () => {
|
||||
callback(resp);
|
||||
});
|
||||
}
|
||||
|
||||
async APIDeleteAsync(path: string, body: any): Promise<any> {
|
||||
return await this.http.delete(`${ApiService.extractBaseHref()}${path}`, body).toPromise();
|
||||
}
|
||||
|
||||
APIDownload(fullpath: string, filename: string): void {
|
||||
ApiService.totalRequests++;
|
||||
|
||||
const body = {
|
||||
filename: fullpath
|
||||
};
|
||||
|
||||
this.http.post(`${ApiService.extractBaseHref()}/api/download`, body, {responseType: 'blob'}).subscribe((r) => {
|
||||
const url = window.URL.createObjectURL(r);
|
||||
const a = document.createElement('a');
|
||||
document.body.appendChild(a);
|
||||
a.setAttribute('style', 'display: none');
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
a.click();
|
||||
window.URL.revokeObjectURL(url);
|
||||
a.remove();
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class WigleService {
|
||||
constructor() {}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { wigleComponent } from './components/wigle.component';
|
||||
import { RouterModule, Routes } from '@angular/router';
|
||||
|
||||
import {MaterialModule} from './modules/material/material.module';
|
||||
import {FlexLayoutModule} from '@angular/flex-layout';
|
||||
|
||||
import {FormsModule} from '@angular/forms';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: wigleComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [wigleComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild(routes),
|
||||
MaterialModule,
|
||||
FlexLayoutModule,
|
||||
FormsModule,
|
||||
],
|
||||
exports: [wigleComponent]
|
||||
})
|
||||
export class wigleModule { }
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"name": "wigle",
|
||||
"title": "WiGLE",
|
||||
"description": "Information gathering of APs with the WiGLE.net database",
|
||||
"version": "1.0.2",
|
||||
"author": "90N45",
|
||||
"firmware_required": "1.0.0",
|
||||
"devices": ["wifipineapplemk7"]
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import json
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import logging
|
||||
from pineapple.modules import Module, Request
|
||||
import pineapple.helpers.notification_helpers as notifier
|
||||
|
||||
module = Module('wigle', logging.DEBUG)
|
||||
|
||||
@module.handles_action('search')
|
||||
def search_db(request):
|
||||
try:
|
||||
with open("modules/wigle/wigle.key", "r") as file:
|
||||
auth_token = file.read()
|
||||
|
||||
req = urllib.request.Request("https://api.wigle.net/api/v2/network/search?onlymine=false&freenet=false&paynet=false&resultsPerPage=1&country=" + urllib.parse.quote(request.user_cc.upper()) + "&city=" + urllib.parse.quote(request.user_city.title()) + "&ssid=" + urllib.parse.quote(request.user_ssid) + "&netid=" + urllib.parse.quote(request.user_mac), headers={"authorization": "Basic " + auth_token})
|
||||
with urllib.request.urlopen(req) as resp:
|
||||
data = resp.read()
|
||||
resp_dict = json.loads(data)
|
||||
|
||||
if resp_dict.get("success") == True:
|
||||
result = resp_dict.get("results")[0]
|
||||
return {"SSID":str(result.get("ssid")),"Channel":str(result.get("channel")),"Encryption":str(result.get("encryption")).upper(),"MAC":str(result.get("netid")).upper(),"DHCP":str(result.get("dhcp")),"Country":str(result.get("country")),"City":str(result.get("city")),"Road":str(result.get("road")),"Latitude":str(result.get("trilat")),"Longitude":str(result.get("trilong")),"total":resp_dict.get("totalResults"),"Message":"Total results: " + str(resp_dict.get("totalResults")),"Link":"https://wigle.net/search?country=" + request.user_cc.upper() + "&ssid=" + request.user_ssid + "&netid=" + request.user_mac}
|
||||
else:
|
||||
return {"Message":str(resp_dict.get("message")).upper()}
|
||||
except Exception as e:
|
||||
if str(e) == "list index out of range":
|
||||
return {"Message":"Total results: " + str(resp_dict.get("totalResults"))}
|
||||
else:
|
||||
return {"Message":"Error: " + str(e)}
|
||||
|
||||
@module.handles_action('check')
|
||||
def check_api_token(request):
|
||||
try:
|
||||
if os.path.getsize("modules/wigle/wigle.key") == 0:
|
||||
return "Key not specified"
|
||||
else:
|
||||
return "Key specified"
|
||||
except Exception as e:
|
||||
return "Key not specified: " + str(e)
|
||||
|
||||
@module.handles_action('save')
|
||||
def save_api_token(request):
|
||||
try:
|
||||
with open("modules/wigle/wigle.key", "w") as file:
|
||||
file.write(request.user_key)
|
||||
return "Key saved"
|
||||
except Exception as e:
|
||||
return "Key not saved: " + str(e)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
module.start()
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Public API Surface of wigle
|
||||
*/
|
||||
|
||||
export * from './lib/services/wigle.service';
|
||||
export * from './lib/components/wigle.component';
|
||||
export * from './lib/wigle.module';
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/lib",
|
||||
"target": "es2015",
|
||||
"declaration": true,
|
||||
"inlineSources": true,
|
||||
"types": [],
|
||||
"lib": [
|
||||
"dom",
|
||||
"es2018"
|
||||
]
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"skipTemplateCodegen": true,
|
||||
"strictMetadataEmit": true,
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true,
|
||||
"enableResourceInlining": true
|
||||
},
|
||||
"exclude": [
|
||||
"src/test.ts",
|
||||
"**/*.spec.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": "./tsconfig.lib.json",
|
||||
"angularCompilerOptions": {
|
||||
"enableIvy": false
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../out-tsc/spec",
|
||||
"types": [
|
||||
"jasmine",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"src/test.ts"
|
||||
],
|
||||
"include": [
|
||||
"**/*.spec.ts",
|
||||
"**/*.d.ts"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"extends": "../../tslint.json",
|
||||
"rules": {
|
||||
"directive-selector": [
|
||||
true,
|
||||
"attribute",
|
||||
"lib",
|
||||
"camelCase"
|
||||
],
|
||||
"component-selector": [
|
||||
true,
|
||||
"element",
|
||||
"lib",
|
||||
"kebab-case"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"typeRoots": [
|
||||
"node_modules/@types"
|
||||
],
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
],
|
||||
"paths": {
|
||||
"wigle": [
|
||||
"dist/wigle"
|
||||
],
|
||||
"wigle/*": [
|
||||
"dist/wigle/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"fullTemplateTypeCheck": true,
|
||||
"strictInjectionParameters": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"extends": "tslint:recommended",
|
||||
"rulesDirectory": [
|
||||
"codelyzer"
|
||||
],
|
||||
"rules": {
|
||||
"array-type": false,
|
||||
"arrow-parens": false,
|
||||
"deprecation": {
|
||||
"severity": "warning"
|
||||
},
|
||||
"import-blacklist": [
|
||||
true,
|
||||
"rxjs/Rx"
|
||||
],
|
||||
"interface-name": false,
|
||||
"max-classes-per-file": false,
|
||||
"max-line-length": [
|
||||
true,
|
||||
140
|
||||
],
|
||||
"member-access": false,
|
||||
"member-ordering": [
|
||||
true,
|
||||
{
|
||||
"order": [
|
||||
"static-field",
|
||||
"instance-field",
|
||||
"static-method",
|
||||
"instance-method"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-consecutive-blank-lines": false,
|
||||
"no-console": [
|
||||
true,
|
||||
"debug",
|
||||
"info",
|
||||
"time",
|
||||
"timeEnd",
|
||||
"trace"
|
||||
],
|
||||
"no-empty": false,
|
||||
"no-inferrable-types": [
|
||||
true,
|
||||
"ignore-params"
|
||||
],
|
||||
"no-non-null-assertion": true,
|
||||
"no-redundant-jsdoc": true,
|
||||
"no-switch-case-fall-through": true,
|
||||
"no-var-requires": false,
|
||||
"object-literal-key-quotes": [
|
||||
true,
|
||||
"as-needed"
|
||||
],
|
||||
"object-literal-sort-keys": false,
|
||||
"ordered-imports": false,
|
||||
"quotemark": [
|
||||
true,
|
||||
"single"
|
||||
],
|
||||
"trailing-comma": false,
|
||||
"component-class-suffix": true,
|
||||
"contextual-lifecycle": true,
|
||||
"directive-class-suffix": true,
|
||||
"no-conflicting-lifecycle": true,
|
||||
"no-host-metadata-property": true,
|
||||
"no-input-rename": true,
|
||||
"no-inputs-metadata-property": true,
|
||||
"no-output-native": true,
|
||||
"no-output-on-prefix": true,
|
||||
"no-output-rename": true,
|
||||
"no-outputs-metadata-property": true,
|
||||
"template-banana-in-box": true,
|
||||
"template-no-negated-async": true,
|
||||
"use-lifecycle-interface": true,
|
||||
"use-pipe-transform-interface": true
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue