Merge pull request from safing/fix/netquery-textql-parser

Fix netquery textql parser for IP addresses
This commit is contained in:
Daniel Hååvi 2024-03-29 11:11:48 +01:00 committed by GitHub
commit 2e130a8ab5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 209 additions and 191 deletions

View file

@ -9,3 +9,13 @@ updates:
directory: "/"
schedule:
interval: "daily"
- package-ecosystem: "npm"
directory: "/desktop/angular"
schedule:
interval: "daily"
- package-ecosystem: "cargo"
directory: "/desktop/tauri"
schedule:
interval: "daily"

61
.github/workflows/angular.yml vendored Normal file
View file

@ -0,0 +1,61 @@
name: Angular
on:
push:
paths:
- 'desktop/angular/**'
branches:
- master
- develop
- migration/mono-repo
pull_request:
paths:
- 'desktop/angular/**'
branches:
- master
- develop
- migration/mono-repo
jobs:
lint:
name: Linter
runs-on: ubuntu-latest
defaults:
run:
working-directory: desktop/angular
steps:
- name: Check out code
uses: actions/checkout@v4
- uses: actions/setup-node@v3
with:
node-version: 18
- run: npm install
- uses: sibiraj-s/action-eslint@v3
with:
annotations: true
extensions: 'ts,html'
working-directory: desktop/angular
test:
name: Build
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@v1
with:
version: v0.8.0
- uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build angular projects
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +build-angular

View file

@ -45,5 +45,13 @@ jobs:
with:
version: v0.8.0
- uses: actions/checkout@v4
- name: Run tests
run: earthly --ci +test-go --TESTFLAGS="-short"
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build angular projects
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +test-go --TESTFLAGS="-short"

38
.github/workflows/tauri.yml vendored Normal file
View file

@ -0,0 +1,38 @@
name: Tauri
on:
push:
paths:
- 'desktop/tauri/**'
branches:
- master
- develop
- migration/mono-repo
pull_request:
paths:
- 'desktop/tauri/**'
branches:
- master
- develop
- migration/mono-repo
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- uses: earthly/actions-setup@v1
with:
version: v0.8.0
- uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build angular projects
run: earthly --ci --remote-cache=ghcr.io/safing/build-cache --push +tauri-release

View file

@ -66,11 +66,11 @@ go-base:
LET version = $(git tag --points-at)
IF [ "${version}" = "" ]
SET version = $(git describe --tags --abbrev=0 || echo "dev build")
SET version = $(git describe --tags --abbrev=0 || echo "dev_build")
END
ENV VERSION="${version}"
LET source = $( ( git remote -v | cut -f2 | cut -d" " -f1 | head -n 1 ) || echo "unknown source" )
LET source = $( ( git remote -v | cut -f2 | cut -d" " -f1 | head -n 1 ) || echo "unknown_source" )
ENV SOURCE="${source}"
# updates all go dependencies and runs go mod tidy, saving go.mod and go.sum locally.
@ -222,6 +222,11 @@ angular-project:
SAVE ARTIFACT "./${project}.zip" AS LOCAL ${outputDir}/${project}.zip
SAVE ARTIFACT "./dist" AS LOCAL ${outputDir}/${project}
# Builds all angular projects
build-angular:
BUILD +angular-project --project=portmaster --dist=./dist --configuration=development --baseHref=/ui/modules/portmaster/
BUILD +angular-project --project=tauri-builtin --dist=./dist/tauri-builtin --configuration=development --baseHref=/
# Build the angular projects (portmaster-UI and tauri-builtin) in production mode
angular-release:
BUILD +angular-project --project=portmaster --dist=./dist --configuration=production --baseHref=/ui/modules/portmaster/

View file

@ -0,0 +1,54 @@
{
"root": true,
"ignorePatterns": [
"projects/**/*"
],
"parserOptions": {
"tsconfigRootDir": "desktop/angular"
},
"overrides": [
{
"files": [
"*.ts"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates"
],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "app",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "app",
"style": "kebab-case"
}
],
"@typescript-eslint/no-explicit-any": "off"
}
},
{
"files": [
"*.html"
],
"extends": [
"plugin:@angular-eslint/template/recommended",
"plugin:@angular-eslint/template/accessibility"
],
"rules": {
"@angular-eslint/template/click-events-have-key-events": "off",
"@angular-eslint/template/interactive-supports-focus": "off"
}
}
]
}

View file

@ -96,7 +96,6 @@
"protractor": "~7.0.0",
"tailwindcss": "^3.3.2",
"ts-node": "^10.9.1",
"tslint": "~6.1.0",
"typescript": "4.9",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-ext-reloader": "^1.1.9",

View file

@ -1,5 +1,5 @@
<ng-template #customTriggerTemplate>
<button [class.active]="dropdown?.isOpen" type="button" class="sfng-select" [class.disabled]="disabled">
<button [class.active]="dropdown?.isOpen" type="button" class="sfng-select" [class.disabled]="disabled" tabindex="-1">
<ng-template [ngIf]="mode !== 'multi' || (currentItems.length || 0) <= 1" [ngIfElse]="multiTemplate">
<span *ngIf="!currentItems.length; else: itemTemplate">
@ -58,7 +58,7 @@
</li>
<!-- fake item for "dynamic" values -->
<li *ngIf="!!searchText && items.length === 0 && dynamicValues"
<li *ngIf="!!searchText && items.length === 0 && dynamicValues"
(click)="selectItem({selected: false, value: searchText})" class="pl-1 pr-5">
<sfng-select-item>
<span>

View file

@ -117,12 +117,7 @@ export const supportTypes: PageSections[] = [
includeDebugData: true,
privateTicket: true,
ghIssuePreset: "report-bug.md",
repositories: [
{ repo: 'portmaster', name: 'Portmaster Core' },
{ repo: 'portmaster-ui', name: 'User Interface' },
{ repo: 'portmaster-packaging', name: 'Packaging & Installers' },
{ repo: 'spn', name: 'SPN' },
]
repositories: []
},
{
id: "give-feedback",
@ -140,12 +135,7 @@ export const supportTypes: PageSections[] = [
includeDebugData: false,
privateTicket: true,
ghIssuePreset: "suggest-feature.md",
repositories: [
{ repo: 'portmaster', name: 'Portmaster Core' },
{ repo: 'portmaster-ui', name: 'User Interface' },
{ repo: 'portmaster-packaging', name: 'Packaging & Installers' },
{ repo: 'spn', name: 'SPN' },
]
repositories: []
},
{
id: "compatibility-report",

View file

@ -188,12 +188,12 @@ export class SfngNetqueryLineChartComponent<D extends SeriesData = any> implemen
}
ngOnChanges(changes: SimpleChanges): void {
if (changes.hasOwnProperty('config') && this.config) {
if (Object.prototype.hasOwnProperty.call(changes, 'config') && this.config) {
this.redraw()
return
}
if (changes.hasOwnProperty('data') && this.data) {
if (Object.prototype.hasOwnProperty.call(changes, 'data') && this.data) {
this.drawChart();
}
}
@ -398,9 +398,9 @@ export class SfngNetqueryLineChartComponent<D extends SeriesData = any> implemen
const interval = this.config.fillEmptyTicks.interval;
let filledData: D[] = [];
const filledData: D[] = [];
const addEmpty = (ts: number) => {
let empty: any = {
const empty: any = {
timestamp: ts,
}
@ -410,7 +410,11 @@ export class SfngNetqueryLineChartComponent<D extends SeriesData = any> implemen
filledData.push(empty)
}
let firstElement = data[0]!.timestamp;
if (!data.length) {
return [];
}
let firstElement = data[0].timestamp;
if (this.config.time?.from) {
firstElement = Math.round(coerceDate(this.config.time.from).getTime() / 1000)
}

View file

@ -14,9 +14,9 @@
</svg>
</div>
<span class="ml-2 cursor-pointer text-tertiary text-xxs hover:text-primary" (click)="clearQuery()">
<button class="bg-transparent hover:bg-transparent ml-2 cursor-pointer text-tertiary text-xxs hover:text-primary p-2" (click)="clearQuery()" (keyup.enter)="clearQuery()">
Clear All
</span>
</button>
</div>
<div class="flex flex-row items-center w-full gap-2">
@ -129,7 +129,7 @@
<ng-template #customTimeRange>
<span class="py-2 uppercase text-xxs text-secondary">Quick Settings</span>
<ul class="grid grid-flow-row grid-cols-3 py-2 text-xs">
<li *ngFor="let qds of quickDateSettings" (click)="applyQuickDateSetting(qds)"
<li tabindex="0" *ngFor="let qds of quickDateSettings" (click)="applyQuickDateSetting(qds)" (keyup.enter)="applyQuickDateSetting(qds)"
class="cursor-pointer text-secondary hover:text-primary px-2 py-1.5 hover:bg-gray-500 hover:bg-opacity-50 rounded-md">
{{ qds.name }}
</li>
@ -350,7 +350,7 @@
d="M11 3a1 1 0 10-2 0v1a1 1 0 102 0V3zM15.657 5.757a1 1 0 00-1.414-1.414l-.707.707a1 1 0 001.414 1.414l.707-.707zM18 10a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM5.05 6.464A1 1 0 106.464 5.05l-.707-.707a1 1 0 00-1.414 1.414l.707.707zM5 10a1 1 0 01-1 1H3a1 1 0 110-2h1a1 1 0 011 1zM8 16v-1h4v1a2 2 0 11-4 0zM12 14c.015-.34.208-.646.477-.859a4 4 0 10-4.954 0c.27.213.462.519.476.859h4.002z" />
</svg>
<span class="font-semibold text-primary">Pro Tip:</span>
<span class="protip">
<span class="flex items-center gap-1 protip">
<ng-container *ngTemplateOutlet="proTips?.get(proTipIdx) || null"></ng-container>
</span>
</div>

View file

@ -39,6 +39,7 @@ const freeTextSearchFields: (keyof Partial<NetqueryConnection>)[] = [
'as_owner',
'path',
'profile_name',
'remote_ip'
]
const groupByKeys: (keyof Partial<NetqueryConnection>)[] = [

View file

@ -43,7 +43,7 @@ export class Lexer {
}
/** reads a number token */
private readNumber(): Token<TokenType.NUMBER> {
private readNumber(): Token<TokenType.NUMBER> | null {
const start = this._input.pos;
let has_dot = false;
@ -59,9 +59,10 @@ export class Lexer {
return isDigit(ch);
});
if (!this._input.eof() && isIdentChar(this._input.peek())) {
this._input.revert(number.length + 1);
this._input.croak("invalid number character")
if (!this._input.eof() && !isWhitespace(this._input.peek())) {
this._input.revert(number.length);
return null;
}
return {
@ -182,13 +183,11 @@ export class Lexer {
return this.readString('\'', true);
}
try {
if (isDigit(ch)) {
return this.readNumber();
if (isDigit(ch)) {
const number = this.readNumber();
if (number !== null) {
return number;
}
} catch (err) {
// we ignore that error here as it may only happen for unqoted strings
// that start with a number.
}
if (ch === ':') {

View file

@ -7,6 +7,8 @@
@apply capitalize;
@apply rounded-sm;
@apply font-medium;
@apply focus:underline focus:underline-offset-4;
user-select: none;
outline: none;
cursor: pointer;

View file

@ -1,153 +0,0 @@
{
"extends": "tslint:recommended",
"rules": {
"align": {
"options": [
"parameters",
"statements"
]
},
"array-type": false,
"arrow-return-shorthand": true,
"curly": true,
"deprecation": {
"severity": "warning"
},
"component-class-suffix": true,
"contextual-lifecycle": true,
"directive-class-suffix": true,
"directive-selector": [
true,
"attribute",
"app",
"camelCase"
],
"component-selector": [
true,
"element",
"app",
"kebab-case"
],
"eofline": true,
"import-blacklist": [
true,
"rxjs/Rx"
],
"import-spacing": true,
"indent": {
"options": [
"spaces"
]
},
"max-classes-per-file": false,
"max-line-length": [
true,
140
],
"member-ordering": [
true,
{
"order": [
"static-field",
"instance-field",
"static-method",
"instance-method"
]
}
],
"no-any": true,
"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"
],
"quotemark": [
true,
"single"
],
"semicolon": {
"options": [
"always"
]
},
"space-before-function-paren": {
"options": {
"anonymous": "never",
"asyncArrow": "always",
"constructor": "never",
"method": "never",
"named": "never"
}
},
"typedef": [
true,
"call-signature"
],
"typedef-whitespace": {
"options": [
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
]
},
"variable-name": {
"options": [
"ban-keywords",
"check-format",
"allow-pascal-case"
]
},
"whitespace": {
"options": [
"check-branch",
"check-decl",
"check-operator",
"check-separator",
"check-type",
"check-typecast"
]
},
"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
},
"rulesDirectory": [
"codelyzer"
]
}