Add BlackIP v1.0.0
parent
64d07e7b20
commit
45ea4c59d9
|
@ -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": {
|
||||
"BlackIP": {
|
||||
"projectType": "library",
|
||||
"root": "projects/BlackIP",
|
||||
"sourceRoot": "projects/BlackIP/src",
|
||||
"prefix": "lib",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@angular-devkit/build-ng-packagr:build",
|
||||
"options": {
|
||||
"tsConfig": "projects/BlackIP/tsconfig.lib.json",
|
||||
"project": "projects/BlackIP/ng-package.json"
|
||||
},
|
||||
"configurations": {
|
||||
"production": {
|
||||
"tsConfig": "projects/BlackIP/tsconfig.lib.prod.json"
|
||||
}
|
||||
}
|
||||
},
|
||||
"test": {
|
||||
"builder": "@angular-devkit/build-angular:karma",
|
||||
"options": {
|
||||
"main": "projects/BlackIP/src/test.ts",
|
||||
"tsConfig": "projects/BlackIP/tsconfig.spec.json",
|
||||
"karmaConfig": "projects/BlackIP/karma.conf.js"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"builder": "@angular-devkit/build-angular:tslint",
|
||||
"options": {
|
||||
"tsConfig": [
|
||||
"projects/BlackIP/tsconfig.lib.json",
|
||||
"projects/BlackIP/tsconfig.spec.json"
|
||||
],
|
||||
"exclude": [
|
||||
"**/node_modules/**"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}},
|
||||
"defaultProject": "BlackIP"
|
||||
}
|
|
@ -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": "BlackIP",
|
||||
"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/BlackIP",
|
||||
"lib": {
|
||||
"entryFile": "src/public-api.ts"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"name": "BlackIP",
|
||||
"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,27 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { BlackIPComponent } from './components/BlackIP.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: BlackIPComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
declarations: [BlackIPComponent],
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterModule.forChild(routes),
|
||||
MaterialModule,
|
||||
FlexLayoutModule,
|
||||
FormsModule,
|
||||
],
|
||||
exports: [BlackIPComponent]
|
||||
})
|
||||
export class BlackIPModule { }
|
|
@ -0,0 +1,60 @@
|
|||
<div style="display: flex; justify-content: center; align-items: center;">
|
||||
<span *ngIf="!hasInit" style="display: flex; justify-content: center; align-items: center; height: 10vh;">
|
||||
<mat-spinner diameter="25"></mat-spinner>
|
||||
</span>
|
||||
<mat-card *ngIf="hasInit" style="width: 40%;">
|
||||
<mat-card-content>
|
||||
<mat-card-title style="text-align: center;">BlackIP</mat-card-title>
|
||||
<mat-divider></mat-divider>
|
||||
<br>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<div style="width: 45%;">
|
||||
<i style="color: grey;"><small>IPv4 Blacklist</small></i>
|
||||
<textarea style="width: 100%; height: 150px; background-color: #efefef; border-color: #cecece; border-radius: 2px; resize: vertical;" disabled>{{ addresses4 }}</textarea>
|
||||
</div>
|
||||
<div style="width: 45%;">
|
||||
<i style="color: grey;"><small>IPv6 Blacklist</small></i>
|
||||
<textarea style="width: 100%; height: 150px; background-color: #efefef; border-color: #cecece; border-radius: 2px; resize: vertical;" disabled>{{ addresses6 }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<mat-form-field style="width: 75%;">
|
||||
<mat-label>IP Address (Local Or Public)</mat-label>
|
||||
<input class="control-input" matInput [(ngModel)]="userIP"/>
|
||||
</mat-form-field>
|
||||
<mat-form-field style="width: 15%">
|
||||
<mat-label>IPv4/IPv6</mat-label>
|
||||
<mat-select [(ngModel)]="userType">
|
||||
<mat-option value="">--</mat-option>
|
||||
<mat-option value="4">IPv4</mat-option>
|
||||
<mat-option value="6">IPv6</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<button style="width: 45%; height: 5vh;" mat-flat-button color="accent" (click)="add();">
|
||||
<span *ngIf="!isAdding">Add</span>
|
||||
<span *ngIf="isAdding" style="display: flex; justify-content: center; align-items: center; height: 5vh;">
|
||||
<mat-spinner diameter="20"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
<button style="width: 45%; height: 5vh; background-color: red;" mat-flat-button color="accent" (click)="clear();">
|
||||
<span *ngIf="!isResetting">Clear</span>
|
||||
<span *ngIf="isResetting" style="display: flex; justify-content: center; align-items: center; height: 5vh;">
|
||||
<mat-spinner diameter="20"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<br>
|
||||
<div style="display: flex; justify-content: space-evenly; align-items: center;">
|
||||
<button style="width: 100%; height: 5vh;" mat-flat-button color="accent" (click)="update();">
|
||||
<span *ngIf="!isUpdating">Update Firewall</span>
|
||||
<span *ngIf="isUpdating" style="display: flex; justify-content: center; align-items: center; height: 5vh;">
|
||||
<mat-spinner diameter="20"></mat-spinner>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<span style="display: flex; justify-content: center; align-items: center;"><small>{{ error }}</small></span>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
|
@ -0,0 +1,107 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { ApiService } from '../services/api.service';
|
||||
|
||||
@Component({
|
||||
selector: 'lib-BlackIP',
|
||||
templateUrl: './BlackIP.component.html',
|
||||
styleUrls: ['./BlackIP.component.css']
|
||||
})
|
||||
export class BlackIPComponent implements OnInit {
|
||||
constructor(private API: ApiService) { }
|
||||
|
||||
error = "";
|
||||
addresses4 = "";
|
||||
addresses6 = "";
|
||||
|
||||
userIP = "";
|
||||
userType = "";
|
||||
hasInit: boolean = false;
|
||||
isAdding: boolean = false;
|
||||
isResetting: boolean = false;
|
||||
isUpdating: boolean = false;
|
||||
|
||||
init(): void {
|
||||
this.API.request({
|
||||
module: 'BlackIP',
|
||||
action: "init"
|
||||
}, (response) => {
|
||||
if (response != "ok") {
|
||||
this.error = response;
|
||||
} else {
|
||||
this.hasInit = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get4(): void {
|
||||
this.API.request({
|
||||
module: 'BlackIP',
|
||||
action: "get4"
|
||||
}, (response) => {
|
||||
this.addresses4 = response;
|
||||
})
|
||||
}
|
||||
|
||||
get6(): void {
|
||||
this.API.request({
|
||||
module: 'BlackIP',
|
||||
action: "get6"
|
||||
}, (response) => {
|
||||
this.addresses6 = response;
|
||||
})
|
||||
}
|
||||
|
||||
add(): void {
|
||||
this.isAdding = true;
|
||||
this.API.request({
|
||||
module: 'BlackIP',
|
||||
action: "add",
|
||||
user_ip: this.userIP,
|
||||
user_type: this.userType
|
||||
}, (response) => {
|
||||
if (response != "ok") {
|
||||
this.error = response;
|
||||
} else {
|
||||
this.userIP = "";
|
||||
this.get4();
|
||||
this.get6();
|
||||
}
|
||||
this.isAdding = false;
|
||||
})
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.isResetting = true;
|
||||
this.API.request({
|
||||
module: 'BlackIP',
|
||||
action: "clear"
|
||||
}, (response) => {
|
||||
if (response != "ok") {
|
||||
this.error = response;
|
||||
} else {
|
||||
this.get4();
|
||||
this.get6();
|
||||
}
|
||||
this.isResetting = false;
|
||||
})
|
||||
}
|
||||
|
||||
update(): void {
|
||||
this.isUpdating = true;
|
||||
this.API.request({
|
||||
module: 'BlackIP',
|
||||
action: "update"
|
||||
}, (response) => {
|
||||
if (response != "ok") {
|
||||
this.error = response;
|
||||
}
|
||||
this.isUpdating = false;
|
||||
})
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.init();
|
||||
this.get4();
|
||||
this.get6();
|
||||
}
|
||||
}
|
|
@ -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,8 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class BlackIPService {
|
||||
constructor() {}
|
||||
}
|
|
@ -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,10 @@
|
|||
{
|
||||
"name": "BlackIP",
|
||||
"title": "BlackIP",
|
||||
"description": "Blacklist IP addresses and refuse their traffic",
|
||||
"version": "1.0.0",
|
||||
"author": "90N45",
|
||||
"firmware_required": "1.0.0",
|
||||
"devices": ["wifipineapplemk7"]
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
from pineapple.modules import Module, Request
|
||||
|
||||
module = Module('BlackIP', logging.DEBUG)
|
||||
|
||||
addresses_4 = []
|
||||
addresses_6 = []
|
||||
|
||||
@module.handles_action("init")
|
||||
def init(request):
|
||||
try:
|
||||
blacklist = str(os.popen("ipset list").read())
|
||||
if not "Name: blacklist" in blacklist:
|
||||
subprocess.run(["ipset", "create", "blacklist", "hash:ip", "hashsize", "4096"])
|
||||
subprocess.run(["ipset", "create", "blacklist6", "hash:net", "hashsize", "4096", "family", "inet6"])
|
||||
subprocess.run(["iptables", "-I", "FORWARD", "-m", "set", "--match-set", "blacklist", "src", "-j", "DROP",])
|
||||
subprocess.run(["iptables", "-I", "FORWARD", "-m", "set", "--match-set", "blacklist6", "src", "-j", "DROP",])
|
||||
return "ok"
|
||||
except Exception as e:
|
||||
return "Error: " + str(e)
|
||||
|
||||
@module.handles_action("add")
|
||||
def add_ip(request):
|
||||
if request.user_ip == "":
|
||||
return "Please specify an IP address"
|
||||
elif request.user_type == "":
|
||||
return "Please specify IPv4 or IPv6"
|
||||
elif request.user_ip == "" and request.user_type == "":
|
||||
return "Please specify an IP address and IPv4 or IPv6"
|
||||
elif request.user_type == "4":
|
||||
addresses_4.append(request.user_ip)
|
||||
return "ok"
|
||||
elif request.user_type == "6":
|
||||
addresses_6.append(request.user_ip)
|
||||
return "ok"
|
||||
|
||||
@module.handles_action("get4")
|
||||
def fetch_blacklist4(request):
|
||||
try:
|
||||
blacklist = ""
|
||||
for address in addresses_4:
|
||||
blacklist = blacklist + address + "\n"
|
||||
return blacklist
|
||||
except Exception as e:
|
||||
return "Error: " + str(e)
|
||||
|
||||
@module.handles_action("get6")
|
||||
def fetch_blacklist6(request):
|
||||
try:
|
||||
blacklist = ""
|
||||
for address in addresses_6:
|
||||
blacklist = blacklist + address + "\n"
|
||||
return blacklist
|
||||
except Exception as e:
|
||||
return "Error: " + str(e)
|
||||
|
||||
@module.handles_action("clear")
|
||||
def clear_blacklist(request):
|
||||
addresses_4.clear()
|
||||
addresses_6.clear()
|
||||
return "ok"
|
||||
|
||||
@module.handles_action("update")
|
||||
def update(request):
|
||||
try:
|
||||
blacklist = ""
|
||||
subprocess.run(["ipset", "flush", "blacklist"])
|
||||
subprocess.run(["ipset", "flush", "blacklist6"])
|
||||
|
||||
for address in addresses_4:
|
||||
subprocess.run(["ipset", "add", "blacklist", address])
|
||||
for address in addresses_6:
|
||||
subprocess.run(["ipset", "add", "blacklist6", address])
|
||||
return "ok"
|
||||
except Exception as e:
|
||||
return "Error: " + str(e)
|
||||
|
||||
if __name__ == '__main__':
|
||||
module.start()
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg height="100%" stroke-miterlimit="10" style="fill-rule:nonzero;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;" version="1.1" viewBox="0 0 1024 1024" width="100%" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs/>
|
||||
<g id="Ebene-1">
|
||||
<path d="M512 49.5C256.568 49.5 49.5 256.568 49.5 512C49.5 767.432 256.568 974.5 512 974.5C767.432 974.5 974.5 767.432 974.5 512C974.5 256.568 767.432 49.5 512 49.5ZM512 162C588.122 162 658.502 186.388 715.938 227.656L227.656 715.938C186.388 658.502 162 588.122 162 512C162 318.7 318.7 162 512 162ZM797.375 309.5C838.018 366.671 862 436.513 862 512C862 705.3 705.3 862 512 862C436.513 862 366.671 838.018 309.5 797.375L797.375 309.5Z" fill="#000000" fill-rule="nonzero" opacity="1" stroke="none"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 970 B |
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Public API Surface of BlackIP
|
||||
*/
|
||||
|
||||
export * from './lib/services/BlackIP.service';
|
||||
export * from './lib/components/BlackIP.component';
|
||||
export * from './lib/BlackIP.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": {
|
||||
"BlackIP": [
|
||||
"dist/BlackIP"
|
||||
],
|
||||
"BlackIP/*": [
|
||||
"dist/BlackIP/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"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