mirror of
https://github.com/pi-hole/web.git
synced 2026-04-02 00:27:23 +01:00
Merge development into new/simple-dhcp-static-leases and address review feedback
Resolve merge conflict in style/pi-hole.css (keep both StaticDHCPTable styles and DNSSEC query log styles). Address outstanding reviewer feedback: - Change save button icon from floppy-disk to checkmark to clarify it confirms the row edit, not a final save - Update hint text to mention "Save & Apply" is still needed - Add hostname validation on the hostname cell (rejects spaces, commas, and other characters invalid in DNS names) Signed-off-by: Dominik <dl6er@dl6er.de>
This commit is contained in:
8
.github/workflows/codeql.yml
vendored
8
.github/workflows/codeql.yml
vendored
@@ -26,21 +26,21 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3.29.2
|
uses: github/codeql-action/init@16140ae1a102900babc80a33c44059580f687047 #v4.30.9
|
||||||
with:
|
with:
|
||||||
config-file: ./.github/codeql/codeql-config.yml
|
config-file: ./.github/codeql/codeql-config.yml
|
||||||
languages: "javascript"
|
languages: "javascript"
|
||||||
queries: +security-and-quality
|
queries: +security-and-quality
|
||||||
|
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v3.29.2
|
uses: github/codeql-action/autobuild@16140ae1a102900babc80a33c44059580f687047 #v4.30.9
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3.29.2
|
uses: github/codeql-action/analyze@16140ae1a102900babc80a33c44059580f687047 #v4.30.9
|
||||||
with:
|
with:
|
||||||
category: "/language:javascript"
|
category: "/language:javascript"
|
||||||
|
|||||||
4
.github/workflows/codespell.yml
vendored
4
.github/workflows/codespell.yml
vendored
@@ -13,12 +13,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Spell-Checking
|
- name: Spell-Checking
|
||||||
uses: codespell-project/actions-codespell@master
|
uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 #v2.1
|
||||||
with:
|
with:
|
||||||
ignore_words_file: .codespellignore
|
ignore_words_file: .codespellignore
|
||||||
skip: ./vendor,./package.json,./package-lock.json
|
skip: ./vendor,./package.json,./package-lock.json
|
||||||
|
|||||||
4
.github/workflows/editorconfig-checker.yml
vendored
4
.github/workflows/editorconfig-checker.yml
vendored
@@ -10,8 +10,8 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- uses: editorconfig-checker/action-editorconfig-checker@main
|
- uses: editorconfig-checker/action-editorconfig-checker@5ecdd656fe347c26f76b1b435b90e1d74fb5e787 # tag v2. is really out of date
|
||||||
- run: editorconfig-checker
|
- run: editorconfig-checker
|
||||||
|
|||||||
2
.github/workflows/merge-conflict.yml
vendored
2
.github/workflows/merge-conflict.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check if PRs are have merge conflicts
|
- name: Check if PRs are have merge conflicts
|
||||||
uses: eps1lon/actions-label-merge-conflict@v3.0.3
|
uses: eps1lon/actions-label-merge-conflict@1df065ebe6e3310545d4f4c4e862e43bdca146f0 #v3.0.3
|
||||||
with:
|
with:
|
||||||
dirtyLabel: "Merge Conflicts"
|
dirtyLabel: "Merge Conflicts"
|
||||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|||||||
4
.github/workflows/stale.yml
vendored
4
.github/workflows/stale.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
issues: write
|
issues: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9.1.0
|
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 #v10.1.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
days-before-stale: 30
|
days-before-stale: 30
|
||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Remove 'stale' label
|
- name: Remove 'stale' label
|
||||||
|
|||||||
2
.github/workflows/stale_pr.yml
vendored
2
.github/workflows/stale_pr.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
pull-requests: write
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/stale@v9.1.0
|
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 #v10.1.0
|
||||||
with:
|
with:
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# Do not automatically mark PR/issue as stale
|
# Do not automatically mark PR/issue as stale
|
||||||
|
|||||||
2
.github/workflows/sync-back-to-dev.yml
vendored
2
.github/workflows/sync-back-to-dev.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
name: Syncing branches
|
name: Syncing branches
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
- name: Opening pull request
|
- name: Opening pull request
|
||||||
|
|||||||
4
.github/workflows/test.yml
vendored
4
.github/workflows/test.yml
vendored
@@ -19,12 +19,12 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Clone repository
|
- name: Clone repository
|
||||||
uses: actions/checkout@v4.2.2
|
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4.4.0
|
uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903 #v6.0.0
|
||||||
with:
|
with:
|
||||||
node-version: "22.x"
|
node-version: "22.x"
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|||||||
@@ -9,14 +9,15 @@
|
|||||||
|
|
||||||
mg.include('scripts/lua/header.lp','r')
|
mg.include('scripts/lua/header.lp','r')
|
||||||
?>
|
?>
|
||||||
<body class="hold-transition layout-boxed login-page page-<?=pihole.format_path(mg.request_info.request_uri)?>">
|
</head>
|
||||||
|
<body class="hold-transition layout-boxed login-page page-<?=pihole.format_path(scriptname)?>">
|
||||||
<div class="box login-box">
|
<div class="box login-box">
|
||||||
<section style="padding: 15px;">
|
<section style="padding: 15px;">
|
||||||
<h2 class="error-headline text-danger">403</h2>
|
<h2 class="error-headline text-danger">403</h2>
|
||||||
<div class="error-content">
|
<div class="error-content">
|
||||||
<h3><i class="fa fa-times-circle text-danger"></i> Oops! Access denied.</h3>
|
<h3><i class="fa fa-times-circle text-danger"></i> Oops! Access denied.</h3>
|
||||||
<p>
|
<p>
|
||||||
You don't have permission to access <code><?=mg.request_info.request_uri?></code> on this server.<br>
|
You don't have permission to access this URL.<br>
|
||||||
Did you mean to go to <a href="<?=pihole.webhome()?>">your Pi-hole's dashboard</a> instead?
|
Did you mean to go to <a href="<?=pihole.webhome()?>">your Pi-hole's dashboard</a> instead?
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
mg.include('scripts/lua/header.lp','r')
|
mg.include('scripts/lua/header.lp','r')
|
||||||
?>
|
?>
|
||||||
<body class="hold-transition layout-boxed login-page page-<?=pihole.format_path(mg.request_info.request_uri)?>">
|
</head>
|
||||||
|
<body class="hold-transition layout-boxed login-page page-<?=pihole.format_path(scriptname)?>">
|
||||||
<div class="box login-box">
|
<div class="box login-box">
|
||||||
<section style="padding: 15px;">
|
<section style="padding: 15px;">
|
||||||
<h2 class="error-headline text-yellow">404</h2>
|
<h2 class="error-headline text-yellow">404</h2>
|
||||||
|
|||||||
13
login.lp
13
login.lp
@@ -9,7 +9,8 @@
|
|||||||
|
|
||||||
mg.include('scripts/lua/header.lp','r')
|
mg.include('scripts/lua/header.lp','r')
|
||||||
?>
|
?>
|
||||||
<body class="hold-transition layout-boxed login-page page-<?=pihole.format_path(mg.request_info.request_uri)?>" data-apiurl="<?=pihole.api_url()?>" data-webhome="<?=webhome?>">
|
</head>
|
||||||
|
<body class="hold-transition layout-boxed login-page page-<?=pihole.format_path(scriptname)?>" data-apiurl="<?=pihole.api_url()?>" data-webhome="<?=webhome?>">
|
||||||
<div class="box login-box" id="login-box">
|
<div class="box login-box" id="login-box">
|
||||||
<section style="padding: 15px;">
|
<section style="padding: 15px;">
|
||||||
<div class="login-logo">
|
<div class="login-logo">
|
||||||
@@ -50,9 +51,13 @@ mg.include('scripts/lua/header.lp','r')
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group has-feedback hidden" id="totp_input">
|
<div class="form-group hidden" id="totp_input">
|
||||||
<input type="text" id="totp" size="6" maxlen="6" class="form-control totp_token" placeholder="123456" value="" spellcheck="false" autofocus autocomplete="off">
|
<div class="input-group">
|
||||||
<span class="fa fa-clock-rotate-left pwd-field form-control-feedback"></span>
|
<input type="text" id="totp" size="6" maxlen="6" class="form-control totp_token" placeholder="123456" value="" spellcheck="false" autofocus autocomplete="off">
|
||||||
|
<div class="input-group-addon" data-toggle="tooltip" data-placement="auto" title="TOTP verification code">
|
||||||
|
<i class="fa fa-clock-rotate-left"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<button type="submit" class="btn btn-primary form-control"><i class="fas fa-sign-in-alt"></i> Log in (uses cookie)</button>
|
<button type="submit" class="btn btn-primary form-control"><i class="fas fa-sign-in-alt"></i> Log in (uses cookie)</button>
|
||||||
|
|||||||
235
package-lock.json
generated
235
package-lock.json
generated
@@ -37,13 +37,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"eslint": "^9.31.0",
|
"eslint": "^9.38.0",
|
||||||
"eslint-plugin-compat": "^6.0.2",
|
"eslint-plugin-compat": "^6.0.2",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.4.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"postcss-cli": "^11.0.1",
|
"postcss-cli": "^11.0.1",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"xo": "^1.1.1"
|
"xo": "^1.2.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/code-frame": {
|
"node_modules/@babel/code-frame": {
|
||||||
@@ -126,9 +126,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.7.0",
|
"version": "4.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
|
||||||
"integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==",
|
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -168,13 +168,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/config-array": {
|
"node_modules/@eslint/config-array": {
|
||||||
"version": "0.21.0",
|
"version": "0.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz",
|
||||||
"integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
|
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/object-schema": "^2.1.6",
|
"@eslint/object-schema": "^2.1.7",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"minimatch": "^3.1.2"
|
"minimatch": "^3.1.2"
|
||||||
},
|
},
|
||||||
@@ -183,19 +183,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/config-helpers": {
|
"node_modules/@eslint/config-helpers": {
|
||||||
"version": "0.3.0",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz",
|
||||||
"integrity": "sha512-ViuymvFmcJi04qdZeDc2whTHryouGcDlaxPqarTD0ZE10ISpxGUVZGZDx4w01upyIynL3iu6IXH2bS1NhclQMw==",
|
"integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@eslint/core": "^0.16.0"
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/core": {
|
"node_modules/@eslint/core": {
|
||||||
"version": "0.15.1",
|
"version": "0.16.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.1.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz",
|
||||||
"integrity": "sha512-bkOp+iumZCCbt1K1CmWf0R9pM5yKpDv+ZXtvSyQpudrI9kuFLp+bM2WOPXImuD/ceQuaa8f5pj93Y7zyECIGNA==",
|
"integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -243,9 +246,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/js": {
|
"node_modules/@eslint/js": {
|
||||||
"version": "9.31.0",
|
"version": "9.38.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.31.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz",
|
||||||
"integrity": "sha512-LOm5OVt7D4qiKCqoiPbA7LWmI+tbw1VbTUowBcUMgQSuM6poJufkFkYDcQpo5KfgD39TnNySV26QjOh7VFpSyw==",
|
"integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -256,9 +259,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/object-schema": {
|
"node_modules/@eslint/object-schema": {
|
||||||
"version": "2.1.6",
|
"version": "2.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
|
||||||
"integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
|
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -266,13 +269,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@eslint/plugin-kit": {
|
"node_modules/@eslint/plugin-kit": {
|
||||||
"version": "0.3.3",
|
"version": "0.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz",
|
||||||
"integrity": "sha512-1+WqvgNMhmlAambTvT3KPtCl/Ibr68VldY2XY40SL1CE0ZXiakFR/cbTspaF5HsnpDMvcYYoJHfl4980NBjGag==",
|
"integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint/core": "^0.15.1",
|
"@eslint/core": "^0.16.0",
|
||||||
"levn": "^0.4.1"
|
"levn": "^0.4.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -563,17 +566,17 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.37.0.tgz",
|
||||||
"integrity": "sha512-ijItUYaiWuce0N1SoSMrEd0b6b6lYkYt99pqCPfybd+HKVXtEvYhICfLdwp42MhiI5mp0oq7PKEL+g1cNiz/Eg==",
|
"integrity": "sha512-jsuVWeIkb6ggzB+wPCsR4e6loj+rM72ohW6IBn2C+5NCvfUVY8s33iFPySSVXqtm5Hu29Ne/9bnA0JmyLmgenA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "8.35.0",
|
"@typescript-eslint/scope-manager": "8.37.0",
|
||||||
"@typescript-eslint/type-utils": "8.35.0",
|
"@typescript-eslint/type-utils": "8.37.0",
|
||||||
"@typescript-eslint/utils": "8.35.0",
|
"@typescript-eslint/utils": "8.37.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.35.0",
|
"@typescript-eslint/visitor-keys": "8.37.0",
|
||||||
"graphemer": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^7.0.0",
|
"ignore": "^7.0.0",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
@@ -587,7 +590,7 @@
|
|||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@typescript-eslint/parser": "^8.35.0",
|
"@typescript-eslint/parser": "^8.37.0",
|
||||||
"eslint": "^8.57.0 || ^9.0.0",
|
"eslint": "^8.57.0 || ^9.0.0",
|
||||||
"typescript": ">=4.8.4 <5.9.0"
|
"typescript": ">=4.8.4 <5.9.0"
|
||||||
}
|
}
|
||||||
@@ -603,16 +606,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.37.0.tgz",
|
||||||
"integrity": "sha512-6sMvZePQrnZH2/cJkwRpkT7DxoAWh+g6+GFRK6bV3YQo7ogi3SX5rgF6099r5Q53Ma5qeT7LGmOmuIutF4t3lA==",
|
"integrity": "sha512-kVIaQE9vrN9RLCQMQ3iyRlVJpTiDUY6woHGb30JDkfJErqrQEmtdWH3gV0PBAfGZgQXoqzXOO0T3K6ioApbbAA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.35.0",
|
"@typescript-eslint/scope-manager": "8.37.0",
|
||||||
"@typescript-eslint/types": "8.35.0",
|
"@typescript-eslint/types": "8.37.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.35.0",
|
"@typescript-eslint/typescript-estree": "8.37.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.35.0",
|
"@typescript-eslint/visitor-keys": "8.37.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -628,14 +631,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/project-service": {
|
"node_modules/@typescript-eslint/project-service": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.37.0.tgz",
|
||||||
"integrity": "sha512-41xatqRwWZuhUMF/aZm2fcUsOFKNcG28xqRSS6ZVr9BVJtGExosLAm5A1OxTjRMagx8nJqva+P5zNIGt8RIgbQ==",
|
"integrity": "sha512-BIUXYsbkl5A1aJDdYJCBAo8rCEbAvdquQ8AnLb6z5Lp1u3x5PNgSSx9A/zqYc++Xnr/0DVpls8iQ2cJs/izTXA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/tsconfig-utils": "^8.35.0",
|
"@typescript-eslint/tsconfig-utils": "^8.37.0",
|
||||||
"@typescript-eslint/types": "^8.35.0",
|
"@typescript-eslint/types": "^8.37.0",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -650,14 +653,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.37.0.tgz",
|
||||||
"integrity": "sha512-+AgL5+mcoLxl1vGjwNfiWq5fLDZM1TmTPYs2UkyHfFhgERxBbqHlNjRzhThJqz+ktBqTChRYY6zwbMwy0591AA==",
|
"integrity": "sha512-0vGq0yiU1gbjKob2q691ybTg9JX6ShiVXAAfm2jGf3q0hdP6/BruaFjL/ManAR/lj05AvYCH+5bbVo0VtzmjOA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.35.0",
|
"@typescript-eslint/types": "8.37.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.35.0"
|
"@typescript-eslint/visitor-keys": "8.37.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -668,9 +671,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.37.0.tgz",
|
||||||
"integrity": "sha512-04k/7247kZzFraweuEirmvUj+W3bJLI9fX6fbo1Qm2YykuBvEhRTPl8tcxlYO8kZZW+HIXfkZNoasVb8EV4jpA==",
|
"integrity": "sha512-1/YHvAVTimMM9mmlPvTec9NP4bobA1RkDbMydxG8omqwJJLEW/Iy2C4adsAESIXU3WGLXFHSZUU+C9EoFWl4Zg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -685,14 +688,15 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.37.0.tgz",
|
||||||
"integrity": "sha512-ceNNttjfmSEoM9PW87bWLDEIaLAyR+E6BoYJQ5PfaDau37UGca9Nyq3lBk8Bw2ad0AKvYabz6wxc7DMTO2jnNA==",
|
"integrity": "sha512-SPkXWIkVZxhgwSwVq9rqj/4VFo7MnWwVaRNznfQDc/xPYHjXnPfLWn+4L6FF1cAz6e7dsqBeMawgl7QjUMj4Ow==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "8.35.0",
|
"@typescript-eslint/types": "8.37.0",
|
||||||
"@typescript-eslint/utils": "8.35.0",
|
"@typescript-eslint/typescript-estree": "8.37.0",
|
||||||
|
"@typescript-eslint/utils": "8.37.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ts-api-utils": "^2.1.0"
|
"ts-api-utils": "^2.1.0"
|
||||||
},
|
},
|
||||||
@@ -709,9 +713,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.37.0.tgz",
|
||||||
"integrity": "sha512-0mYH3emanku0vHw2aRLNGqe7EXh9WHEhi7kZzscrMDf6IIRUQ5Jk4wp1QrledE/36KtdZrVfKnE32eZCf/vaVQ==",
|
"integrity": "sha512-ax0nv7PUF9NOVPs+lmQ7yIE7IQmAf8LGcXbMvHX5Gm+YJUYNAl340XkGnrimxZ0elXyoQJuN5sbg6C4evKA4SQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -723,16 +727,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.37.0.tgz",
|
||||||
"integrity": "sha512-F+BhnaBemgu1Qf8oHrxyw14wq6vbL8xwWKKMwTMwYIRmFFY/1n/9T/jpbobZL8vp7QyEUcC6xGrnAO4ua8Kp7w==",
|
"integrity": "sha512-zuWDMDuzMRbQOM+bHyU4/slw27bAUEcKSKKs3hcv2aNnc/tvE/h7w60dwVw8vnal2Pub6RT1T7BI8tFZ1fE+yg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/project-service": "8.35.0",
|
"@typescript-eslint/project-service": "8.37.0",
|
||||||
"@typescript-eslint/tsconfig-utils": "8.35.0",
|
"@typescript-eslint/tsconfig-utils": "8.37.0",
|
||||||
"@typescript-eslint/types": "8.35.0",
|
"@typescript-eslint/types": "8.37.0",
|
||||||
"@typescript-eslint/visitor-keys": "8.35.0",
|
"@typescript-eslint/visitor-keys": "8.37.0",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
@@ -778,16 +782,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.37.0.tgz",
|
||||||
"integrity": "sha512-nqoMu7WWM7ki5tPgLVsmPM8CkqtoPUG6xXGeefM5t4x3XumOEKMoUZPdi+7F+/EotukN4R9OWdmDxN80fqoZeg==",
|
"integrity": "sha512-TSFvkIW6gGjN2p6zbXo20FzCABbyUAuq6tBvNRGsKdsSQ6a7rnV6ADfZ7f4iI3lIiXc4F4WWvtUfDw9CJ9pO5A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.7.0",
|
"@eslint-community/eslint-utils": "^4.7.0",
|
||||||
"@typescript-eslint/scope-manager": "8.35.0",
|
"@typescript-eslint/scope-manager": "8.37.0",
|
||||||
"@typescript-eslint/types": "8.35.0",
|
"@typescript-eslint/types": "8.37.0",
|
||||||
"@typescript-eslint/typescript-estree": "8.35.0"
|
"@typescript-eslint/typescript-estree": "8.37.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -802,13 +806,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.37.0.tgz",
|
||||||
"integrity": "sha512-zTh2+1Y8ZpmeQaQVIc/ZZxsx8UzgKJyNg1PTvjzC7WMhPSVS8bfDX34k1SrwOf016qd5RU3az2UxUNue3IfQ5g==",
|
"integrity": "sha512-YzfhzcTnZVPiLfP/oeKtDp2evwvHLMe0LOy7oe+hb9KKIumLNohYS9Hgp1ifwpu42YWxhZE8yieggz6JpqO/1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.35.0",
|
"@typescript-eslint/types": "8.37.0",
|
||||||
"eslint-visitor-keys": "^4.2.1"
|
"eslint-visitor-keys": "^4.2.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3161,25 +3165,24 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint": {
|
"node_modules/eslint": {
|
||||||
"version": "9.31.0",
|
"version": "9.38.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.31.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz",
|
||||||
"integrity": "sha512-QldCVh/ztyKJJZLr4jXNUByx3gR+TDYZCRXEktiZoUR3PGy4qCmSbkxcIle8GEwGpb5JBZazlaJ/CxLidXdEbQ==",
|
"integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.2.0",
|
"@eslint-community/eslint-utils": "^4.8.0",
|
||||||
"@eslint-community/regexpp": "^4.12.1",
|
"@eslint-community/regexpp": "^4.12.1",
|
||||||
"@eslint/config-array": "^0.21.0",
|
"@eslint/config-array": "^0.21.1",
|
||||||
"@eslint/config-helpers": "^0.3.0",
|
"@eslint/config-helpers": "^0.4.1",
|
||||||
"@eslint/core": "^0.15.0",
|
"@eslint/core": "^0.16.0",
|
||||||
"@eslint/eslintrc": "^3.3.1",
|
"@eslint/eslintrc": "^3.3.1",
|
||||||
"@eslint/js": "9.31.0",
|
"@eslint/js": "9.38.0",
|
||||||
"@eslint/plugin-kit": "^0.3.1",
|
"@eslint/plugin-kit": "^0.4.0",
|
||||||
"@humanfs/node": "^0.16.6",
|
"@humanfs/node": "^0.16.6",
|
||||||
"@humanwhocodes/module-importer": "^1.0.1",
|
"@humanwhocodes/module-importer": "^1.0.1",
|
||||||
"@humanwhocodes/retry": "^0.4.2",
|
"@humanwhocodes/retry": "^0.4.2",
|
||||||
"@types/estree": "^1.0.6",
|
"@types/estree": "^1.0.6",
|
||||||
"@types/json-schema": "^7.0.15",
|
|
||||||
"ajv": "^6.12.4",
|
"ajv": "^6.12.4",
|
||||||
"chalk": "^4.0.0",
|
"chalk": "^4.0.0",
|
||||||
"cross-spawn": "^7.0.6",
|
"cross-spawn": "^7.0.6",
|
||||||
@@ -3632,14 +3635,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-n": {
|
"node_modules/eslint-plugin-n": {
|
||||||
"version": "17.20.0",
|
"version": "17.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.20.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-17.21.0.tgz",
|
||||||
"integrity": "sha512-IRSoatgB/NQJZG5EeTbv/iAx1byOGdbbyhQrNvWdCfTnmPxUT0ao9/eGOeG7ljD8wJBsxwE8f6tES5Db0FRKEw==",
|
"integrity": "sha512-1+iZ8We4ZlwVMtb/DcHG3y5/bZOdazIpa/4TySo22MLKdwrLcfrX0hbadnCvykSQCCmkAnWmIP8jZVb2AAq29A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.5.0",
|
"@eslint-community/eslint-utils": "^4.5.0",
|
||||||
"@typescript-eslint/utils": "^8.26.1",
|
|
||||||
"enhanced-resolve": "^5.17.1",
|
"enhanced-resolve": "^5.17.1",
|
||||||
"eslint-plugin-es-x": "^7.8.0",
|
"eslint-plugin-es-x": "^7.8.0",
|
||||||
"get-tsconfig": "^4.8.1",
|
"get-tsconfig": "^4.8.1",
|
||||||
@@ -4623,9 +4625,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/globals": {
|
"node_modules/globals": {
|
||||||
"version": "16.3.0",
|
"version": "16.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-16.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
|
||||||
"integrity": "sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==",
|
"integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -8315,9 +8317,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-declaration-location/node_modules/picomatch": {
|
"node_modules/ts-declaration-location/node_modules/picomatch": {
|
||||||
"version": "4.0.2",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
|
||||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -8466,15 +8468,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript-eslint": {
|
"node_modules/typescript-eslint": {
|
||||||
"version": "8.35.0",
|
"version": "8.37.0",
|
||||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.37.0.tgz",
|
||||||
"integrity": "sha512-uEnz70b7kBz6eg/j0Czy6K5NivaYopgxRjsnAJ2Fx5oTLo3wefTHIbL7AkQr1+7tJCRVpTs/wiM8JR/11Loq9A==",
|
"integrity": "sha512-TnbEjzkE9EmcO0Q2zM+GE8NQLItNAJpMmED1BdgoBMYNdqMhzlbqfdSwiRlAzEK2pA9UzVW0gzaaIzXWg2BjfA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "8.35.0",
|
"@typescript-eslint/eslint-plugin": "8.37.0",
|
||||||
"@typescript-eslint/parser": "8.35.0",
|
"@typescript-eslint/parser": "8.37.0",
|
||||||
"@typescript-eslint/utils": "8.35.0"
|
"@typescript-eslint/typescript-estree": "8.37.0",
|
||||||
|
"@typescript-eslint/utils": "8.37.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -8876,43 +8879,43 @@
|
|||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
"node_modules/xo": {
|
"node_modules/xo": {
|
||||||
"version": "1.1.1",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/xo/-/xo-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/xo/-/xo-1.2.3.tgz",
|
||||||
"integrity": "sha512-CMuUby6vSP+OQyOQRbhqWWIfc1dg06M6MFdtIQh/EMNE+ONcBzDhzNnbtDt/qD9gGRdg5qZ9YK16BBGwOfA2BQ==",
|
"integrity": "sha512-ykvWr88620CwealQwr7nWcPwolE6RMAVsCSBIdF3JnVdQUBAllnBJypSPsu0YYFzWTrJjQfNgH82lnWMPVTXnA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
|
"@eslint-community/eslint-plugin-eslint-comments": "^4.5.0",
|
||||||
"@sindresorhus/tsconfig": "^7.0.0",
|
"@sindresorhus/tsconfig": "^7.0.0",
|
||||||
"@stylistic/eslint-plugin": "^4.2.0",
|
"@stylistic/eslint-plugin": "^4.2.0",
|
||||||
"@typescript-eslint/parser": "^8.32.1",
|
"@typescript-eslint/parser": "^8.37.0",
|
||||||
"arrify": "^3.0.0",
|
"arrify": "^3.0.0",
|
||||||
"cosmiconfig": "^9.0.0",
|
"cosmiconfig": "^9.0.0",
|
||||||
"define-lazy-prop": "^3.0.0",
|
"define-lazy-prop": "^3.0.0",
|
||||||
"eslint": "^9.27.0",
|
"eslint": "^9.31.0",
|
||||||
"eslint-config-prettier": "^10.1.5",
|
"eslint-config-prettier": "^10.1.5",
|
||||||
"eslint-config-xo-react": "^0.28.0",
|
"eslint-config-xo-react": "^0.28.0",
|
||||||
"eslint-config-xo-typescript": "^7.0.0",
|
"eslint-config-xo-typescript": "^7.0.0",
|
||||||
"eslint-formatter-pretty": "^6.0.1",
|
"eslint-formatter-pretty": "^6.0.1",
|
||||||
"eslint-plugin-ava": "^15.0.1",
|
"eslint-plugin-ava": "^15.0.1",
|
||||||
"eslint-plugin-import-x": "^4.12.2",
|
"eslint-plugin-import-x": "^4.16.1",
|
||||||
"eslint-plugin-n": "^17.18.0",
|
"eslint-plugin-n": "^17.21.0",
|
||||||
"eslint-plugin-no-use-extend-native": "^0.7.2",
|
"eslint-plugin-no-use-extend-native": "^0.7.2",
|
||||||
"eslint-plugin-prettier": "^5.4.0",
|
"eslint-plugin-prettier": "^5.5.1",
|
||||||
"eslint-plugin-promise": "^7.2.1",
|
"eslint-plugin-promise": "^7.2.1",
|
||||||
"eslint-plugin-unicorn": "^59.0.1",
|
"eslint-plugin-unicorn": "^59.0.1",
|
||||||
"find-cache-directory": "^6.0.0",
|
"find-cache-directory": "^6.0.0",
|
||||||
"get-stdin": "^9.0.0",
|
"get-stdin": "^9.0.0",
|
||||||
"get-tsconfig": "^4.10.1",
|
"get-tsconfig": "^4.10.1",
|
||||||
"globals": "^16.1.0",
|
"globals": "^16.3.0",
|
||||||
"globby": "^14.1.0",
|
"globby": "^14.1.0",
|
||||||
"meow": "^13.2.0",
|
"meow": "^13.2.0",
|
||||||
"micromatch": "^4.0.8",
|
"micromatch": "^4.0.8",
|
||||||
"open-editor": "^5.1.0",
|
"open-editor": "^5.1.0",
|
||||||
"path-exists": "^5.0.0",
|
"path-exists": "^5.0.0",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.6.2",
|
||||||
"type-fest": "^4.41.0",
|
"type-fest": "^4.41.0",
|
||||||
"typescript-eslint": "^8.32.1"
|
"typescript-eslint": "^8.37.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"xo": "dist/cli.js"
|
"xo": "dist/cli.js"
|
||||||
|
|||||||
@@ -53,13 +53,13 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"eslint": "^9.31.0",
|
"eslint": "^9.38.0",
|
||||||
"eslint-plugin-compat": "^6.0.2",
|
"eslint-plugin-compat": "^6.0.2",
|
||||||
"globals": "^16.3.0",
|
"globals": "^16.4.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"postcss-cli": "^11.0.1",
|
"postcss-cli": "^11.0.1",
|
||||||
"prettier": "^3.6.2",
|
"prettier": "^3.6.2",
|
||||||
"xo": "^1.1.1"
|
"xo": "^1.2.3"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
">= 0.5%",
|
">= 0.5%",
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ mg.include('scripts/lua/header_authenticated.lp','r')
|
|||||||
</div>
|
</div>
|
||||||
<!-- /.box-body -->
|
<!-- /.box-body -->
|
||||||
<div class="box-footer clearfix">
|
<div class="box-footer clearfix">
|
||||||
<span class="pull-left">* These input fields allow manual input as well. Use <code>*</code> for wildcard search.</span>
|
<span class="pull-left">* These input fields allow manual input as well. Use <code>*</code> for wildcard search. An <code>_</code> can be used as a single-character wildcard. If you want to search for <code>_</code> explicitly, then you must escape it like <code>\_</code></span>
|
||||||
<span class="pull-right">Click "Refresh" below to apply.</span>
|
<span class="pull-right">Click "Refresh" below to apply.</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- /.box -->
|
<!-- /.box -->
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global upstreams:false */
|
/* global upstreamIPs:false */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
@@ -63,6 +63,23 @@ globalThis.htmlLegendPlugin = {
|
|||||||
for (const item of items) {
|
for (const item of items) {
|
||||||
const li = document.createElement("li");
|
const li = document.createElement("li");
|
||||||
|
|
||||||
|
// Select the corresponding "slice" of the chart when the mouse is over a legend item
|
||||||
|
li.addEventListener("mouseover", () => {
|
||||||
|
chart.setActiveElements([
|
||||||
|
{
|
||||||
|
datasetIndex: 0,
|
||||||
|
index: item.index,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
chart.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Deselect all "slices"
|
||||||
|
li.addEventListener("mouseout", () => {
|
||||||
|
chart.setActiveElements([]);
|
||||||
|
chart.update();
|
||||||
|
});
|
||||||
|
|
||||||
// Color checkbox (toggle visibility)
|
// Color checkbox (toggle visibility)
|
||||||
const boxSpan = document.createElement("span");
|
const boxSpan = document.createElement("span");
|
||||||
boxSpan.title = "Toggle visibility";
|
boxSpan.title = "Toggle visibility";
|
||||||
@@ -96,9 +113,19 @@ globalThis.htmlLegendPlugin = {
|
|||||||
|
|
||||||
if (isQueryTypeChart) {
|
if (isQueryTypeChart) {
|
||||||
link.href = `queries?type=${item.text}`;
|
link.href = `queries?type=${item.text}`;
|
||||||
} else if (isForwardDestinationChart) {
|
} else {
|
||||||
// Encode the forward destination as it may contain an "#" character
|
// Encode the forward destination as it may contain an "#" character
|
||||||
link.href = `queries?upstream=${encodeURIComponent(upstreams[item.text])}`;
|
link.href = `queries?upstream=${encodeURIComponent(upstreamIPs[item.index])}`;
|
||||||
|
|
||||||
|
// If server name and IP are different:
|
||||||
|
if (item.text !== upstreamIPs[item.index]) {
|
||||||
|
// replace the title tooltip to include the upstream IP to the text ...
|
||||||
|
link.title = `List ${item.text} (${upstreamIPs[item.index]}) queries`;
|
||||||
|
|
||||||
|
// ... and include the server name (without port) to the querystring, to match
|
||||||
|
// the text used on the SELECT element (sent by suggestions API endpoint)
|
||||||
|
link.href += ` (${item.text.split("#")[0]})`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no clickable links in other charts
|
// no clickable links in other charts
|
||||||
@@ -233,6 +260,10 @@ function positionTooltip(tooltipEl, tooltip, context) {
|
|||||||
const arrowMinIndent = 2 * tooltip.options.cornerRadius;
|
const arrowMinIndent = 2 * tooltip.options.cornerRadius;
|
||||||
const arrowSize = 5;
|
const arrowSize = 5;
|
||||||
|
|
||||||
|
// Check if this is a queryOverTimeChart or clientsChart - these should stick to x-axis
|
||||||
|
const canvasId = context.chart.canvas.id;
|
||||||
|
const isTimelineChart = canvasId === "queryOverTimeChart" || canvasId === "clientsChart";
|
||||||
|
|
||||||
let tooltipX = offsetX + caretX;
|
let tooltipX = offsetX + caretX;
|
||||||
let arrowX;
|
let arrowX;
|
||||||
|
|
||||||
@@ -289,27 +320,37 @@ function positionTooltip(tooltipEl, tooltip, context) {
|
|||||||
arrowX = offsetX + caretX - tooltipX;
|
arrowX = offsetX + caretX - tooltipX;
|
||||||
}
|
}
|
||||||
|
|
||||||
let tooltipY = offsetY + caretY;
|
let tooltipY;
|
||||||
|
|
||||||
// Compute Y position
|
if (isTimelineChart) {
|
||||||
switch (tooltip.yAlign) {
|
// For timeline charts, always position tooltip below the chart with caret pointing to x-axis
|
||||||
case "top": {
|
const chartArea = context.chart.chartArea;
|
||||||
tooltipY += arrowSize + caretPadding;
|
const canvasBottom = chartArea.bottom;
|
||||||
break;
|
tooltipY = offsetY + canvasBottom + arrowSize + caretPadding;
|
||||||
}
|
|
||||||
|
|
||||||
case "center": {
|
// Ensure the arrow points to the correct X position
|
||||||
tooltipY -= tooltipHeight / 2;
|
arrowX = tooltip.caretX - (tooltipX - offsetX);
|
||||||
if (tooltip.xAlign === "left") tooltipX += arrowSize;
|
} else {
|
||||||
if (tooltip.xAlign === "right") tooltipX -= arrowSize;
|
tooltipY = offsetY + caretY;
|
||||||
break;
|
switch (tooltip.yAlign) {
|
||||||
}
|
case "top": {
|
||||||
|
tooltipY += arrowSize + caretPadding;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case "bottom": {
|
case "center": {
|
||||||
tooltipY -= tooltipHeight + arrowSize + caretPadding;
|
tooltipY -= tooltipHeight / 2;
|
||||||
break;
|
if (tooltip.xAlign === "left") tooltipX += arrowSize;
|
||||||
|
if (tooltip.xAlign === "right") tooltipX -= arrowSize;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "bottom": {
|
||||||
|
tooltipY -= tooltipHeight + arrowSize + caretPadding;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// No default
|
||||||
}
|
}
|
||||||
// No default
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Position tooltip and display
|
// Position tooltip and display
|
||||||
|
|||||||
@@ -241,28 +241,26 @@ function updateFtlInfo() {
|
|||||||
$("#num_lists").text(intl.format(database.lists));
|
$("#num_lists").text(intl.format(database.lists));
|
||||||
$("#num_gravity").text(intl.format(database.gravity));
|
$("#num_gravity").text(intl.format(database.gravity));
|
||||||
$("#num_allowed")
|
$("#num_allowed")
|
||||||
.text(intl.format(database.domains.allowed + database.regex.allowed))
|
.text(intl.format(database.domains.allowed.enabled + database.regex.allowed.enabled))
|
||||||
.attr(
|
.attr(
|
||||||
"title",
|
"title",
|
||||||
"Allowed: " +
|
"Allowed: " +
|
||||||
intl.format(database.domains.allowed) +
|
intl.format(database.domains.allowed.enabled) +
|
||||||
" exact domains and " +
|
" exact domains and " +
|
||||||
intl.format(database.regex.allowed) +
|
intl.format(database.regex.allowed.enabled) +
|
||||||
" regex filters are enabled"
|
" regex filters are enabled"
|
||||||
);
|
);
|
||||||
$("#num_denied")
|
$("#num_denied")
|
||||||
.text(intl.format(database.domains.denied + database.regex.denied))
|
.text(intl.format(database.domains.denied.enabled + database.regex.denied.enabled))
|
||||||
.attr(
|
.attr(
|
||||||
"title",
|
"title",
|
||||||
"Denied: " +
|
"Denied: " +
|
||||||
intl.format(database.domains.denied) +
|
intl.format(database.domains.denied.enabled) +
|
||||||
" exact domains and " +
|
" exact domains and " +
|
||||||
intl.format(database.regex.denied) +
|
intl.format(database.regex.denied.enabled) +
|
||||||
" regex filters are enabled"
|
" regex filters are enabled"
|
||||||
);
|
);
|
||||||
updateQueryFrequency(intl, ftl.query_frequency);
|
updateQueryFrequency(intl, ftl.query_frequency);
|
||||||
$("#sysinfo-cpu-ftl").text("(" + ftl["%cpu"].toFixed(1) + "% used by FTL)");
|
|
||||||
$("#sysinfo-ram-ftl").text("(" + ftl["%mem"].toFixed(1) + "% used by FTL)");
|
|
||||||
$("#sysinfo-pid-ftl").text(ftl.pid);
|
$("#sysinfo-pid-ftl").text(ftl.pid);
|
||||||
const startdate = moment()
|
const startdate = moment()
|
||||||
.subtract(ftl.uptime, "milliseconds")
|
.subtract(ftl.uptime, "milliseconds")
|
||||||
@@ -346,15 +344,17 @@ function updateSystemInfo() {
|
|||||||
);
|
);
|
||||||
$("#cpu").prop(
|
$("#cpu").prop(
|
||||||
"title",
|
"title",
|
||||||
"Load averages for the past 1, 5, and 15 minutes\non a system with " +
|
"CPU usage: " +
|
||||||
|
system.cpu["%cpu"].toFixed(1) +
|
||||||
|
"%\nLoad averages for the past 1, 5, and 15 minutes\non a system with " +
|
||||||
system.cpu.nprocs +
|
system.cpu.nprocs +
|
||||||
" core" +
|
" core" +
|
||||||
(system.cpu.nprocs > 1 ? "s" : "") +
|
(system.cpu.nprocs > 1 ? "s" : "") +
|
||||||
" running " +
|
" running " +
|
||||||
system.procs +
|
system.procs +
|
||||||
" processes " +
|
" processes" +
|
||||||
(system.cpu.load.raw[0] > system.cpu.nprocs
|
(system.cpu.load.raw[0] > system.cpu.nprocs
|
||||||
? " (load is higher than the number of cores)"
|
? "\n(load is higher than the number of cores)"
|
||||||
: "")
|
: "")
|
||||||
);
|
);
|
||||||
$("#sysinfo-cpu").text(
|
$("#sysinfo-cpu").text(
|
||||||
@@ -368,6 +368,9 @@ function updateSystemInfo() {
|
|||||||
" processes"
|
" processes"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
$("#sysinfo-cpu-ftl").text("(" + system.ftl["%cpu"].toFixed(1) + "% used by FTL)");
|
||||||
|
$("#sysinfo-ram-ftl").text("(" + system.ftl["%mem"].toFixed(1) + "% used by FTL)");
|
||||||
|
|
||||||
const startdate = moment()
|
const startdate = moment()
|
||||||
.subtract(system.uptime, "seconds")
|
.subtract(system.uptime, "seconds")
|
||||||
.format("dddd, MMMM Do YYYY, HH:mm:ss");
|
.format("dddd, MMMM Do YYYY, HH:mm:ss");
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
* This file is copyright under the latest version of the EUPL.
|
* This file is copyright under the latest version of the EUPL.
|
||||||
* Please see LICENSE file for your rights under this license. */
|
* Please see LICENSE file for your rights under this license. */
|
||||||
|
|
||||||
/* global apiFailure:false */
|
/* global apiFailure:false, utils:false */
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
@@ -89,9 +89,11 @@ function parseLines(outputElement, text) {
|
|||||||
const lines = text.split(/(?=\r)/g);
|
const lines = text.split(/(?=\r)/g);
|
||||||
|
|
||||||
for (let line of lines) {
|
for (let line of lines) {
|
||||||
|
// Escape HTML to prevent XSS attacks (both in adlist URL and non-domain entries)
|
||||||
|
line = utils.escapeHtml(line);
|
||||||
if (line[0] === "\r") {
|
if (line[0] === "\r") {
|
||||||
// This line starts with the "OVER" sequence. Replace them with "\n" before print
|
// This line starts with the "OVER" sequence. Replace them with "\n" before print
|
||||||
line = line.replaceAll("\r[K", "\n").replaceAll("\r", "\n");
|
line = line.replaceAll("\r\u001B[K", "\n").replaceAll("\r", "\n");
|
||||||
|
|
||||||
// Last line from the textarea will be overwritten, so we remove it
|
// Last line from the textarea will be overwritten, so we remove it
|
||||||
const lastLineIndex = outputElement.innerHTML.lastIndexOf("\n");
|
const lastLineIndex = outputElement.innerHTML.lastIndexOf("\n");
|
||||||
@@ -138,7 +140,7 @@ function parseLines(outputElement, text) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Append the new text to the end of the output
|
// Append the new text to the end of the output
|
||||||
outputElement.append(line);
|
outputElement.innerHTML += line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -234,23 +234,20 @@ function initTable() {
|
|||||||
if (data.address.startsWith("file://")) {
|
if (data.address.startsWith("file://")) {
|
||||||
// Local files cannot be downloaded from a distant client so don't show
|
// Local files cannot be downloaded from a distant client so don't show
|
||||||
// a link to such a list here
|
// a link to such a list here
|
||||||
$("td:eq(3)", row).html(
|
const codeElem = document.createElement("code");
|
||||||
'<code id="address_' +
|
codeElem.id = "address_" + dataId;
|
||||||
dataId +
|
codeElem.className = "breakall";
|
||||||
'" class="breakall">' +
|
codeElem.textContent = data.address;
|
||||||
utils.escapeHtml(data.address) +
|
$("td:eq(3)", row).empty().append(codeElem);
|
||||||
"</code>"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
$("td:eq(3)", row).html(
|
const aElem = document.createElement("a");
|
||||||
'<a id="address_' +
|
aElem.id = "address_" + dataId;
|
||||||
dataId +
|
aElem.className = "breakall";
|
||||||
'" class="breakall" href="' +
|
aElem.href = data.address;
|
||||||
encodeURI(data.address) +
|
aElem.target = "_blank";
|
||||||
'" target="_blank" rel="noopener noreferrer">' +
|
aElem.rel = "noopener noreferrer";
|
||||||
utils.escapeHtml(data.address) +
|
aElem.textContent = data.address;
|
||||||
"</a>"
|
$("td:eq(3)", row).empty().append(aElem);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$("td:eq(4)", row).html(
|
$("td:eq(4)", row).html(
|
||||||
@@ -518,12 +515,12 @@ function addList(event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: document.body.dataset.apiurl + "/lists",
|
url: document.body.dataset.apiurl + "/lists?type=" + encodeURIComponent(type),
|
||||||
method: "post",
|
method: "post",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
processData: false,
|
processData: false,
|
||||||
contentType: "application/json; charset=utf-8",
|
contentType: "application/json; charset=utf-8",
|
||||||
data: JSON.stringify({ address: addresses, comment, type, groups: group }),
|
data: JSON.stringify({ address: addresses, comment, groups: group }),
|
||||||
success(data) {
|
success(data) {
|
||||||
utils.enableAll();
|
utils.enableAll();
|
||||||
utils.listsAlert(type + "list", addresses, data);
|
utils.listsAlert(type + "list", addresses, data);
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ function updateClientsOverTime() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const upstreams = {};
|
const upstreamIPs = [];
|
||||||
function updateForwardDestinationsPie() {
|
function updateForwardDestinationsPie() {
|
||||||
$.getJSON(document.body.dataset.apiurl + "/stats/upstreams", data => {
|
$.getJSON(document.body.dataset.apiurl + "/stats/upstreams", data => {
|
||||||
const v = [];
|
const v = [];
|
||||||
@@ -248,11 +248,8 @@ function updateForwardDestinationsPie() {
|
|||||||
label += "#" + item.port;
|
label += "#" + item.port;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store upstreams for generating links to the Query Log
|
// Store upstreams IPs for generating links to the Query Log
|
||||||
upstreams[label] = item.ip;
|
upstreamIPs.push(item.port > 0 ? item.ip + "#" + item.port : item.ip);
|
||||||
if (item.port > 0) {
|
|
||||||
upstreams[label] += "#" + item.port;
|
|
||||||
}
|
|
||||||
|
|
||||||
const percent = (100 * item.count) / sum;
|
const percent = (100 * item.count) / sum;
|
||||||
values.push([label, percent, THEME_COLORS[i++ % THEME_COLORS.length]]);
|
values.push([label, percent, THEME_COLORS[i++ % THEME_COLORS.length]]);
|
||||||
@@ -521,8 +518,8 @@ function labelWithPercentage(tooltipLabel, skipZero = false) {
|
|||||||
// Sum all queries for the current time by iterating over all keys in the
|
// Sum all queries for the current time by iterating over all keys in the
|
||||||
// current dataset
|
// current dataset
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
for (const value of Object.values(tooltipLabel.parsed._stacks.y)) {
|
for (const [key, value] of Object.entries(tooltipLabel.parsed._stacks.y)) {
|
||||||
if (value === undefined) continue;
|
if (key.startsWith("_") || value === undefined) continue;
|
||||||
const num = Number.parseInt(value, 10);
|
const num = Number.parseInt(value, 10);
|
||||||
if (num) sum += num;
|
if (num) sum += num;
|
||||||
}
|
}
|
||||||
@@ -639,9 +636,11 @@ $(() => {
|
|||||||
display: false,
|
display: false,
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
enabled: true,
|
// Disable the on-canvas tooltip
|
||||||
|
enabled: false,
|
||||||
intersect: false,
|
intersect: false,
|
||||||
yAlign: "bottom",
|
external: customTooltips,
|
||||||
|
yAlign: "top",
|
||||||
itemSort(a, b) {
|
itemSort(a, b) {
|
||||||
return b.datasetIndex - a.datasetIndex;
|
return b.datasetIndex - a.datasetIndex;
|
||||||
},
|
},
|
||||||
@@ -656,7 +655,7 @@ $(() => {
|
|||||||
return "Queries from " + from + " to " + to;
|
return "Queries from " + from + " to " + to;
|
||||||
},
|
},
|
||||||
label(tooltipLabel) {
|
label(tooltipLabel) {
|
||||||
return labelWithPercentage(tooltipLabel);
|
return labelWithPercentage(tooltipLabel, true);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -893,6 +892,8 @@ $(() => {
|
|||||||
elements: {
|
elements: {
|
||||||
arc: {
|
arc: {
|
||||||
borderColor: $(".box").css("background-color"),
|
borderColor: $(".box").css("background-color"),
|
||||||
|
hoverBorderColor: $(".box").css("background-color"),
|
||||||
|
hoverOffset: 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
@@ -917,6 +918,9 @@ $(() => {
|
|||||||
animation: {
|
animation: {
|
||||||
duration: 750,
|
duration: 750,
|
||||||
},
|
},
|
||||||
|
layout: {
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -939,6 +943,8 @@ $(() => {
|
|||||||
elements: {
|
elements: {
|
||||||
arc: {
|
arc: {
|
||||||
borderColor: $(".box").css("background-color"),
|
borderColor: $(".box").css("background-color"),
|
||||||
|
hoverBorderColor: $(".box").css("background-color"),
|
||||||
|
hoverOffset: 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: {
|
plugins: {
|
||||||
@@ -963,6 +969,9 @@ $(() => {
|
|||||||
animation: {
|
animation: {
|
||||||
duration: 750,
|
duration: 750,
|
||||||
},
|
},
|
||||||
|
layout: {
|
||||||
|
padding: 10,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,14 @@ const filters = [
|
|||||||
"reply",
|
"reply",
|
||||||
"dnssec",
|
"dnssec",
|
||||||
];
|
];
|
||||||
|
let doDNSSEC = false;
|
||||||
|
|
||||||
|
// Check if pihole is validiting DNSSEC
|
||||||
|
function getDnssecConfig() {
|
||||||
|
$.getJSON(document.body.dataset.apiurl + "/config/dns/dnssec", data => {
|
||||||
|
doDNSSEC = data.config.dns.dnssec;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function initDateRangePicker() {
|
function initDateRangePicker() {
|
||||||
$("#querytime").daterangepicker(
|
$("#querytime").daterangepicker(
|
||||||
@@ -480,6 +488,9 @@ function liveUpdate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$(() => {
|
$(() => {
|
||||||
|
// Do we want to show DNSSEC icons?
|
||||||
|
getDnssecConfig();
|
||||||
|
|
||||||
// Do we want to filter queries?
|
// Do we want to filter queries?
|
||||||
const GETDict = utils.parseQueryString();
|
const GETDict = utils.parseQueryString();
|
||||||
|
|
||||||
@@ -561,11 +572,13 @@ $(() => {
|
|||||||
utils.stateSaveCallback("query_log_table", data);
|
utils.stateSaveCallback("query_log_table", data);
|
||||||
},
|
},
|
||||||
stateLoadCallback() {
|
stateLoadCallback() {
|
||||||
return utils.stateLoadCallback("query_log_table");
|
const state = utils.stateLoadCallback("query_log_table");
|
||||||
|
// Default to 25 entries if "All" was previously selected
|
||||||
|
if (state) state.length = state.length === -1 ? 25 : state.length;
|
||||||
|
return state;
|
||||||
},
|
},
|
||||||
rowCallback(row, data) {
|
rowCallback(row, data) {
|
||||||
const querystatus = parseQueryStatus(data);
|
const querystatus = parseQueryStatus(data);
|
||||||
const dnssec = parseDNSSEC(data);
|
|
||||||
|
|
||||||
if (querystatus.icon !== false) {
|
if (querystatus.icon !== false) {
|
||||||
$("td:eq(1)", row).html(
|
$("td:eq(1)", row).html(
|
||||||
@@ -589,14 +602,17 @@ $(() => {
|
|||||||
|
|
||||||
// Prefix colored DNSSEC icon to domain text
|
// Prefix colored DNSSEC icon to domain text
|
||||||
let dnssecIcon = "";
|
let dnssecIcon = "";
|
||||||
dnssecIcon =
|
if (doDNSSEC === true) {
|
||||||
'<i class="mr-2 fa fa-fw ' +
|
const dnssec = parseDNSSEC(data);
|
||||||
dnssec.icon +
|
dnssecIcon =
|
||||||
" " +
|
'<i class="mr-2 fa fa-fw ' +
|
||||||
dnssec.color +
|
dnssec.icon +
|
||||||
'" title="DNSSEC: ' +
|
" " +
|
||||||
dnssec.text +
|
dnssec.color +
|
||||||
'"></i>';
|
'" title="DNSSEC: ' +
|
||||||
|
dnssec.text +
|
||||||
|
'"></i>';
|
||||||
|
}
|
||||||
|
|
||||||
// Escape HTML in domain
|
// Escape HTML in domain
|
||||||
domain = dnssecIcon + utils.escapeHtml(domain);
|
domain = dnssecIcon + utils.escapeHtml(domain);
|
||||||
|
|||||||
@@ -361,7 +361,7 @@ $(document).on("focus input", "#StaticDHCPTable td[contenteditable]", function (
|
|||||||
if (!row.next().hasClass("edit-hint-row")) {
|
if (!row.next().hasClass("edit-hint-row")) {
|
||||||
row.next(".edit-hint-row").remove(); // Remove any existing hint
|
row.next(".edit-hint-row").remove(); // Remove any existing hint
|
||||||
row.after(
|
row.after(
|
||||||
'<tr class="edit-hint-row"><td colspan="4" class="text-info" style="font-style:italic;">Please save this line before editing another or leaving the page, otherwise your changes will be lost.</td></tr>'
|
'<tr class="edit-hint-row"><td colspan="4" class="text-info" style="font-style:italic;">Please confirm changes using the green button, then click "Save & Apply" before leaving the page.</td></tr>'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -398,10 +398,10 @@ function renderStaticDHCPTable() {
|
|||||||
$("<td></td>")
|
$("<td></td>")
|
||||||
.append(
|
.append(
|
||||||
$(
|
$(
|
||||||
'<button type="button" class="btn btn-success btn-xs save-static-row"><i class="fa fa-fw fa-floppy-disk"></i></button>'
|
'<button type="button" class="btn btn-success btn-xs save-static-row"><i class="fa fa-fw fa-check"></i></button>'
|
||||||
)
|
)
|
||||||
.attr("data-row", idx)
|
.attr("data-row", idx)
|
||||||
.attr("title", "Save changes to this line")
|
.attr("title", "Confirm changes to this line")
|
||||||
.attr("data-toggle", "tooltip")
|
.attr("data-toggle", "tooltip")
|
||||||
)
|
)
|
||||||
.append(" ")
|
.append(" ")
|
||||||
@@ -518,3 +518,17 @@ $(document).on("input blur paste", "#StaticDHCPTable td.static-ipaddr", function
|
|||||||
$(this).attr("title", "");
|
$(this).attr("title", "");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$(document).on("input blur paste", "#StaticDHCPTable td.static-hostname", function () {
|
||||||
|
const val = $(this).text().trim();
|
||||||
|
// Hostnames must not contain spaces, commas, or characters invalid in DNS names
|
||||||
|
const hostnameValidator = /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/v;
|
||||||
|
if (val && !hostnameValidator.test(val)) {
|
||||||
|
$(this).addClass("table-danger");
|
||||||
|
$(this).removeClass("table-success");
|
||||||
|
$(this).attr("title", "Invalid hostname: only letters, digits, hyphens, and dots allowed");
|
||||||
|
} else {
|
||||||
|
$(this).removeClass("table-danger table-success");
|
||||||
|
$(this).attr("title", "");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ $(() => {
|
|||||||
|
|
||||||
$("#btnAdd-host").on("click", () => {
|
$("#btnAdd-host").on("click", () => {
|
||||||
utils.disableAll();
|
utils.disableAll();
|
||||||
const elem = $("#Hip").val() + " " + $("#Hdomain").val();
|
const elem = $("#Hip").val().trim() + " " + $("#Hdomain").val().trim();
|
||||||
const url = document.body.dataset.apiurl + "/config/dns/hosts/" + encodeURIComponent(elem);
|
const url = document.body.dataset.apiurl + "/config/dns/hosts/" + encodeURIComponent(elem);
|
||||||
utils.showAlert("info", "", "Adding DNS record...", elem);
|
utils.showAlert("info", "", "Adding DNS record...", elem);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
@@ -239,7 +239,7 @@ $(() => {
|
|||||||
|
|
||||||
$("#btnAdd-cname").on("click", () => {
|
$("#btnAdd-cname").on("click", () => {
|
||||||
utils.disableAll();
|
utils.disableAll();
|
||||||
let elem = $("#Cdomain").val() + "," + $("#Ctarget").val();
|
let elem = $("#Cdomain").val().trim() + "," + $("#Ctarget").val().trim();
|
||||||
const ttlVal = Number.parseInt($("#Cttl").val(), 10);
|
const ttlVal = Number.parseInt($("#Cttl").val(), 10);
|
||||||
// TODO Fix eslint
|
// TODO Fix eslint
|
||||||
// eslint-disable-next-line unicorn/prefer-number-properties
|
// eslint-disable-next-line unicorn/prefer-number-properties
|
||||||
|
|||||||
@@ -267,7 +267,7 @@ $(".confirm-flusharp").confirm({
|
|||||||
title: "Confirmation required",
|
title: "Confirmation required",
|
||||||
confirm() {
|
confirm() {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: document.body.dataset.apiurl + "/action/flush/arp",
|
url: document.body.dataset.apiurl + "/action/flush/network",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
}).fail(data => {
|
}).fail(data => {
|
||||||
apiFailure(data);
|
apiFailure(data);
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ mg.include('header.lp','r')
|
|||||||
<script src="<?=pihole.fileversion('vendor/waitMe-js/modernized-waitme-min.js')?>"></script>
|
<script src="<?=pihole.fileversion('vendor/waitMe-js/modernized-waitme-min.js')?>"></script>
|
||||||
<script src="<?=pihole.fileversion('scripts/js/logout.js')?>"></script>
|
<script src="<?=pihole.fileversion('scripts/js/logout.js')?>"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="<?=theme.name?> hold-transition sidebar-mini <? if pihole.boxedlayout() then ?>layout-boxed<? end ?> logged-in page-<?=pihole.format_path(mg.request_info.request_uri)?>" data-apiurl="<?=pihole.api_url()?>" data-webhome="<?=webhome?>">
|
<body class="<?=theme.name?> hold-transition sidebar-mini <? if pihole.boxedlayout() then ?>layout-boxed<? end ?> logged-in page-<?=pihole.format_path(scriptname)?>" data-apiurl="<?=pihole.api_url()?>" data-webhome="<?=webhome?>">
|
||||||
<noscript>
|
<noscript>
|
||||||
<!-- JS Warning -->
|
<!-- JS Warning -->
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ mg.include('scripts/lua/settings_header.lp','r')
|
|||||||
<h4 class="modal-title">Enable two-factor authentication</h4>
|
<h4 class="modal-title">Enable two-factor authentication</h4>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<p>Use a phone app like Google Authenticator, 2FA Authenticator, FreeOTP or BitWarden, etc. to get 2FA codes when prompted during login.</p>
|
<p>Use a phone app like Google Authenticator, 2FA Authenticator, FreeOTP or Bitwarden, etc. to get 2FA codes when prompted during login.</p>
|
||||||
<p>1. Scan the QR code below with your app or enter the secret manually.</p>
|
<p>1. Scan the QR code below with your app or enter the secret manually.</p>
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<i id="qrcode-spinner" class="fas fa-spinner fa-pulse fa-5x"></i>
|
<i id="qrcode-spinner" class="fas fa-spinner fa-pulse fa-5x"></i>
|
||||||
@@ -192,11 +192,15 @@ mg.include('scripts/lua/settings_header.lp','r')
|
|||||||
<p>2. Enter the 2FA code from your app below to confirm that you have set up 2FA correctly.</p>
|
<p>2. Enter the 2FA code from your app below to confirm that you have set up 2FA correctly.</p>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 col-md-offset-3">
|
<div class="col-md-6 col-md-offset-3">
|
||||||
<div id="totp_div" class="has-feedback has-error">
|
<div id="totp_div">
|
||||||
<div class="pwd-field form-group">
|
<div class="pwd-field form-group has-error">
|
||||||
<input type="text" size="6" maxlength="6" class="form-control totp_token" id="totp_code" placeholder="">
|
<div class="input-group">
|
||||||
|
<input type="text" size="6" maxlength="6" class="form-control totp_token" id="totp_code" placeholder="">
|
||||||
|
<div class="input-group-addon" data-toggle="tooltip" data-placement="auto" title="TOTP verification code">
|
||||||
|
<i class="fa fa-clock-rotate-left"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<i class="fa-solid fa-clock-rotate-left pwd-field form-control-feedback"></i>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ mg.include('scripts/lua/settings_header.lp','r')
|
|||||||
</div>
|
</div>
|
||||||
<div class="box box-warning settings-level-expert d-none">
|
<div class="box box-warning settings-level-expert d-none">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title" data-configkeys="dns.domain dns.expandHosts">DNS domain settings</h3>
|
<h3 class="box-title" data-configkeys="dns.domain.name dns.expandHosts">DNS domain settings</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@@ -68,7 +68,7 @@ mg.include('scripts/lua/settings_header.lp','r')
|
|||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<div class="input-group-addon">Domain</div>
|
<div class="input-group-addon">Domain</div>
|
||||||
<input type="text" class="form-control" id="dns.domain" data-key="dns.domain" value="">
|
<input type="text" class="form-control" id="dns.domain.name" data-key="dns.domain.name" value="">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>The DNS domains for your Pi-hole. This DNS domain is purely local. FTL may answer queries from its local cache and configuration but *never* forwards any requests upstream *unless* you have configured a dns.revServer exactly for this domain. If no domain is specified and you are using Pi-hole's DHCP server, then any hostnames with a domain part (i.e., with a period) will be disallowed. If a domain is specified, then hostnames with a domain parts matching the domain here are allowed. In addition, when a suffix is set then hostnames without a domain part have the suffix added as an optional domain part.</p>
|
<p>The DNS domains for your Pi-hole. This DNS domain is purely local. FTL may answer queries from its local cache and configuration but *never* forwards any requests upstream *unless* you have configured a dns.revServer exactly for this domain. If no domain is specified and you are using Pi-hole's DHCP server, then any hostnames with a domain part (i.e., with a period) will be disallowed. If a domain is specified, then hostnames with a domain parts matching the domain here are allowed. In addition, when a suffix is set then hostnames without a domain part have the suffix added as an optional domain part.</p>
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ mg.include('scripts/lua/settings_header.lp','r')
|
|||||||
<th scope="row">Kernel:</th>
|
<th scope="row">Kernel:</th>
|
||||||
<td><span id="sysinfo-kernel"></span></td>
|
<td><span id="sysinfo-kernel"></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr title="The machine uptime. For containers, this will match the host uptime">
|
||||||
<th scope="row">Uptime:</th>
|
<th scope="row">Uptime:</th>
|
||||||
<td><span id="sysinfo-uptime"></span></td>
|
<td><span id="sysinfo-uptime"></span></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -594,12 +594,6 @@ td.details-control {
|
|||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-control-feedback {
|
|
||||||
right: 0.5em;
|
|
||||||
width: 16px;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loginpage-logo {
|
.loginpage-logo {
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
}
|
}
|
||||||
@@ -1650,3 +1644,13 @@ div.dhcp-hosts-wrapper {
|
|||||||
background-color: #599900;
|
background-color: #599900;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used in query log page */
|
||||||
|
td.dnssec {
|
||||||
|
padding-inline-start: 2.25em !important;
|
||||||
|
text-indent: -1.25em;
|
||||||
|
}
|
||||||
|
td.dnssec i {
|
||||||
|
text-indent: 0;
|
||||||
|
margin-left: -0.5rem;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user