mirror of
https://github.com/ZoeyVid/NPMplus.git
synced 2026-03-03 04:16:58 +00:00
Compare commits
122 Commits
2026-02-15
...
develop
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0da1cc184f | ||
|
|
19c819fc95 | ||
|
|
8521cf19cc | ||
|
|
daed77142f | ||
|
|
537ca98f8f | ||
|
|
f1e95f7ba6 | ||
|
|
842b7d9a72 | ||
|
|
ca8f602466 | ||
|
|
57605b455c | ||
|
|
bd06d48f0b | ||
|
|
c1d09eaceb | ||
|
|
9c509f30de | ||
|
|
c85b11ee33 | ||
|
|
cd5ef390b9 | ||
|
|
d49cab1c0e | ||
|
|
d2b446192f | ||
|
|
33b1a993ec | ||
|
|
67d40e186f | ||
|
|
52be66c43e | ||
|
|
ec46cabcd4 | ||
|
|
a7a9cc3acb | ||
|
|
020b3ebb33 | ||
|
|
c1c4baf389 | ||
|
|
672b5d6dd9 | ||
|
|
cd230b5878 | ||
|
|
a8f35062af | ||
|
|
da5955412d | ||
|
|
adb27fe67d | ||
|
|
d874af8692 | ||
|
|
0844dade98 | ||
|
|
71d59516e8 | ||
|
|
06e220e184 | ||
|
|
dc53647e76 | ||
|
|
4c04e89483 | ||
|
|
8c3e0f2809 | ||
|
|
074a01546a | ||
|
|
246d31c2fd | ||
|
|
7241869a9e | ||
|
|
0333ab08f3 | ||
|
|
dda1c5ebe0 | ||
|
|
951062a6b9 | ||
|
|
94f6191a21 | ||
|
|
cac52dd0ff | ||
|
|
906f177960 | ||
|
|
f52afced5d | ||
|
|
e8224ff0af | ||
|
|
a4fa83d0ce | ||
|
|
770716ebf8 | ||
|
|
17c2a68ff0 | ||
|
|
d144f54a6c | ||
|
|
27fe362854 | ||
|
|
507a71cf9b | ||
|
|
1b713e3a88 | ||
|
|
c0c4f748b2 | ||
|
|
ae13514410 | ||
|
|
814827be4e | ||
|
|
30ad65c5a6 | ||
|
|
f1067d3308 | ||
|
|
85c1a935ea | ||
|
|
51ef7f3b86 | ||
|
|
8484c69af8 | ||
|
|
316cdf3479 | ||
|
|
dffa4a9888 | ||
|
|
846b94f7e8 | ||
|
|
ace499a546 | ||
|
|
19e24c7e7e | ||
|
|
c1bc471dac | ||
|
|
608dc0b6bf | ||
|
|
0dbf268f37 | ||
|
|
f9a49092ba | ||
|
|
23c49447ab | ||
|
|
dde694b57d | ||
|
|
9c9f82dc26 | ||
|
|
c7437ddf8f | ||
|
|
627f43c729 | ||
|
|
fc4c5aac86 | ||
|
|
aff390f35d | ||
|
|
5f5a3870e4 | ||
|
|
40f363bd4f | ||
|
|
678fdd22c6 | ||
|
|
6c3cc83d66 | ||
|
|
5916fd5bee | ||
|
|
f105673904 | ||
|
|
a37d0b88d6 | ||
|
|
43bc2a743e | ||
|
|
269545256a | ||
|
|
e5df45e9ef | ||
|
|
5601dd14fc | ||
|
|
3e5655cfcd | ||
|
|
1e723b2f88 | ||
|
|
27510c888d | ||
|
|
7499388f49 | ||
|
|
ed70405773 | ||
|
|
a90af83270 | ||
|
|
619a8e5acc | ||
|
|
6dcdefb57e | ||
|
|
787616010b | ||
|
|
5891c291d2 | ||
|
|
41a2a41e67 | ||
|
|
379099d7ed | ||
|
|
dbeab93c02 | ||
|
|
010cb562a0 | ||
|
|
7ff2fc1900 | ||
|
|
1c189a1888 | ||
|
|
f3c46487f6 | ||
|
|
fcca481d1b | ||
|
|
c59c237000 | ||
|
|
94a0e4a42f | ||
|
|
a62b6de9f2 | ||
|
|
d92cc953e1 | ||
|
|
1b6412688b | ||
|
|
1d14f72ba5 | ||
|
|
099243aff7 | ||
|
|
5fe12f69ba | ||
|
|
3f2aec7b86 | ||
|
|
09a3d65aa1 | ||
|
|
c910cf9512 | ||
|
|
304c51aae8 | ||
|
|
b552eb90ed | ||
|
|
b78ef9bcd3 | ||
|
|
7c67fafedf | ||
|
|
47b367d61e |
2
.github/workflows/caddy-fmt.yml
vendored
2
.github/workflows/caddy-fmt.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Read version
|
||||
id: version
|
||||
run: echo "version=$(cat caddy/Dockerfile | grep "^COPY --from=caddy:.*$" | head -1 | sed "s|COPY --from=caddy:\([0-9.]\+\).*|\1|g")" >> $GITHUB_OUTPUT
|
||||
|
||||
12
.github/workflows/caddy.yml
vendored
12
.github/workflows/caddy.yml
vendored
@@ -13,28 +13,28 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 # v3
|
||||
with:
|
||||
platforms: all
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
password: ${{ github.token }}
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: caddy
|
||||
platforms: linux/amd64,linux/arm64
|
||||
|
||||
114
.github/workflows/dependency-updates.yml
vendored
114
.github/workflows/dependency-updates.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update nginx version
|
||||
id: update
|
||||
run: |
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
sed -i "s|ARG NGINX_VER=.*|ARG NGINX_VER=$NGINX_VER|" Dockerfile
|
||||
echo "version=$NGINX_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -39,24 +39,22 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update dynamic_tls_records version
|
||||
id: update
|
||||
run: |
|
||||
git clone https://github.com/nginx-modules/ngx_http_tls_dyn_size ngx_http_tls_dyn_size
|
||||
git clone --depth 1 https://github.com/nginx-modules/ngx_http_tls_dyn_size ngx_http_tls_dyn_size
|
||||
DTR_VER="$(
|
||||
ls ngx_http_tls_dyn_size/nginx__dynamic_tls_records_*.patch \
|
||||
| sed "s|ngx_http_tls_dyn_size/nginx__dynamic_tls_records_\([0-9.]\+\)+.patch|\1|g" \
|
||||
| sort -V \
|
||||
| grep -v rc \
|
||||
| tail -1 \
|
||||
| sed "s|\^{}||g"
|
||||
| tail -1
|
||||
)"
|
||||
rm -r ngx_http_tls_dyn_size
|
||||
sed -i "s|ARG DTR_VER=.*|ARG DTR_VER=$DTR_VER|" Dockerfile
|
||||
echo "version=$DTR_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -68,22 +66,21 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update resolver_conf_parsing version
|
||||
id: update
|
||||
run: |
|
||||
git clone https://github.com/openresty/openresty openresty
|
||||
git clone --depth 1 https://github.com/openresty/openresty openresty
|
||||
RCP_VER="$(
|
||||
ls openresty/patches/nginx \
|
||||
| sort -V \
|
||||
| tail -1 \
|
||||
| sed "s|\^{}||g"
|
||||
| tail -1
|
||||
)"
|
||||
rm -r openresty
|
||||
sed -i "s|ARG RCP_VER=.*|ARG RCP_VER=$RCP_VER|" Dockerfile
|
||||
echo "version=$RCP_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -91,12 +88,39 @@ jobs:
|
||||
branch: update-resolver_conf_parsing-version
|
||||
title: update resolver_conf_parsing version to ${{ steps.update.outputs.version }}
|
||||
body: update resolver_conf_parsing version to ${{ steps.update.outputs.version }}
|
||||
zlib-ng-patch-update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update zlib-ng-patch version
|
||||
id: update
|
||||
run: |
|
||||
git clone --depth 1 https://github.com/zlib-ng/patches zlib-ng-patches
|
||||
ZNP_VER="$(
|
||||
ls zlib-ng-patches/nginx/*-zlib-ng.patch \
|
||||
| sed "s|zlib-ng-patches/nginx/\([0-9.]\+\)-zlib-ng.patch|\1|g" \
|
||||
| sort -V \
|
||||
| tail -1
|
||||
)"
|
||||
rm -r zlib-ng-patches
|
||||
sed -i "s|ARG ZNP_VER=.*|ARG ZNP_VER=$ZNP_VER|" Dockerfile
|
||||
echo "version=$ZNP_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
commit-message: update zlib-ng-patch version to ${{ steps.update.outputs.version }}
|
||||
branch: update-zlib-ng-patch-version
|
||||
title: update zlib-ng-patch version to ${{ steps.update.outputs.version }}
|
||||
body: update zlib-ng-patch version to ${{ steps.update.outputs.version }}
|
||||
|
||||
ngx_brotli-update:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update ngx_brotli version
|
||||
id: update
|
||||
run: |
|
||||
@@ -111,7 +135,7 @@ jobs:
|
||||
sed -i "s|ARG NB_VER=.*|ARG NB_VER=$NB_VER|" Dockerfile
|
||||
echo "version=$NB_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != '' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -124,7 +148,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update ngx_unbrotli version
|
||||
id: update
|
||||
run: |
|
||||
@@ -139,7 +163,7 @@ jobs:
|
||||
sed -i "s|ARG NUB_VER=.*|ARG NUB_VER=$NUB_VER|" Dockerfile
|
||||
echo "version=$NUB_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != '' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -152,7 +176,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update zstd-nginx-module version
|
||||
id: update
|
||||
run: |
|
||||
@@ -167,7 +191,7 @@ jobs:
|
||||
sed -i "s|ARG ZNM_VER=.*|ARG ZNM_VER=$ZNM_VER|" Dockerfile
|
||||
echo "version=$ZNM_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != '0.1.1' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -180,7 +204,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update ngx_http_unzstd_filter_module version
|
||||
id: update
|
||||
run: |
|
||||
@@ -195,7 +219,7 @@ jobs:
|
||||
sed -i "s|ARG NHUZFM_VER=.*|ARG NHUZFM_VER=$NHUZFM_VER|" Dockerfile
|
||||
echo "version=$NHUZFM_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != '' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -208,7 +232,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update ngx-fancyindex version
|
||||
id: update
|
||||
run: |
|
||||
@@ -223,7 +247,7 @@ jobs:
|
||||
sed -i "s|ARG NF_VER=.*|ARG NF_VER=$NF_VER|" Dockerfile
|
||||
echo "version=$NF_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != 'v0.5.2' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -236,7 +260,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update headers-more-nginx-module version
|
||||
id: update
|
||||
run: |
|
||||
@@ -251,7 +275,7 @@ jobs:
|
||||
sed -i "s|ARG HMNM_VER=.*|ARG HMNM_VER=$HMNM_VER|" Dockerfile
|
||||
echo "version=$HMNM_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -263,7 +287,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update ngx_devel_kit version
|
||||
id: update
|
||||
run: |
|
||||
@@ -278,7 +302,7 @@ jobs:
|
||||
sed -i "s|ARG NDK_VER=.*|ARG NDK_VER=$NDK_VER|" Dockerfile
|
||||
echo "version=$NDK_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -290,7 +314,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update lua-nginx-module version
|
||||
id: update
|
||||
run: |
|
||||
@@ -305,7 +329,7 @@ jobs:
|
||||
sed -i "s|ARG LNM_VER=.*|ARG LNM_VER=$LNM_VER|" Dockerfile
|
||||
echo "version=$LNM_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -319,7 +343,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update njs version
|
||||
id: update
|
||||
run: |
|
||||
@@ -334,7 +358,7 @@ jobs:
|
||||
sed -i "s|ARG NJS_VER=.*|ARG NJS_VER=$NJS_VER|" Dockerfile
|
||||
echo "version=$NJS_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -346,7 +370,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update nginx-auth-ldap version
|
||||
id: update
|
||||
run: |
|
||||
@@ -361,7 +385,7 @@ jobs:
|
||||
sed -i "s|ARG NAL_VER=.*|ARG NAL_VER=$NAL_VER|" Dockerfile
|
||||
echo "version=$NAL_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != 'v0.1' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -374,7 +398,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update vts version
|
||||
id: update
|
||||
run: |
|
||||
@@ -389,7 +413,7 @@ jobs:
|
||||
sed -i "s|ARG VTS_VER=.*|ARG VTS_VER=$VTS_VER|" Dockerfile
|
||||
echo "version=$VTS_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -401,7 +425,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update nginx-ntlm-module version
|
||||
id: update
|
||||
run: |
|
||||
@@ -416,7 +440,7 @@ jobs:
|
||||
sed -i "s|ARG NNTLM_VER=.*|ARG NNTLM_VER=$NNTLM_VER|" Dockerfile
|
||||
echo "version=$NNTLM_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
if: ${{ steps.update.outputs.version != 'v1.19.3-beta.1' }}
|
||||
with:
|
||||
signoff: true
|
||||
@@ -429,7 +453,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update ngx_http_geoip2_module version
|
||||
id: update
|
||||
run: |
|
||||
@@ -444,7 +468,7 @@ jobs:
|
||||
sed -i "s|ARG NHG2M_VER=.*|ARG NHG2M_VER=$NHG2M_VER|" Dockerfile
|
||||
echo "version=$NHG2M_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -457,7 +481,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update lua-resty-core version
|
||||
id: update
|
||||
run: |
|
||||
@@ -472,7 +496,7 @@ jobs:
|
||||
sed -i "s|ARG LRC_VER=.*|ARG LRC_VER=$LRC_VER|" Dockerfile
|
||||
echo "version=$LRC_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -484,7 +508,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update lua-resty-lrucache version
|
||||
id: update
|
||||
run: |
|
||||
@@ -499,7 +523,7 @@ jobs:
|
||||
sed -i "s|ARG LRL_VER=.*|ARG LRL_VER=$LRL_VER|" Dockerfile
|
||||
echo "version=$LRL_VER" >> $GITHUB_OUTPUT
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
@@ -512,7 +536,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: update lua-cs-bouncer version
|
||||
id: update
|
||||
run: |
|
||||
@@ -529,7 +553,7 @@ jobs:
|
||||
wget https://raw.githubusercontent.com/crowdsecurity/cs-nginx-bouncer/refs/heads/main/nginx/crowdsec_nginx.conf -O rootfs/usr/local/nginx/conf/conf.d/crowdsec.conf.original
|
||||
wget https://raw.githubusercontent.com/crowdsecurity/lua-cs-bouncer/refs/tags/"$LCSB_VER"/config_example.conf -O rootfs/etc/crowdsec.conf.original
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8
|
||||
with:
|
||||
signoff: true
|
||||
delete-branch: true
|
||||
|
||||
20
.github/workflows/docker-beta.yml
vendored
20
.github/workflows/docker-beta.yml
vendored
@@ -12,13 +12,13 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" frontend/package.json
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" backend/package.json
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -42,13 +42,13 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" frontend/package.json
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" backend/package.json
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -73,12 +73,12 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
|
||||
20
.github/workflows/docker-latest.yml
vendored
20
.github/workflows/docker-latest.yml
vendored
@@ -12,13 +12,13 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
@@ -28,7 +28,7 @@ jobs:
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" frontend/package.json
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" backend/package.json
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -42,13 +42,13 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" frontend/package.json
|
||||
sed -i "s|\"0.0.0\"|\"${{ inputs.tag }}-$(git rev-parse --short HEAD)-$(cat .version)\"|g" backend/package.json
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -73,12 +73,12 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
|
||||
67
.github/workflows/docker.yml
vendored
67
.github/workflows/docker.yml
vendored
@@ -3,7 +3,6 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
build-x86_64:
|
||||
@@ -11,13 +10,13 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
@@ -27,8 +26,7 @@ jobs:
|
||||
sed -i "s|\"0.0.0\"|\"$(git rev-parse --short HEAD)\"|g" frontend/package.json
|
||||
sed -i "s|\"0.0.0\"|\"$(git rev-parse --short HEAD)\"|g" backend/package.json
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -36,33 +34,19 @@ jobs:
|
||||
tags: ghcr.io/zoeyvid/npmplus:develop-x86_64
|
||||
build-args: |
|
||||
FLAGS=-march=x86-64-v2 -mtune=generic -fcf-protection=full
|
||||
- name: Set PR-Number (PR)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: pr
|
||||
run: echo "pr=$(echo pr-develop | sed "s|refs/pull/:||g" | sed "s|/merge||g")" >> $GITHUB_OUTPUT
|
||||
- name: Build (PR)
|
||||
uses: docker/build-push-action@v6
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ghcr.io/zoeyvid/npmplus:${{ steps.pr.outputs.pr }}-x86_64
|
||||
build-args: |
|
||||
FLAGS=-march=x86-64-v2 -mtune=generic -fcf-protection=full
|
||||
|
||||
build-aarch64:
|
||||
runs-on: ubuntu-24.04-arm
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
||||
with:
|
||||
driver-opts: env.BUILDKIT_STEP_LOG_MAX_SIZE=-1
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
@@ -72,8 +56,7 @@ jobs:
|
||||
sed -i "s|\"0.0.0\"|\"$(git rev-parse --short HEAD)\"|g" frontend/package.json
|
||||
sed -i "s|\"0.0.0\"|\"$(git rev-parse --short HEAD)\"|g" backend/package.json
|
||||
- name: Build
|
||||
uses: docker/build-push-action@v6
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
@@ -81,20 +64,6 @@ jobs:
|
||||
tags: ghcr.io/zoeyvid/npmplus:develop-aarch64
|
||||
build-args: |
|
||||
FLAGS=-mbranch-protection=standard
|
||||
- name: Set PR-Number (PR)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: pr
|
||||
run: echo "pr=$(echo pr-develop | sed "s|refs/pull/:||g" | sed "s|/merge||g")" >> $GITHUB_OUTPUT
|
||||
- name: Build (PR)
|
||||
uses: docker/build-push-action@v6
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
push: true
|
||||
tags: ghcr.io/zoeyvid/npmplus:${{ steps.pr.outputs.pr }}-aarch64
|
||||
build-args: |
|
||||
FLAGS=-mbranch-protection=standard
|
||||
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -102,33 +71,17 @@ jobs:
|
||||
if: ${{ github.repository_owner == 'ZoeyVid' }}
|
||||
steps:
|
||||
- name: Login to DockerHub
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_PASSWORD }}
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9 # v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: zoeyvid
|
||||
password: ${{ github.token }}
|
||||
- name: create multiarch
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
run: |
|
||||
docker buildx imagetools create --tag zoeyvid/npmplus:develop ghcr.io/zoeyvid/npmplus:develop-x86_64 ghcr.io/zoeyvid/npmplus:develop-aarch64
|
||||
docker buildx imagetools create --tag ghcr.io/zoeyvid/npmplus:develop ghcr.io/zoeyvid/npmplus:develop-x86_64 ghcr.io/zoeyvid/npmplus:develop-aarch64
|
||||
- name: Set PR-Number (PR)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
id: pr
|
||||
run: echo "pr=$(echo pr-develop | sed "s|refs/pull/:||g" | sed "s|/merge||g")" >> $GITHUB_OUTPUT
|
||||
- name: create multiarch (PR)
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: docker buildx imagetools create --tag ghcr.io/zoeyvid/npmplus:${{ steps.pr.outputs.pr }} ghcr.io/zoeyvid/npmplus:${{ steps.pr.outputs.pr }}-x86_64 ghcr.io/zoeyvid/npmplus:${{ steps.pr.outputs.pr }}-aarch64
|
||||
- name: add comment (PR)
|
||||
uses: mshick/add-pr-comment@v2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
with:
|
||||
message: "The Docker Image can now be found here: `ghcr.io/zoeyvid/npmplus:${{ steps.pr.outputs.pr }}`"
|
||||
repo-token: ${{ github.token }}
|
||||
refresh-message-position: true
|
||||
|
||||
2
.github/workflows/dockerlint.yml
vendored
2
.github/workflows/dockerlint.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
name: docker-lint
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Install hadolint
|
||||
run: |
|
||||
sudo wget https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64 -O /usr/bin/hadolint
|
||||
|
||||
4
.github/workflows/json.yml
vendored
4
.github/workflows/json.yml
vendored
@@ -9,8 +9,8 @@ jobs:
|
||||
test-json:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: json-syntax-check
|
||||
uses: limitusus/json-syntax-check@v2
|
||||
uses: limitusus/json-syntax-check@77d5756026b93886eaa3dc6ca1c4b17dd19dc703 # v2
|
||||
with:
|
||||
pattern: "\\.json"
|
||||
|
||||
6
.github/workflows/lint-and-format.yml
vendored
6
.github/workflows/lint-and-format.yml
vendored
@@ -10,11 +10,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6
|
||||
with:
|
||||
node-version: lts/*
|
||||
- uses: pnpm/action-setup@v4
|
||||
- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061 # v4
|
||||
with:
|
||||
version: latest
|
||||
- name: install-sponge
|
||||
|
||||
2
.github/workflows/shellcheck.yml
vendored
2
.github/workflows/shellcheck.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
name: Check Shell
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Run Shellcheck
|
||||
uses: ludeeus/action-shellcheck@master
|
||||
with:
|
||||
|
||||
4
.github/workflows/spellcheck.yml
vendored
4
.github/workflows/spellcheck.yml
vendored
@@ -11,9 +11,9 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code.
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
- name: Check spelling
|
||||
uses: codespell-project/actions-codespell@v2
|
||||
uses: codespell-project/actions-codespell@406322ec52dd7b488e48c1c4b82e2a8b3a1bf630 # v2
|
||||
with:
|
||||
check_filenames: true
|
||||
check_hidden: true
|
||||
|
||||
28
Dockerfile
28
Dockerfile
@@ -8,12 +8,13 @@ ARG LUAJIT_LIB=/usr/lib
|
||||
ARG NGINX_VER=release-1.29.5
|
||||
ARG DTR_VER=1.29.2
|
||||
ARG RCP_VER=1.29.4
|
||||
ARG ZNP_VER=1.26.3
|
||||
|
||||
ARG NB_VER=master
|
||||
ARG NUB_VER=main
|
||||
ARG ZNM_VER=master
|
||||
ARG NHUZFM_VER=main
|
||||
ARG NF_VER=master
|
||||
ARG NF_VER=v0.6.0
|
||||
ARG HMNM_VER=v0.39
|
||||
ARG NDK_VER=v0.3.4
|
||||
ARG LNM_VER=v0.10.29R2
|
||||
@@ -26,20 +27,17 @@ ARG NHG2M_VER=3.4
|
||||
|
||||
ARG FLAGS
|
||||
ARG CC=clang
|
||||
ARG CFLAGS="$FLAGS -m64 -O3 -pipe -flto=thin -fstack-clash-protection -fstack-protector-strong -ftrivial-auto-var-init=zero -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -Wformat=2 -Werror=format-security -Wno-sign-compare"
|
||||
ARG CFLAGS="$FLAGS -m64 -O3 -pipe -flto=full -fstack-clash-protection -fstack-protector-strong -ftrivial-auto-var-init=zero -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -Wformat=2 -Werror=format-security -Wno-sign-compare"
|
||||
ARG CXX=clang++
|
||||
ARG CXXFLAGS="$FLAGS -m64 -O3 -pipe -flto=thin -fstack-clash-protection -fstack-protector-strong -ftrivial-auto-var-init=zero -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST -Wformat=2 -Werror=format-security -Wno-sign-compare"
|
||||
ARG LDFLAGS="-fuse-ld=lld -m64 -Wl,-s -Wl,-O1 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--sort-common -Wl,--as-needed -Wl,-z,pack-relative-relocs"
|
||||
ARG CXXFLAGS="$FLAGS -m64 -O3 -pipe -flto=full -fstack-clash-protection -fstack-protector-strong -ftrivial-auto-var-init=zero -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fno-plt -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=3 -D_GLIBCXX_ASSERTIONS -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST -Wformat=2 -Werror=format-security -Wno-sign-compare"
|
||||
ARG LDFLAGS="-fuse-ld=lld -m64 -Wl,-s -Wl,-O2 -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--sort-common -Wl,--as-needed -Wl,-z,pack-relative-relocs"
|
||||
|
||||
COPY nginx/nginx.patch /src/nginx.patch
|
||||
COPY nginx/ngx_brotli.patch /src/ngx_brotli.patch
|
||||
COPY nginx/ngx_unbrotli.patch /src/ngx_unbrotli.patch
|
||||
COPY nginx/zstd-nginx-module.patch /src/zstd-nginx-module.patch
|
||||
COPY nginx/attachment.patch /src/attachment.patch
|
||||
WORKDIR /src
|
||||
COPY patches/*.patch /src
|
||||
|
||||
RUN apk upgrade --no-cache -a && \
|
||||
apk add --no-cache ca-certificates build-base clang lld cmake ninja git \
|
||||
linux-headers libatomic_ops-dev openssl-dev pcre2-dev luajit-dev zlib-dev brotli-dev zstd-dev libxslt-dev openldap-dev libmaxminddb-dev
|
||||
apk add --no-cache git make clang lld cmake ninja file \
|
||||
linux-headers libatomic_ops-dev aws-lc aws-lc-dev pcre2-dev luajit-dev zlib-ng-dev brotli-dev zstd-dev libxslt-dev openldap-dev quickjs-ng-dev libmaxminddb-dev clang-dev
|
||||
|
||||
RUN git clone --depth 1 https://github.com/nginx/nginx --branch "$NGINX_VER" /src/nginx && \
|
||||
cd /src/nginx && \
|
||||
@@ -49,6 +47,8 @@ RUN git clone --depth 1 https://github.com/nginx/nginx --branch "$NGINX_VER" /sr
|
||||
git apply /src/nginx/2.patch && \
|
||||
wget -q https://patch-diff.githubusercontent.com/raw/nginx/nginx/pull/689.patch -O /src/nginx/3.patch && \
|
||||
git apply /src/nginx/3.patch && \
|
||||
wget -q https://raw.githubusercontent.com/zlib-ng/patches/refs/heads/master/nginx/"$ZNP_VER"-zlib-ng.patch -O /src/nginx/4.patch && \
|
||||
git apply /src/nginx/4.patch && \
|
||||
git apply /src/nginx.patch && \
|
||||
\
|
||||
git clone --depth 1 https://github.com/google/ngx_brotli --branch "$NB_VER" /src/ngx_brotli && \
|
||||
@@ -65,10 +65,12 @@ RUN git clone --depth 1 https://github.com/nginx/nginx --branch "$NGINX_VER" /sr
|
||||
git apply /src/zstd-nginx-module/1.patch && \
|
||||
git apply /src/zstd-nginx-module/2.patch && \
|
||||
git clone --depth 1 https://github.com/HanadaLee/ngx_http_unzstd_filter_module --branch "$NHUZFM_VER" /src/ngx_http_unzstd_filter_module && \
|
||||
git clone --depth 1 https://github.com/Zoey2936/ngx-fancyindex --branch "$NF_VER" /src/ngx-fancyindex && \
|
||||
git clone --depth 1 https://github.com/aperezdc/ngx-fancyindex --branch "$NF_VER" /src/ngx-fancyindex && \
|
||||
git clone --depth 1 https://github.com/openresty/headers-more-nginx-module --branch "$HMNM_VER" /src/headers-more-nginx-module && \
|
||||
git clone --depth 1 https://github.com/vision5/ngx_devel_kit --branch "$NDK_VER" /src/ngx_devel_kit && \
|
||||
git clone --depth 1 https://github.com/openresty/lua-nginx-module --branch "$LNM_VER" /src/lua-nginx-module && \
|
||||
cd /src/lua-nginx-module && \
|
||||
git apply /src/lua-nginx-module.patch && \
|
||||
\
|
||||
git clone --depth 1 https://github.com/nginx/njs --branch "$NJS_VER" /src/njs && \
|
||||
git clone --depth 1 https://github.com/kvspb/nginx-auth-ldap --branch "$NAL_VER" /src/nginx-auth-ldap && \
|
||||
@@ -188,7 +190,7 @@ COPY COPYING /COPYING
|
||||
WORKDIR /app
|
||||
RUN apk upgrade --no-cache -a && \
|
||||
apk add --no-cache tzdata tini \
|
||||
libssl3 libcrypto3 pcre2 luajit zlib brotli zstd lua5.1-cjson libxml2 libldap libmaxminddb-libs \
|
||||
aws-lc pcre2 luajit zlib-ng brotli zstd lua5.1-cjson libxml2 libldap quickjs-ng-libs libmaxminddb-libs \
|
||||
curl coreutils findutils grep jq openssl shadow su-exec util-linux-misc \
|
||||
bash bash-completion nano \
|
||||
logrotate goaccess fcgi \
|
||||
|
||||
16
README.md
16
README.md
@@ -95,8 +95,12 @@ name: appsec
|
||||
source: appsec
|
||||
labels:
|
||||
type: appsec
|
||||
# if you use openappsec you can enable this
|
||||
#---
|
||||
# If you use open-appsec, uncomment the section below.
|
||||
# If connecting to open-appsec cloud, you must edit the default 'log trigger'
|
||||
# in the cloud dashboard: check "Log to > gateway / agent" and click 'enforce'.
|
||||
# Otherwise, no intrusion events will be logged to the local agent
|
||||
# for CrowdSec to process.
|
||||
#source: file
|
||||
#filenames:
|
||||
# - /opt/openappsec/logs/cp-nano-http-transaction-handler.log*
|
||||
@@ -118,7 +122,7 @@ labels:
|
||||
2. Make other settings (like TLS)
|
||||
3. Create a custom location `/` set the scheme to `path`, put in the path, the press the gear button and fill this in (edit the last line):
|
||||
```
|
||||
location ~* \.php(?:$|/) {
|
||||
location ~* [^/]\.php(?:$|/) {
|
||||
fastcgi_split_path_info ^(.*\.php)(/.*)$;
|
||||
try_files $fastcgi_script_name =404;
|
||||
fastcgi_pass ...; # set this to the address of your php-fpm (socket/tcp): https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass
|
||||
@@ -135,7 +139,7 @@ location ~* \.php(?:$|/) {
|
||||
- If the scheme is set to `path`, a path ending with a `/` will be searched relative to the custom location (is uses nginx alias) and a path ending without a `/` will be searched relative to the main `/` location (it uses nginx root)
|
||||
- Forward Port (optional): port of upstream or php version if scheme is `path`
|
||||
- Send noindex header and block some user agents: This does what is says, it appends a header to all responses which says that the site should not be indexed while blocking requests of crawlers based on the user agent sent with the request
|
||||
- Disable Crowdsec Appsec: this will disable crowdsec appsec only for one host/one location
|
||||
- Disable Crowdsec Appsec: this will disable crowdsec appsec only for one host/one location, this will only do something if appsec is configured
|
||||
- Disable Response Buffering: Most time you want keep buffering enabled, you may want to disable this if you for example want to stream videos and you have a fast and stable connection to the upstream server, this effects the connection from the upstream server to NPMplus
|
||||
- Disable Request Buffering: Most time you want keep buffering enabled, request buffering will always be enabled if crowdsec appsec is enabled, you may want to disable this if you for example want to upload huge files and have a fast and stable connection to the upstream server, this effects the connection from the NPMplus to the upstream server
|
||||
- Enable compression by upstream: this will allow the backend to compress files, I recommend you to keep this disabled, there may be cases where this is needed since otherwise the upstream missbehaves for some reason (like collabora in nextcloud all-in-one)
|
||||
@@ -156,16 +160,16 @@ status_codes:
|
||||
DENY: 403
|
||||
```
|
||||
3. Set the AUTH_REQUEST_ANUBIS_UPSTREAM env in the NPMplus compose.yaml and select anubis in the Auth Request selection, no custom/advanced config/locations needed
|
||||
4. You can override the images used by default by creating a custom location `/.within.website/x/cmd/anubis/static/img` which acts as a file server and serves the files `happy.webp`, `pensive.webp` and `reject.webp`
|
||||
4. You can override the "allow", "checking" and "blocked" images used by default by setting the `AUTH_REQUEST_ANUBIS_USE_CUSTOM_IMAGES` env to true and putting put your custom images as happy.webp, pensive.webp and reject.webp to /opt/npmplus/anubis
|
||||
|
||||
### Tinyauth
|
||||
1. Set the AUTH_REQUEST_TINYAUTH_UPSTREAM and AUTH_REQUEST_TINYAUTH_UPSTREAM env in the NPMplus compose.yaml and select tinyauth in the Auth Request selection, no custom/advanced config/locations needed
|
||||
1. Set the AUTH_REQUEST_TINYAUTH_UPSTREAM and AUTH_REQUEST_TINYAUTH_DOMAIM env in the NPMplus compose.yaml and select tinyauth in the Auth Request selection, no custom/advanced config/locations needed
|
||||
|
||||
### Authelia (modern)
|
||||
1. Set the AUTH_REQUEST_AUTHELIA_UPSTREAM env in the NPMplus compose.yaml and select authelia (modern) in the Auth Request selection, no custom/advanced config/locations needed
|
||||
|
||||
### Authentik
|
||||
1. Set the AUTH_REQUEST_AUTHENTIK_UPSTREAM (and optional AUTH_REQUEST_AUTHENTIK_DOMAIN) env in the NPMplus compose.yaml and select authentik/authentik-send-basic-auth in the Auth Request selection, no custom/advanced config/locations needed
|
||||
1. Set the AUTH_REQUEST_AUTHENTIK_UPSTREAM env (and optional AUTH_REQUEST_AUTHENTIK_DOMAIN env if you use the "domain level" variant in authentik, do not set this env if you use the "single application" variant) in the NPMplus compose.yaml and select authentik/authentik-send-basic-auth in the Auth Request selection, no custom/advanced config/locations needed
|
||||
|
||||
## Load Balancing
|
||||
1. Open and edit this file: `/opt/npmplus/custom_nginx/http_top.conf` (or `/opt/npmplus/custom_nginx/stream_top.conf` for streams), if you changed /opt/npmplus to a different path make sure to change the path to fit
|
||||
|
||||
@@ -8,7 +8,11 @@ import mainRoutes from "./routes/main.js";
|
||||
* App
|
||||
*/
|
||||
const app = express();
|
||||
app.use(fileUpload());
|
||||
app.use(
|
||||
fileUpload({
|
||||
limits: { fileSize: 1024 * 1024 },
|
||||
}),
|
||||
);
|
||||
app.use(cookieParser());
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
@@ -21,6 +25,25 @@ app.disable("x-powered-by");
|
||||
app.enable("trust proxy", ["loopback", "linklocal", "uniquelocal"]);
|
||||
app.enable("strict routing");
|
||||
|
||||
app.use((req, res, next) => {
|
||||
if (["same-origin", undefined, "none"].includes(req.get("sec-fetch-site"))) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (
|
||||
req.method === "GET" &&
|
||||
req.path === "/api/oidc/callback" &&
|
||||
req.get("sec-fetch-mode") === "navigate" &&
|
||||
req.get("sec-fetch-dest") === "document"
|
||||
) {
|
||||
return next();
|
||||
}
|
||||
|
||||
res.status(403).json({
|
||||
error: { message: "Rejected Sec-Fetch-Site Value." },
|
||||
});
|
||||
});
|
||||
|
||||
// pretty print JSON when not live
|
||||
app.set("json spaces", 2);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/2.3.15/schema.json",
|
||||
"$schema": "https://biomejs.dev/schemas/2.4.5/schema.json",
|
||||
"vcs": {
|
||||
"enabled": true,
|
||||
"clientKind": "git",
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
"credentials": "dns_aliyun_access_key = 12345678\ndns_aliyun_access_key_secret = 1234567890abcdef1234567890abcdef",
|
||||
"full_plugin_name": "dns-aliyun"
|
||||
},
|
||||
"arvan": {
|
||||
"name": "ArvanCloud",
|
||||
"package_name": "certbot-dns-arvan",
|
||||
"credentials": "dns_arvan_key = Apikey xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
|
||||
"full_plugin_name": "dns-arvan"
|
||||
},
|
||||
"azure": {
|
||||
"name": "Azure",
|
||||
"package_name": "certbot-dns-azure",
|
||||
|
||||
@@ -164,6 +164,10 @@ const internal2fa = {
|
||||
|
||||
const codeTrim = code.trim();
|
||||
|
||||
if (codeTrim.length !== 6 && codeTrim.length !== 8) {
|
||||
throw new errs.ValidationError("Invalid verification code");
|
||||
}
|
||||
|
||||
// Try TOTP code first, if it's 6 chars. it will throw errors if it's not 6 chars
|
||||
// and the backup codes are 8 chars.
|
||||
if (codeTrim.length === 6) {
|
||||
@@ -307,6 +311,10 @@ const internal2fa = {
|
||||
|
||||
const tokenTrim = token.trim();
|
||||
|
||||
if (tokenTrim.length !== 6 && tokenTrim.length !== 8) {
|
||||
throw new errs.ValidationError("Invalid verification code");
|
||||
}
|
||||
|
||||
// Try TOTP code first, if it's 6 chars. it will throw errors if it's not 6 chars
|
||||
// and the backup codes are 8 chars.
|
||||
if (tokenTrim.length === 6) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { createPrivateKey, X509Certificate } from "node:crypto";
|
||||
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { domainToASCII } from "node:url";
|
||||
import archiver from "archiver";
|
||||
import dayjs from "dayjs";
|
||||
import _ from "lodash";
|
||||
import moment from "moment";
|
||||
import tempWrite from "temp-write";
|
||||
import dnsPlugins from "../certbot/dns-plugins.json" with { type: "json" };
|
||||
import { installPlugin } from "../lib/certbot.js";
|
||||
import error from "../lib/error.js";
|
||||
@@ -85,7 +86,7 @@ const internalCertificate = {
|
||||
.where("id", certificate.id)
|
||||
.andWhere("provider", "letsencrypt")
|
||||
.patch({
|
||||
expires_on: moment(certInfo.dates.to, "X").format("YYYY-MM-DD HH:mm:ss"),
|
||||
expires_on: dayjs.unix(certInfo.dates.to).format("YYYY-MM-DD HH:mm:ss"),
|
||||
});
|
||||
} catch (err) {
|
||||
// Don't want to stop the train here, just log the error
|
||||
@@ -137,7 +138,7 @@ const internalCertificate = {
|
||||
const savedRow = await certificateModel
|
||||
.query()
|
||||
.patchAndFetchById(certificate.id, {
|
||||
expires_on: moment(certInfo.dates.to, "X").format("YYYY-MM-DD HH:mm:ss"),
|
||||
expires_on: dayjs.unix(certInfo.dates.to).format("YYYY-MM-DD HH:mm:ss"),
|
||||
})
|
||||
.then(utils.omitRow(omissions()));
|
||||
|
||||
@@ -361,8 +362,8 @@ const internalCertificate = {
|
||||
// Revoke the cert
|
||||
await internalCertificate.revokeCertbot(row);
|
||||
} else {
|
||||
fs.rmSync(`/data/tls/custom/npm-${row.id}`, { force: true, recursive: true });
|
||||
fs.rmSync(`/data/tls/custom/npm-${row.id}.der`, { force: true });
|
||||
await rm(`/data/tls/custom/npm-${row.id}`, { force: true, recursive: true });
|
||||
await rm(`/data/tls/custom/npm-${row.id}.der`, { force: true });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
@@ -430,43 +431,17 @@ const internalCertificate = {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
writeCustomCert: async (certificate) => {
|
||||
if (certificate.provider === "letsencrypt") {
|
||||
throw new Error("Refusing to write certbot certs here");
|
||||
}
|
||||
|
||||
logger.info("Writing Custom Certificate:", certificate.id);
|
||||
|
||||
const dir = `/data/tls/custom/npm-${certificate.id}`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
if (certificate.provider === "letsencrypt") {
|
||||
reject(new Error("Refusing to write certbot certs here"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!fs.existsSync(dir)) {
|
||||
fs.mkdirSync(dir);
|
||||
}
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
|
||||
fs.writeFile(`${dir}/fullchain.pem`, certificate.meta.certificate, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}).then(() => {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.writeFile(`${dir}/privkey.pem`, certificate.meta.certificate_key, (err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
await mkdir(dir, { recursive: true });
|
||||
await writeFile(`${dir}/fullchain.pem`, certificate.meta.certificate);
|
||||
await writeFile(`${dir}/privkey.pem`, certificate.meta.certificate_key);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -491,40 +466,22 @@ const internalCertificate = {
|
||||
* @param {Object} data.files
|
||||
* @returns {Promise}
|
||||
*/
|
||||
validate: (data) => {
|
||||
// Put file contents into an object
|
||||
const files = {};
|
||||
_.map(data.files, (file, name) => {
|
||||
if (internalCertificate.allowedSslFiles.indexOf(name) !== -1) {
|
||||
files[name] = file.data.toString();
|
||||
validate: async (data) => {
|
||||
const finalData = {};
|
||||
for (const [name, file] of Object.entries(data.files)) {
|
||||
if (internalCertificate.allowedSslFiles.includes(name)) {
|
||||
const content = file.data.toString();
|
||||
let res;
|
||||
if (name === "certificate_key") {
|
||||
res = await internalCertificate.checkPrivateKey(content);
|
||||
} else {
|
||||
res = await internalCertificate.getCertificateInfo(content, true);
|
||||
}
|
||||
finalData[name] = res;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// For each file, create a temp file and write the contents to it
|
||||
// Then test it depending on the file type
|
||||
const promises = [];
|
||||
_.map(files, (content, type) => {
|
||||
promises.push(
|
||||
new Promise((resolve) => {
|
||||
if (type === "certificate_key") {
|
||||
resolve(internalCertificate.checkPrivateKey(content));
|
||||
} else {
|
||||
// this should handle `certificate` and intermediate certificate
|
||||
resolve(internalCertificate.getCertificateInfo(content, true));
|
||||
}
|
||||
}).then((res) => {
|
||||
return { [type]: res };
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
return Promise.all(promises).then((files) => {
|
||||
let data = {};
|
||||
_.each(files, (file) => {
|
||||
data = _.assign({}, data, file);
|
||||
});
|
||||
return data;
|
||||
});
|
||||
return finalData;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -554,8 +511,8 @@ const internalCertificate = {
|
||||
|
||||
const certificate = await internalCertificate.update(access, {
|
||||
id: data.id,
|
||||
expires_on: moment(validations.certificate.dates.to, "X").format("YYYY-MM-DD HH:mm:ss"),
|
||||
domain_names: [validations.certificate.cn],
|
||||
expires_on: dayjs.unix(validations.certificate.dates.to).format("YYYY-MM-DD HH:mm:ss"),
|
||||
domain_names: validations.certificate.cn,
|
||||
meta: _.clone(row.meta), // Prevent the update method from changing this value that we'll use later
|
||||
});
|
||||
|
||||
@@ -571,24 +528,10 @@ const internalCertificate = {
|
||||
* @param {String} privateKey This is the entire key contents as a string
|
||||
*/
|
||||
checkPrivateKey: async (privateKey) => {
|
||||
const filepath = await tempWrite(privateKey);
|
||||
const failTimeout = setTimeout(() => {
|
||||
throw new error.ValidationError(
|
||||
"Result Validation Error: Validation timed out. This could be due to the key being passphrase-protected.",
|
||||
);
|
||||
}, 10000);
|
||||
|
||||
try {
|
||||
const result = await utils.execFile("openssl", ["pkey", "-in", filepath, "-check", "-noout"]);
|
||||
clearTimeout(failTimeout);
|
||||
if (!result.toLowerCase().includes("key is valid")) {
|
||||
throw new error.ValidationError(`Result Validation Error: ${result}`);
|
||||
}
|
||||
fs.unlinkSync(filepath);
|
||||
createPrivateKey(privateKey);
|
||||
return true;
|
||||
} catch (err) {
|
||||
clearTimeout(failTimeout);
|
||||
fs.unlinkSync(filepath);
|
||||
throw new error.ValidationError(`Certificate Key is not valid (${err.message})`, err);
|
||||
}
|
||||
},
|
||||
@@ -601,77 +544,38 @@ const internalCertificate = {
|
||||
* @param {Boolean} [throwExpired] Throw when the certificate is out of date
|
||||
*/
|
||||
getCertificateInfo: async (certificate, throwExpired) => {
|
||||
const filepath = await tempWrite(certificate);
|
||||
try {
|
||||
const certData = await internalCertificate.getCertificateInfoFromFile(filepath, throwExpired);
|
||||
fs.unlinkSync(filepath);
|
||||
return certData;
|
||||
} catch (err) {
|
||||
fs.unlinkSync(filepath);
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Uses the openssl command to both validate and get info out of the certificate.
|
||||
* It will save the file to disk first, then run commands on it, then delete the file.
|
||||
*
|
||||
* @param {String} certificateFile The file location on disk
|
||||
* @param {Boolean} [throw_expired] Throw when the certificate is out of date
|
||||
*/
|
||||
getCertificateInfoFromFile: async (certificateFile, throw_expired) => {
|
||||
const certData = {};
|
||||
|
||||
try {
|
||||
const result = await utils.execFile("openssl", ["x509", "-in", certificateFile, "-subject", "-noout"]);
|
||||
// Examples:
|
||||
// subject=CN = *.jc21.com
|
||||
// subject=CN = something.example.com
|
||||
const regex = /(?:subject=)?[^=]+=\s*(\S+)/gim;
|
||||
const match = regex.exec(result);
|
||||
if (match && typeof match[1] !== "undefined") {
|
||||
certData.cn = match[1];
|
||||
}
|
||||
const cert = new X509Certificate(certificate);
|
||||
|
||||
const result2 = await utils.execFile("openssl", ["x509", "-in", certificateFile, "-issuer", "-noout"]);
|
||||
// Examples:
|
||||
// issuer=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
|
||||
// issuer=C = US, O = Let's Encrypt, CN = E5
|
||||
// issuer=O = NginxProxyManager, CN = NginxProxyManager Intermediate CA","O = NginxProxyManager, CN = NginxProxyManager Intermediate CA
|
||||
const regex2 = /^(?:issuer=)?(.*)$/gim;
|
||||
const match2 = regex2.exec(result2);
|
||||
if (match2 && typeof match2[1] !== "undefined") {
|
||||
certData.issuer = match2[1];
|
||||
}
|
||||
|
||||
const result3 = await utils.execFile("openssl", ["x509", "-in", certificateFile, "-dates", "-noout"]);
|
||||
// notBefore=Jul 14 04:04:29 2018 GMT
|
||||
// notAfter=Oct 12 04:04:29 2018 GMT
|
||||
let validFrom = null;
|
||||
let validTo = null;
|
||||
|
||||
const lines = result3.split("\n");
|
||||
lines.map((str) => {
|
||||
const regex = /^(\S+)=(.*)$/gim;
|
||||
const match = regex.exec(str.trim());
|
||||
|
||||
if (match && typeof match[2] !== "undefined") {
|
||||
const date = Number.parseInt(moment(match[2], "MMM DD HH:mm:ss YYYY z").format("X"), 10);
|
||||
|
||||
if (match[1].toLowerCase() === "notbefore") {
|
||||
validFrom = date;
|
||||
} else if (match[1].toLowerCase() === "notafter") {
|
||||
validTo = date;
|
||||
}
|
||||
if (cert.subjectAltName) {
|
||||
certData.cn = cert.subjectAltName.split(", ").map((entry) => {
|
||||
const firstColonIdx = entry.indexOf(":");
|
||||
return firstColonIdx === -1 ? entry.trim() : entry.substring(firstColonIdx + 1).trim();
|
||||
});
|
||||
} else {
|
||||
const cnMatch = /\bCN=([^\n]+)/i.exec(cert.subject);
|
||||
if (cnMatch?.[1]) {
|
||||
certData.cn = [cnMatch[1].trim()];
|
||||
} else {
|
||||
certData.cn = [];
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!validFrom || !validTo) {
|
||||
throw new error.ValidationError(`Could not determine dates from certificate: ${result}`);
|
||||
}
|
||||
|
||||
if (throw_expired && validTo < Number.parseInt(moment().format("X"), 10)) {
|
||||
if (cert.issuer) {
|
||||
certData.issuer = cert.issuer.replace(/\n/g, ", ");
|
||||
}
|
||||
|
||||
const validFrom = Math.floor(new Date(cert.validFrom).getTime() / 1000);
|
||||
const validTo = Math.floor(new Date(cert.validTo).getTime() / 1000);
|
||||
|
||||
if (Number.isNaN(validFrom) || Number.isNaN(validTo)) {
|
||||
throw new error.ValidationError("Could not determine dates from certificate");
|
||||
}
|
||||
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
if (throwExpired && validTo < now) {
|
||||
throw new error.ValidationError("Certificate has expired");
|
||||
}
|
||||
|
||||
@@ -686,6 +590,18 @@ const internalCertificate = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Uses the openssl command to both validate and get info out of the certificate.
|
||||
* It will save the file to disk first, then run commands on it, then delete the file.
|
||||
*
|
||||
* @param {String} certificateFile The file location on disk
|
||||
* @param {Boolean} [throwExpired] Throw when the certificate is out of date
|
||||
*/
|
||||
getCertificateInfoFromFile: async (certificateFile, throwExpired) => {
|
||||
const certContent = await readFile(certificateFile);
|
||||
return internalCertificate.getCertificateInfo(certContent, throwExpired);
|
||||
},
|
||||
|
||||
/**
|
||||
* Cleans the tls keys from the meta object and sets them
|
||||
* @param {String} email the email address to use for registration to "true"
|
||||
@@ -752,7 +668,7 @@ const internalCertificate = {
|
||||
);
|
||||
|
||||
const credentialsLocation = `/tmp/certbot-credentials/credentials-${certificate.id}`;
|
||||
fs.writeFileSync(credentialsLocation, certificate.meta.dns_provider_credentials, { mode: 0o600 });
|
||||
await writeFile(credentialsLocation, certificate.meta.dns_provider_credentials, { mode: 0o600 });
|
||||
|
||||
try {
|
||||
const result = await utils.execFile("certbot", [
|
||||
@@ -778,8 +694,7 @@ const internalCertificate = {
|
||||
logger.info(result);
|
||||
return result;
|
||||
} catch (err) {
|
||||
// Don't fail if file does not exist, so no need for action in the callback
|
||||
fs.unlink(credentialsLocation, () => {});
|
||||
await rm(credentialsLocation, { force: true });
|
||||
throw err;
|
||||
}
|
||||
},
|
||||
@@ -805,7 +720,7 @@ const internalCertificate = {
|
||||
);
|
||||
|
||||
const updatedCertificate = await certificateModel.query().patchAndFetchById(certificate.id, {
|
||||
expires_on: moment(certInfo.dates.to, "X").format("YYYY-MM-DD HH:mm:ss"),
|
||||
expires_on: dayjs.unix(certInfo.dates.to).format("YYYY-MM-DD HH:mm:ss"),
|
||||
});
|
||||
|
||||
// Add to audit log
|
||||
@@ -929,7 +844,7 @@ const internalCertificate = {
|
||||
"unspecified",
|
||||
"--delete-after-revoke",
|
||||
]);
|
||||
fs.rmSync(`/data/tls/certbot/live/npm-${certificate.id}.der`, { force: true });
|
||||
await rm(`/data/tls/certbot/live/npm-${certificate.id}.der`, { force: true });
|
||||
logger.info(result);
|
||||
return result;
|
||||
} catch (err) {
|
||||
@@ -953,7 +868,7 @@ const internalCertificate = {
|
||||
const testChallengeDir = "/data/tls/certbot/acme-challenge/.well-known/acme-challenge";
|
||||
const testChallengeFile = `${testChallengeDir}/test-challenge`;
|
||||
fs.mkdirSync(testChallengeDir, { recursive: true });
|
||||
fs.writeFileSync(testChallengeFile, "Success", { encoding: "utf8" });
|
||||
await writeFile(testChallengeFile, "Success", { encoding: "utf8" });
|
||||
|
||||
const results = [];
|
||||
|
||||
@@ -965,7 +880,7 @@ const internalCertificate = {
|
||||
}
|
||||
|
||||
// Remove the test challenge file
|
||||
fs.unlinkSync(testChallengeFile);
|
||||
await rm(testChallengeFile, { force: true });
|
||||
|
||||
return results;
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fs from "node:fs";
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import { dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import utils from "../lib/utils.js";
|
||||
@@ -82,20 +82,21 @@ const internalIpRanges = {
|
||||
generateConfig: async (ip_ranges) => {
|
||||
try {
|
||||
const renderEngine = utils.getRenderEngine();
|
||||
const template = fs.readFileSync(`${__dirname}/../templates/ip_ranges.conf`, { encoding: "utf8" });
|
||||
const template = await readFile(`${__dirname}/../templates/ip_ranges.conf`, { encoding: "utf8" });
|
||||
const newConfig = await renderEngine.parseAndRender(template, { ip_ranges: ip_ranges });
|
||||
const filePath = "/usr/local/nginx/conf/conf.d/ip_ranges.conf";
|
||||
|
||||
if (fs.existsSync("/usr/local/nginx/conf/conf.d/ip_ranges.conf")) {
|
||||
const oldConfig = fs.readFileSync("/usr/local/nginx/conf/conf.d/ip_ranges.conf", {
|
||||
try {
|
||||
const oldConfig = await readFile(filePath, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
if (oldConfig === newConfig) {
|
||||
logger.info("Not updating Cloudflared IPs");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
||||
fs.writeFileSync("/usr/local/nginx/conf/conf.d/ip_ranges.conf", newConfig, { encoding: "utf8" });
|
||||
await writeFile(filePath, newConfig, { encoding: "utf8" });
|
||||
logger.info("Updated Cloudflared IPs");
|
||||
return true;
|
||||
} catch (err) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import fs from "node:fs";
|
||||
import { readFile, rename, rm, writeFile } from "node:fs/promises";
|
||||
import { dirname } from "node:path";
|
||||
import { domainToASCII, fileURLToPath } from "node:url";
|
||||
import _ from "lodash";
|
||||
@@ -24,111 +24,81 @@ const internalNginx = {
|
||||
* @param {Object} host
|
||||
* @returns {Promise}
|
||||
*/
|
||||
configure: (model, host_type, host) => {
|
||||
configure: async (model, host_type, host) => {
|
||||
let combined_meta = {};
|
||||
|
||||
return internalNginx
|
||||
.test()
|
||||
.then(() => {
|
||||
return internalNginx.deleteConfig(host_type, host);
|
||||
})
|
||||
.then(() => {
|
||||
return internalNginx.reload();
|
||||
})
|
||||
.then(() => {
|
||||
return internalNginx.generateConfig(host_type, host);
|
||||
})
|
||||
.then(() => {
|
||||
// Test nginx again and update meta with result
|
||||
return internalNginx
|
||||
.test()
|
||||
.then(() => {
|
||||
// nginx is ok
|
||||
combined_meta = _.assign({}, host.meta, {
|
||||
nginx_online: true,
|
||||
nginx_err: null,
|
||||
});
|
||||
await internalNginx.deleteConfig(host_type, host);
|
||||
await internalNginx.generateConfig(host_type, host);
|
||||
|
||||
return model.query().where("id", host.id).patch({
|
||||
meta: combined_meta,
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
logger.error(err.message);
|
||||
|
||||
// config is bad, update meta and rename config
|
||||
combined_meta = _.assign({}, host.meta, {
|
||||
nginx_online: false,
|
||||
nginx_err: err.message,
|
||||
});
|
||||
|
||||
return model
|
||||
.query()
|
||||
.where("id", host.id)
|
||||
.patch({
|
||||
meta: combined_meta,
|
||||
})
|
||||
.then(() => {
|
||||
internalNginx.renameConfigAsError(host_type, host);
|
||||
});
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return internalNginx.reload();
|
||||
})
|
||||
.then(() => {
|
||||
return combined_meta;
|
||||
try {
|
||||
await internalNginx.test();
|
||||
combined_meta = _.assign({}, host.meta, {
|
||||
nginx_online: true,
|
||||
nginx_err: null,
|
||||
});
|
||||
|
||||
await model.query().where("id", host.id).patch({
|
||||
meta: combined_meta,
|
||||
});
|
||||
} catch (err) {
|
||||
logger.error(err.message);
|
||||
|
||||
// config is bad, update meta and rename config
|
||||
combined_meta = _.assign({}, host.meta, {
|
||||
nginx_online: false,
|
||||
nginx_err: err.message,
|
||||
});
|
||||
|
||||
await model.query().where("id", host.id).patch({
|
||||
meta: combined_meta,
|
||||
});
|
||||
|
||||
await internalNginx.renameConfigAsError(host_type, host);
|
||||
}
|
||||
|
||||
await internalNginx.reload();
|
||||
return combined_meta;
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
test: () => {
|
||||
test: async () => {
|
||||
return utils.execFile("nginx", ["-tq"]);
|
||||
},
|
||||
|
||||
/**
|
||||
* @returns {Promise}
|
||||
*/
|
||||
reload: () => {
|
||||
const promises = [];
|
||||
|
||||
reload: async () => {
|
||||
if (process.env.ACME_OCSP_STAPLING === "true") {
|
||||
promises.push(
|
||||
utils
|
||||
.execFile("certbot-ocsp-fetcher.sh", [
|
||||
"-c",
|
||||
"/data/tls/certbot/live",
|
||||
"-o",
|
||||
"/data/tls/certbot/live",
|
||||
"--no-reload-webserver",
|
||||
"--quiet",
|
||||
])
|
||||
.catch(() => {}),
|
||||
);
|
||||
try {
|
||||
await utils.execFile("certbot-ocsp-fetcher.sh", [
|
||||
"-c",
|
||||
"/data/tls/certbot/live",
|
||||
"-o",
|
||||
"/data/tls/certbot/live",
|
||||
"--no-reload-webserver",
|
||||
"--quiet",
|
||||
]);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (process.env.CUSTOM_OCSP_STAPLING === "true") {
|
||||
promises.push(
|
||||
utils
|
||||
.execFile("certbot-ocsp-fetcher.sh", [
|
||||
"-c",
|
||||
"/data/tls/custom",
|
||||
"-o",
|
||||
"/data/tls/custom",
|
||||
"--no-reload-webserver",
|
||||
"--quiet",
|
||||
])
|
||||
.catch(() => {}),
|
||||
);
|
||||
try {
|
||||
await utils.execFile("certbot-ocsp-fetcher.sh", [
|
||||
"-c",
|
||||
"/data/tls/custom",
|
||||
"-o",
|
||||
"/data/tls/custom",
|
||||
"--no-reload-webserver",
|
||||
"--quiet",
|
||||
]);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
return Promise.all(promises).finally(() => {
|
||||
return internalNginx.test().then(() => {
|
||||
return utils.execFile("nginx", ["-s", "reload"]);
|
||||
});
|
||||
});
|
||||
await internalNginx.test();
|
||||
return utils.execFile("nginx", ["-s", "reload"]);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -148,45 +118,40 @@ const internalNginx = {
|
||||
* @param {Object} host
|
||||
* @returns {Promise}
|
||||
*/
|
||||
renderLocations: (host) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let template;
|
||||
renderLocations: async (host) => {
|
||||
let template;
|
||||
|
||||
try {
|
||||
template = fs.readFileSync(`${__dirname}/../templates/_proxy_host_custom_location.conf`, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
} catch (err) {
|
||||
reject(new errs.ConfigurationError(err.message));
|
||||
return;
|
||||
try {
|
||||
template = await readFile(`${__dirname}/../templates/_proxy_host_custom_location.conf`, {
|
||||
encoding: "utf8",
|
||||
});
|
||||
} catch (err) {
|
||||
throw new errs.ConfigurationError(err.message);
|
||||
}
|
||||
|
||||
const renderEngine = utils.getRenderEngine();
|
||||
let renderedLocations = "";
|
||||
|
||||
for (const location of host.locations) {
|
||||
if (location.npmplus_enabled === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const renderEngine = utils.getRenderEngine();
|
||||
let renderedLocations = "";
|
||||
if (
|
||||
location.forward_host.indexOf("/") > -1 &&
|
||||
!location.forward_host.startsWith("/") &&
|
||||
!location.forward_host.startsWith("unix")
|
||||
) {
|
||||
const split = location.forward_host.split("/");
|
||||
|
||||
const locationRendering = async () => {
|
||||
for (let i = 0; i < host.locations.length; i++) {
|
||||
if (host.locations[i].npmplus_enabled === false) {
|
||||
continue;
|
||||
}
|
||||
location.forward_host = split.shift();
|
||||
location.forward_path = `/${split.join("/")}`;
|
||||
}
|
||||
|
||||
if (
|
||||
host.locations[i].forward_host.indexOf("/") > -1 &&
|
||||
!host.locations[i].forward_host.startsWith("/") &&
|
||||
!host.locations[i].forward_host.startsWith("unix")
|
||||
) {
|
||||
const split = host.locations[i].forward_host.split("/");
|
||||
renderedLocations += await renderEngine.parseAndRender(template, location);
|
||||
}
|
||||
|
||||
host.locations[i].forward_host = split.shift();
|
||||
host.locations[i].forward_path = `/${split.join("/")}`;
|
||||
}
|
||||
|
||||
renderedLocations += await renderEngine.parseAndRender(template, host.locations[i]);
|
||||
}
|
||||
};
|
||||
|
||||
locationRendering().then(() => resolve(renderedLocations));
|
||||
});
|
||||
return renderedLocations;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -194,132 +159,97 @@ const internalNginx = {
|
||||
* @param {Object} host
|
||||
* @returns {Promise}
|
||||
*/
|
||||
generateConfig: (host_type, host_row) => {
|
||||
generateConfig: async (host_type, host_row) => {
|
||||
// Prevent modifying the original object:
|
||||
const host = JSON.parse(JSON.stringify(host_row));
|
||||
const nice_host_type = internalNginx.getFileFriendlyHostType(host_type);
|
||||
|
||||
const renderEngine = utils.getRenderEngine();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let template = null;
|
||||
const filename = internalNginx.getConfigName(nice_host_type, host.id);
|
||||
let template = null;
|
||||
const filename = internalNginx.getConfigName(nice_host_type, host.id);
|
||||
|
||||
try {
|
||||
template = fs.readFileSync(`${__dirname}/../templates/${nice_host_type}.conf`, { encoding: "utf8" });
|
||||
} catch (err) {
|
||||
reject(new errs.ConfigurationError(err.message));
|
||||
return;
|
||||
}
|
||||
|
||||
let locationsPromise;
|
||||
let origLocations;
|
||||
|
||||
// Manipulate the data a bit before sending it to the template
|
||||
if (nice_host_type !== "default") {
|
||||
host.use_default_location = true;
|
||||
if (typeof host.advanced_config !== "undefined" && host.advanced_config) {
|
||||
host.use_default_location = !internalNginx.advancedConfigHasDefaultLocation(host.advanced_config);
|
||||
}
|
||||
}
|
||||
|
||||
// For redirection hosts, if the scheme is not http or https, set it to $scheme
|
||||
if (
|
||||
nice_host_type === "redirection_host" &&
|
||||
["http", "https"].indexOf(host.forward_scheme.toLowerCase()) === -1
|
||||
) {
|
||||
host.forward_scheme = "$scheme";
|
||||
}
|
||||
|
||||
if (host.locations) {
|
||||
//logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2));
|
||||
origLocations = [].concat(host.locations);
|
||||
locationsPromise = internalNginx.renderLocations(host).then((renderedLocations) => {
|
||||
host.locations = renderedLocations;
|
||||
});
|
||||
|
||||
// Allow someone who is using / custom location path to use it, and skip the default / location
|
||||
_.map(host.locations, (location) => {
|
||||
if (location.path === "/" && location.location_type !== "= ") {
|
||||
host.use_default_location = false;
|
||||
}
|
||||
if (location.npmplus_auth_request === "anubis") {
|
||||
host.create_anubis_locations = true;
|
||||
}
|
||||
if (location.npmplus_auth_request === "tinyauth") {
|
||||
host.create_tinyauth_locations = true;
|
||||
}
|
||||
if (location.npmplus_auth_request === "authelia") {
|
||||
host.create_authelia_locations = true;
|
||||
}
|
||||
if (
|
||||
location.npmplus_auth_request === "authentik" ||
|
||||
location.npmplus_auth_request === "authentik-send-basic-auth"
|
||||
) {
|
||||
host.create_authentik_locations = true;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
locationsPromise = Promise.resolve();
|
||||
}
|
||||
|
||||
if (
|
||||
host.forward_host &&
|
||||
host.forward_host.indexOf("/") > -1 &&
|
||||
!host.forward_host.startsWith("/") &&
|
||||
!host.forward_host.startsWith("unix")
|
||||
) {
|
||||
const split = host.forward_host.split("/");
|
||||
|
||||
host.forward_host = split.shift();
|
||||
host.forward_path = `/${split.join("/")}`;
|
||||
}
|
||||
|
||||
if (host.domain_names) {
|
||||
host.server_names = host.domain_names.map((domain_name) => domainToASCII(domain_name) || domain_name);
|
||||
}
|
||||
|
||||
host.env = process.env;
|
||||
|
||||
locationsPromise.then(() => {
|
||||
renderEngine
|
||||
.parseAndRender(template, host)
|
||||
.then((config_text) => {
|
||||
fs.writeFileSync(filename, config_text, { encoding: "utf8" });
|
||||
debug(logger, "Wrote config:", filename);
|
||||
|
||||
// Restore locations array
|
||||
host.locations = origLocations;
|
||||
|
||||
resolve(true);
|
||||
})
|
||||
.catch((err) => {
|
||||
debug(logger, `Could not write ${filename}:`, err.message);
|
||||
reject(new errs.ConfigurationError(err.message));
|
||||
})
|
||||
.then(() => {
|
||||
if (process.env.DISABLE_NGINX_BEAUTIFIER === "false") {
|
||||
utils.execFile("nginxbeautifier", ["-s", "4", filename]).catch(() => {});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* A simple wrapper around unlinkSync that writes to the logger
|
||||
*
|
||||
* @param {String} filename
|
||||
*/
|
||||
deleteFile: (filename) => {
|
||||
if (!fs.existsSync(filename)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
debug(logger, `Deleting file: ${filename}`);
|
||||
fs.unlinkSync(filename);
|
||||
template = await readFile(`${__dirname}/../templates/${nice_host_type}.conf`, { encoding: "utf8" });
|
||||
} catch (err) {
|
||||
debug(logger, "Could not delete file:", JSON.stringify(err, null, 2));
|
||||
throw new errs.ConfigurationError(err.message);
|
||||
}
|
||||
|
||||
let origLocations;
|
||||
|
||||
// Manipulate the data a bit before sending it to the template
|
||||
if (nice_host_type !== "default") {
|
||||
host.use_default_location = true;
|
||||
if (typeof host.advanced_config !== "undefined" && host.advanced_config) {
|
||||
host.use_default_location = !internalNginx.advancedConfigHasDefaultLocation(host.advanced_config);
|
||||
}
|
||||
}
|
||||
|
||||
// For redirection hosts, if the scheme is not http or https, set it to $scheme
|
||||
if (
|
||||
nice_host_type === "redirection_host" &&
|
||||
["http", "https"].indexOf(host.forward_scheme.toLowerCase()) === -1
|
||||
) {
|
||||
host.forward_scheme = "$scheme";
|
||||
}
|
||||
|
||||
if (host.locations) {
|
||||
_.map(host.locations, (location) => {
|
||||
if (location.path === "/" && location.location_type !== "= " && location.npmplus_enabled !== false) {
|
||||
host.use_default_location = false;
|
||||
}
|
||||
if (location.npmplus_auth_request === "anubis") {
|
||||
host.create_anubis_locations = true;
|
||||
}
|
||||
if (location.npmplus_auth_request === "tinyauth") {
|
||||
host.create_tinyauth_locations = true;
|
||||
}
|
||||
if (location.npmplus_auth_request === "authelia") {
|
||||
host.create_authelia_locations = true;
|
||||
}
|
||||
if (
|
||||
location.npmplus_auth_request === "authentik" ||
|
||||
location.npmplus_auth_request === "authentik-send-basic-auth"
|
||||
) {
|
||||
host.create_authentik_locations = true;
|
||||
}
|
||||
});
|
||||
|
||||
host.locations = await internalNginx.renderLocations(host);
|
||||
}
|
||||
|
||||
if (
|
||||
host.forward_host &&
|
||||
host.forward_host.indexOf("/") > -1 &&
|
||||
!host.forward_host.startsWith("/") &&
|
||||
!host.forward_host.startsWith("unix")
|
||||
) {
|
||||
const split = host.forward_host.split("/");
|
||||
|
||||
host.forward_host = split.shift();
|
||||
host.forward_path = `/${split.join("/")}`;
|
||||
}
|
||||
|
||||
if (host.domain_names) {
|
||||
host.server_names = host.domain_names.map((domain_name) => domainToASCII(domain_name) || domain_name);
|
||||
}
|
||||
|
||||
host.env = process.env;
|
||||
|
||||
try {
|
||||
const config_text = await renderEngine.parseAndRender(template, host);
|
||||
|
||||
await writeFile(filename, config_text, { encoding: "utf8" });
|
||||
debug(logger, "Wrote config:", filename);
|
||||
|
||||
if (process.env.DISABLE_NGINX_BEAUTIFIER === "false") {
|
||||
await utils.execFile("nginxbeautifier", ["-s", "4", filename]).catch(() => {});
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (err) {
|
||||
debug(logger, `Could not write ${filename}:`, err.message);
|
||||
throw new errs.ConfigurationError(err.message);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -337,17 +267,22 @@ const internalNginx = {
|
||||
* @param {Object} [host]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
deleteConfig: (host_type, host) => {
|
||||
deleteConfig: async (host_type, host) => {
|
||||
const config_file = internalNginx.getConfigName(
|
||||
internalNginx.getFileFriendlyHostType(host_type),
|
||||
typeof host === "undefined" ? 0 : host.id,
|
||||
);
|
||||
|
||||
return new Promise((resolve /*, reject*/) => {
|
||||
internalNginx.deleteFile(config_file);
|
||||
internalNginx.deleteFile(`${config_file}.err`);
|
||||
resolve();
|
||||
});
|
||||
const filesToDelete = [config_file, `${config_file}.err`];
|
||||
|
||||
for (const filename of filesToDelete) {
|
||||
try {
|
||||
debug(logger, `Deleting file: ${filename}`);
|
||||
await rm(filename, { force: true });
|
||||
} catch (err) {
|
||||
debug(logger, "Could not delete file:", JSON.stringify(err, null, 2));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -355,17 +290,15 @@ const internalNginx = {
|
||||
* @param {Object} [host]
|
||||
* @returns {Promise}
|
||||
*/
|
||||
renameConfigAsError: (host_type, host) => {
|
||||
renameConfigAsError: async (host_type, host) => {
|
||||
const config_file = internalNginx.getConfigName(
|
||||
internalNginx.getFileFriendlyHostType(host_type),
|
||||
typeof host === "undefined" ? 0 : host.id,
|
||||
);
|
||||
|
||||
return new Promise((resolve /*, reject */) => {
|
||||
fs.rename(config_file, `${config_file}.err`, () => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
try {
|
||||
await rename(config_file, `${config_file}.err`);
|
||||
} catch {}
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -74,7 +74,7 @@ export default {
|
||||
};
|
||||
}
|
||||
|
||||
// Create a moment of the expiry expression
|
||||
// Create a dayjs of the expiry expression
|
||||
const expiry = parseDatePeriod(data.expiry);
|
||||
if (expiry === null) {
|
||||
throw new errs.AuthError(`Invalid expiry time: ${data.expiry}`);
|
||||
@@ -117,7 +117,7 @@ export default {
|
||||
throw new errs.AuthError(ERROR_MESSAGE_INVALID_AUTH);
|
||||
}
|
||||
|
||||
// Create a moment of the expiry expression
|
||||
// Create a dayjs of the expiry expression
|
||||
const expiry = parseDatePeriod(data.expiry);
|
||||
if (expiry === null) {
|
||||
throw new errs.AuthError(`Invalid expiry time: ${data.expiry}`);
|
||||
@@ -152,7 +152,7 @@ export default {
|
||||
thisData.expiry = thisData.expiry || "1d";
|
||||
|
||||
if (access?.token.getUserId(0)) {
|
||||
// Create a moment of the expiry expression
|
||||
// Create a dayjs of the expiry expression
|
||||
const expiry = parseDatePeriod(thisData.expiry);
|
||||
if (expiry === null) {
|
||||
throw new errs.AuthError(`Invalid expiry time: ${thisData.expiry}`);
|
||||
|
||||
@@ -3,40 +3,13 @@ import crypto from "node:crypto";
|
||||
import { global as logger } from "../logger.js";
|
||||
|
||||
const keysFile = "/data/npmplus/keys.json";
|
||||
const sqliteEngine = "better-sqlite3";
|
||||
const mysqlEngine = "mysql2";
|
||||
const postgresEngine = "pg";
|
||||
const sqliteClientName = "better-sqlite3";
|
||||
|
||||
let instance = null;
|
||||
|
||||
// 1. Load from config file first (not recommended anymore)
|
||||
// 2. Use config env variables next
|
||||
const configure = () => {
|
||||
const filename = "/data/npmplus/default.json";
|
||||
if (fs.existsSync(filename)) {
|
||||
let configData;
|
||||
try {
|
||||
// Load this json synchronously
|
||||
const rawData = fs.readFileSync(filename);
|
||||
configData = JSON.parse(rawData);
|
||||
} catch (_) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
if (configData?.database) {
|
||||
logger.info(`Using configuration from file: ${filename}`);
|
||||
|
||||
// Migrate those who have "mysql" engine to "mysql2"
|
||||
if (configData.database.engine === "mysql") {
|
||||
configData.database.engine = mysqlEngine;
|
||||
}
|
||||
|
||||
instance = configData;
|
||||
instance.keys = getKeys();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const toBool = (v) => /^(1|true|yes|on)$/i.test((v || "").trim());
|
||||
|
||||
const envMysqlHost = process.env.DB_MYSQL_HOST || null;
|
||||
@@ -98,7 +71,7 @@ const configure = () => {
|
||||
database: {
|
||||
engine: "knex-native",
|
||||
knex: {
|
||||
client: sqliteClientName,
|
||||
client: sqliteEngine,
|
||||
connection: {
|
||||
filename: envSqliteFile,
|
||||
},
|
||||
@@ -195,7 +168,7 @@ const configGet = (key) => {
|
||||
*/
|
||||
const isSqlite = () => {
|
||||
instance === null && configure();
|
||||
return instance.database.knex && instance.database.knex.client === sqliteClientName;
|
||||
return instance.database.knex && instance.database.knex.client === sqliteEngine;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import moment from "moment";
|
||||
import dayjs from "dayjs";
|
||||
import { ref } from "objection";
|
||||
import { isPostgres } from "./config.js";
|
||||
|
||||
/**
|
||||
* Takes an expression such as 30d and returns a moment object of that date in future
|
||||
* Takes an expression such as 30d and returns a dayjs object of that date in future
|
||||
*
|
||||
* Key Shorthand
|
||||
* ==================
|
||||
@@ -23,7 +23,7 @@ import { isPostgres } from "./config.js";
|
||||
const parseDatePeriod = (expression) => {
|
||||
const matches = expression.match(/^([0-9]+)(y|Q|M|w|d|h|m|s|ms)$/m);
|
||||
if (matches) {
|
||||
return moment().add(matches[1], matches[2]);
|
||||
return dayjs().add(matches[1], matches[2]);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { execFile as nodeExecFile } from "node:child_process";
|
||||
import { promisify } from "node:util";
|
||||
import { dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { Liquid } from "liquidjs";
|
||||
@@ -11,6 +12,8 @@ import errs from "./error.js";
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
const nodeExecFilePromises = promisify(nodeExecFile);
|
||||
|
||||
const writeHash = () => {
|
||||
const envVars = fs.readdirSync(`${__dirname}/../templates`).flatMap((file) => {
|
||||
const content = fs.readFileSync(`${__dirname}/../templates/${file}`, "utf8");
|
||||
@@ -31,18 +34,18 @@ const writeHash = () => {
|
||||
* @param {Array} args
|
||||
* @returns {Promise}
|
||||
*/
|
||||
const execFile = (cmd, args) => {
|
||||
const execFile = async (cmd, args) => {
|
||||
debug(logger, `CMD: ${cmd} ${args ? args.join(" ") : ""}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
nodeExecFile(cmd, args, (err, stdout, stderr) => {
|
||||
if (err && typeof err === "object") {
|
||||
reject(new errs.CommandError((stdout + stderr).trim(), 1, err));
|
||||
} else {
|
||||
resolve((stdout + stderr).trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
try {
|
||||
const { stdout, stderr } = await nodeExecFilePromises(cmd, args);
|
||||
return `${stdout || ""}${stderr || ""}`.trim();
|
||||
} catch (err) {
|
||||
if (err && typeof err === "object") {
|
||||
throw new errs.CommandError(`${err.stdout || ""}${err.stderr || ""}`.trim(), 1, err);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { migrate as logger } from "../logger.js";
|
||||
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "initial-schema";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "websockets";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "forward_host";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "http2_support";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "forward_scheme";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "disabled";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -6,7 +6,7 @@ const migrateName = "custom_locations";
|
||||
* Migrate
|
||||
* Extends proxy_host table with locations field
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "hsts";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "settings";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "access_list_client";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "access_list_client_fix";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "pass_auth";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "redirection_scheme";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "redirection_status_code";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "stream_domain";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -26,7 +26,7 @@ async function regenerateDefaultHost(knex) {
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "stream_ssl";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "change_incoming_port_to_string";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -26,7 +26,7 @@ async function regenerateDefaultHost(knex) {
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "change_forwarding_port_to_string";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "allow_empty_forwarding_port";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "allow_empty_stream_forwarding_port";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "stream_proxy_protocol_forwarding";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "redirect_auto_scheme";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "stream_proxy_ssl";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "stream_rename_pp_and_tls";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "trust_forwarded_proto";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "reset_button_values";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { migrate as logger } from "../logger.js";
|
||||
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "new_proxy_buttons";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "new_proxy_selections";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "npmplus_http3_support";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { migrate as logger } from "../logger.js";
|
||||
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -5,7 +5,7 @@ const migrateName = "new_and_split_proxy_buttons";
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import { migrate as logger } from "../logger.js";
|
||||
|
||||
/**
|
||||
* Migrate
|
||||
*
|
||||
* @see http://knexjs.org/#Schema
|
||||
* @see https://knexjs.org/guide/migrations.html#migration-api
|
||||
*
|
||||
* @param {Object} knex
|
||||
* @returns {Promise}
|
||||
|
||||
@@ -7,29 +7,30 @@
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@apidevtools/json-schema-ref-parser": "15.2.2",
|
||||
"@apidevtools/json-schema-ref-parser": "15.3.1",
|
||||
"ajv": "8.18.0",
|
||||
"archiver": "7.0.1",
|
||||
"bcryptjs": "3.0.3",
|
||||
"better-sqlite3": "12.6.2",
|
||||
"cookie-parser": "1.4.7",
|
||||
"dayjs": "1.11.19",
|
||||
"express": "5.2.1",
|
||||
"express-fileupload": "1.5.2",
|
||||
"express-rate-limit": "8.2.1",
|
||||
"jsonwebtoken": "9.0.3",
|
||||
"knex": "3.1.0",
|
||||
"liquidjs": "10.24.0",
|
||||
"lodash": "4.17.23",
|
||||
"moment": "2.30.1",
|
||||
"mysql2": "3.17.1",
|
||||
"mysql2": "3.18.2",
|
||||
"objection": "3.1.5",
|
||||
"otplib": "13.3.0",
|
||||
"openid-client": "6.8.2",
|
||||
"pg": "8.18.0",
|
||||
"otplib": "13.3.0",
|
||||
"pg": "8.19.0",
|
||||
"signale": "1.4.0",
|
||||
"temp-write": "6.0.1"
|
||||
"swagger-ui-express": "5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apidevtools/swagger-parser": "12.1.0",
|
||||
"@biomejs/biome": "2.3.15"
|
||||
"@biomejs/biome": "2.4.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// based on: https://github.com/jlesage/docker-nginx-proxy-manager/blob/796734a3f9a87e0b1561b47fd418f82216359634/rootfs/opt/nginx-proxy-manager/bin/reset-password
|
||||
|
||||
import fs from "node:fs";
|
||||
import { existsSync } from "node:fs";
|
||||
import bcrypt from "bcryptjs";
|
||||
import Database from "better-sqlite3";
|
||||
|
||||
@@ -13,7 +13,7 @@ Reset password of a NPMplus user.
|
||||
|
||||
Arguments:
|
||||
USER_EMAIL Email address of the user to reset the password.
|
||||
PASSWORD Optional new password of the user. If not set, password is set to 'changeme'.`);
|
||||
PASSWORD New password of the user.`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -21,57 +21,35 @@ const args = process.argv.slice(2);
|
||||
const USER_EMAIL = args[0];
|
||||
const PASSWORD = args[1];
|
||||
|
||||
if (!USER_EMAIL && !PASSWORD) {
|
||||
console.error("ERROR: User email address must be set.");
|
||||
console.error("ERROR: Password must be set.");
|
||||
if (!USER_EMAIL || !PASSWORD) {
|
||||
if (!USER_EMAIL) console.error("ERROR: User email address must be set.");
|
||||
if (!PASSWORD) console.error("ERROR: Password must be set.");
|
||||
usage();
|
||||
}
|
||||
|
||||
if (!USER_EMAIL) {
|
||||
console.error("ERROR: User email address must be set.");
|
||||
usage();
|
||||
}
|
||||
|
||||
if (!PASSWORD) {
|
||||
console.error("ERROR: Password must be set.");
|
||||
usage();
|
||||
}
|
||||
|
||||
if (fs.existsSync("/data/npmplus/database.sqlite")) {
|
||||
bcrypt.hash(PASSWORD, 13, (err, PASSWORD_HASH) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
}
|
||||
const db = new Database("/data/npmplus/database.sqlite");
|
||||
|
||||
try {
|
||||
const stmt = db.prepare(`
|
||||
UPDATE auth
|
||||
SET secret = ?
|
||||
WHERE EXISTS (
|
||||
SELECT *
|
||||
FROM user
|
||||
WHERE user.id = auth.user_id AND user.email = ?
|
||||
)`);
|
||||
|
||||
const result = stmt.run(PASSWORD_HASH, USER_EMAIL);
|
||||
|
||||
if (result.changes > 0) {
|
||||
console.log(`Password for user ${USER_EMAIL} has been reset.`);
|
||||
} else {
|
||||
console.log(`No user found with email ${USER_EMAIL}.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
|
||||
process.exit(0);
|
||||
});
|
||||
} else {
|
||||
if (!existsSync("/data/npmplus/database.sqlite")) {
|
||||
console.error("ERROR: Cannot connect to the sqlite database.");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let db;
|
||||
try {
|
||||
db = new Database("/data/npmplus/database.sqlite");
|
||||
|
||||
const PASSWORD_HASH = bcrypt.hashSync(PASSWORD, 13);
|
||||
const stmt = db.prepare(
|
||||
"UPDATE auth SET secret = ? WHERE EXISTS (SELECT * FROM user WHERE user.id = auth.user_id AND user.email = ?)",
|
||||
);
|
||||
const result = stmt.run(PASSWORD_HASH, USER_EMAIL);
|
||||
|
||||
if (result.changes > 0) {
|
||||
console.log(`Password for user ${USER_EMAIL} has been reset.`);
|
||||
} else {
|
||||
console.log(`No user found with email ${USER_EMAIL}.`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
process.exitCode = 1;
|
||||
} finally {
|
||||
if (db) db.close();
|
||||
}
|
||||
|
||||
421
backend/pnpm-lock.yaml
generated
421
backend/pnpm-lock.yaml
generated
@@ -9,8 +9,8 @@ importers:
|
||||
.:
|
||||
dependencies:
|
||||
'@apidevtools/json-schema-ref-parser':
|
||||
specifier: 15.2.2
|
||||
version: 15.2.2(@types/json-schema@7.0.15)
|
||||
specifier: 15.3.1
|
||||
version: 15.3.1(@types/json-schema@7.0.15)
|
||||
ajv:
|
||||
specifier: 8.18.0
|
||||
version: 8.18.0
|
||||
@@ -26,33 +26,36 @@ importers:
|
||||
cookie-parser:
|
||||
specifier: 1.4.7
|
||||
version: 1.4.7
|
||||
dayjs:
|
||||
specifier: 1.11.19
|
||||
version: 1.11.19
|
||||
express:
|
||||
specifier: 5.2.1
|
||||
version: 5.2.1
|
||||
express-fileupload:
|
||||
specifier: 1.5.2
|
||||
version: 1.5.2
|
||||
express-rate-limit:
|
||||
specifier: 8.2.1
|
||||
version: 8.2.1(express@5.2.1)
|
||||
jsonwebtoken:
|
||||
specifier: 9.0.3
|
||||
version: 9.0.3
|
||||
knex:
|
||||
specifier: 3.1.0
|
||||
version: 3.1.0(better-sqlite3@12.6.2)(mysql2@3.17.1)(pg@8.18.0)
|
||||
version: 3.1.0(better-sqlite3@12.6.2)(mysql2@3.18.2(@types/node@25.3.3))(pg@8.19.0)
|
||||
liquidjs:
|
||||
specifier: 10.24.0
|
||||
version: 10.24.0
|
||||
lodash:
|
||||
specifier: 4.17.23
|
||||
version: 4.17.23
|
||||
moment:
|
||||
specifier: 2.30.1
|
||||
version: 2.30.1
|
||||
mysql2:
|
||||
specifier: 3.17.1
|
||||
version: 3.17.1
|
||||
specifier: 3.18.2
|
||||
version: 3.18.2(@types/node@25.3.3)
|
||||
objection:
|
||||
specifier: 3.1.5
|
||||
version: 3.1.5(knex@3.1.0(better-sqlite3@12.6.2)(mysql2@3.17.1)(pg@8.18.0))
|
||||
version: 3.1.5(knex@3.1.0(better-sqlite3@12.6.2)(mysql2@3.18.2(@types/node@25.3.3))(pg@8.19.0))
|
||||
openid-client:
|
||||
specifier: 6.8.2
|
||||
version: 6.8.2
|
||||
@@ -60,21 +63,21 @@ importers:
|
||||
specifier: 13.3.0
|
||||
version: 13.3.0
|
||||
pg:
|
||||
specifier: 8.18.0
|
||||
version: 8.18.0
|
||||
specifier: 8.19.0
|
||||
version: 8.19.0
|
||||
signale:
|
||||
specifier: 1.4.0
|
||||
version: 1.4.0
|
||||
temp-write:
|
||||
specifier: 6.0.1
|
||||
version: 6.0.1
|
||||
swagger-ui-express:
|
||||
specifier: 5.0.1
|
||||
version: 5.0.1(express@5.2.1)
|
||||
devDependencies:
|
||||
'@apidevtools/swagger-parser':
|
||||
specifier: 12.1.0
|
||||
version: 12.1.0(openapi-types@12.1.3)
|
||||
'@biomejs/biome':
|
||||
specifier: 2.3.15
|
||||
version: 2.3.15
|
||||
specifier: 2.4.5
|
||||
version: 2.4.5
|
||||
|
||||
packages:
|
||||
|
||||
@@ -82,8 +85,8 @@ packages:
|
||||
resolution: {integrity: sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
'@apidevtools/json-schema-ref-parser@15.2.2':
|
||||
resolution: {integrity: sha512-54fvjSwWiBTdVviiUItOCeyxtPSBmCrSEjlOl8XFEDuYD3lXY1lOBWKim/WJ3i1EYzdGx6rSOjK5KRDMppLI4Q==}
|
||||
'@apidevtools/json-schema-ref-parser@15.3.1':
|
||||
resolution: {integrity: sha512-FIweGOR9zrNuskfDXn8dfsA4eJEe8LmmGsGSDikEZvgYm36SO36yMhasXSOX7/OTGZ3b7I9iPhOxB24D8xL5uQ==}
|
||||
engines: {node: '>=20'}
|
||||
peerDependencies:
|
||||
'@types/json-schema': ^7.0.15
|
||||
@@ -100,59 +103,59 @@ packages:
|
||||
peerDependencies:
|
||||
openapi-types: '>=7'
|
||||
|
||||
'@biomejs/biome@2.3.15':
|
||||
resolution: {integrity: sha512-u+jlPBAU2B45LDkjjNNYpc1PvqrM/co4loNommS9/sl9oSxsAQKsNZejYuUztvToB5oXi1tN/e62iNd6ESiY3g==}
|
||||
'@biomejs/biome@2.4.5':
|
||||
resolution: {integrity: sha512-OWNCyMS0Q011R6YifXNOg6qsOg64IVc7XX6SqGsrGszPbkVCoaO7Sr/lISFnXZ9hjQhDewwZ40789QmrG0GYgQ==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
hasBin: true
|
||||
|
||||
'@biomejs/cli-darwin-arm64@2.3.15':
|
||||
resolution: {integrity: sha512-SDCdrJ4COim1r8SNHg19oqT50JfkI/xGZHSyC6mGzMfKrpNe/217Eq6y98XhNTc0vGWDjznSDNXdUc6Kg24jbw==}
|
||||
'@biomejs/cli-darwin-arm64@2.4.5':
|
||||
resolution: {integrity: sha512-lGS4Nd5O3KQJ6TeWv10mElnx1phERhBxqGP/IKq0SvZl78kcWDFMaTtVK+w3v3lusRFxJY78n07PbKplirsU5g==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
'@biomejs/cli-darwin-x64@2.3.15':
|
||||
resolution: {integrity: sha512-RkyeSosBtn3C3Un8zQnl9upX0Qbq4E3QmBa0qjpOh1MebRbHhNlRC16jk8HdTe/9ym5zlfnpbb8cKXzW+vlTxw==}
|
||||
'@biomejs/cli-darwin-x64@2.4.5':
|
||||
resolution: {integrity: sha512-6MoH4tyISIBNkZ2Q5T1R7dLd5BsITb2yhhhrU9jHZxnNSNMWl+s2Mxu7NBF8Y3a7JJcqq9nsk8i637z4gqkJxQ==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
'@biomejs/cli-linux-arm64-musl@2.3.15':
|
||||
resolution: {integrity: sha512-SSSIj2yMkFdSkXqASzIBdjySBXOe65RJlhKEDlri7MN19RC4cpez+C0kEwPrhXOTgJbwQR9QH1F4+VnHkC35pg==}
|
||||
'@biomejs/cli-linux-arm64-musl@2.4.5':
|
||||
resolution: {integrity: sha512-iqLDgpzobG7gpBF0fwEVS/LT8kmN7+S0E2YKFDtqliJfzNLnAiV2Nnyb+ehCDCJgAZBASkYHR2o60VQWikpqIg==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@biomejs/cli-linux-arm64@2.3.15':
|
||||
resolution: {integrity: sha512-FN83KxrdVWANOn5tDmW6UBC0grojchbGmcEz6JkRs2YY6DY63sTZhwkQ56x6YtKhDVV1Unz7FJexy8o7KwuIhg==}
|
||||
'@biomejs/cli-linux-arm64@2.4.5':
|
||||
resolution: {integrity: sha512-U1GAG6FTjhAO04MyH4xn23wRNBkT6H7NentHh+8UxD6ShXKBm5SY4RedKJzkUThANxb9rUKIPc7B8ew9Xo/cWg==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@biomejs/cli-linux-x64-musl@2.3.15':
|
||||
resolution: {integrity: sha512-dbjPzTh+ijmmNwojFYbQNMFp332019ZDioBYAMMJj5Ux9d8MkM+u+J68SBJGVwVeSHMYj+T9504CoxEzQxrdNw==}
|
||||
'@biomejs/cli-linux-x64-musl@2.4.5':
|
||||
resolution: {integrity: sha512-NlKa7GpbQmNhZf9kakQeddqZyT7itN7jjWdakELeXyTU3pg/83fTysRRDPJD0akTfKDl6vZYNT9Zqn4MYZVBOA==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@biomejs/cli-linux-x64@2.3.15':
|
||||
resolution: {integrity: sha512-T8n9p8aiIKOrAD7SwC7opiBM1LYGrE5G3OQRXWgbeo/merBk8m+uxJ1nOXMPzfYyFLfPlKF92QS06KN1UW+Zbg==}
|
||||
'@biomejs/cli-linux-x64@2.4.5':
|
||||
resolution: {integrity: sha512-NdODlSugMzTlENPTa4z0xB82dTUlCpsrOxc43///aNkTLblIYH4XpYflBbf5ySlQuP8AA4AZd1qXhV07IdrHdQ==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@biomejs/cli-win32-arm64@2.3.15':
|
||||
resolution: {integrity: sha512-puMuenu/2brQdgqtQ7geNwQlNVxiABKEZJhMRX6AGWcmrMO8EObMXniFQywy2b81qmC+q+SDvlOpspNwz0WiOA==}
|
||||
'@biomejs/cli-win32-arm64@2.4.5':
|
||||
resolution: {integrity: sha512-EBfrTqRIWOFSd7CQb/0ttjHMR88zm3hGravnDwUA9wHAaCAYsULKDebWcN5RmrEo1KBtl/gDVJMrFjNR0pdGUw==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
'@biomejs/cli-win32-x64@2.3.15':
|
||||
resolution: {integrity: sha512-kDZr/hgg+igo5Emi0LcjlgfkoGZtgIpJKhnvKTRmMBv6FF/3SDyEV4khBwqNebZIyMZTzvpca9sQNSXJ39pI2A==}
|
||||
'@biomejs/cli-win32-x64@2.4.5':
|
||||
resolution: {integrity: sha512-Pmhv9zT95YzECfjEHNl3mN9Vhusw9VA5KHY0ZvlGsxsjwS5cb7vpRnHzJIv0vG7jB0JI7xEaMH9ddfZm/RozBw==}
|
||||
engines: {node: '>=14.21.3'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
@@ -187,12 +190,18 @@ packages:
|
||||
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
'@scarf/scarf@1.4.0':
|
||||
resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==}
|
||||
|
||||
'@scure/base@2.0.0':
|
||||
resolution: {integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==}
|
||||
|
||||
'@types/json-schema@7.0.15':
|
||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
|
||||
'@types/node@25.3.3':
|
||||
resolution: {integrity: sha512-DpzbrH7wIcBaJibpKo9nnSQL0MTRdnWttGyE5haGwK86xgMOkFLp7vEyfQPGLOJh5wNYiJ3V9PmUMDhV9u8kkQ==}
|
||||
|
||||
abort-controller@3.0.0:
|
||||
resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==}
|
||||
engines: {node: '>=6.5'}
|
||||
@@ -258,8 +267,8 @@ packages:
|
||||
resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
|
||||
engines: {node: '>= 6.0.0'}
|
||||
|
||||
b4a@1.7.4:
|
||||
resolution: {integrity: sha512-u20zJLDaSWpxaZ+zaAkEIB2dZZ1o+DF4T/MRbmsvGp9nletHOyiai19OzX1fF8xUBYsO1bPXxODvcd0978pnug==}
|
||||
b4a@1.8.0:
|
||||
resolution: {integrity: sha512-qRuSmNSkGQaHwNbM7J78Wwy+ghLEYF1zNrSeMxj4Kgw6y33O3mXcQ6Ie9fRvfU/YnxWkOchPXbaLb73TkIsfdg==}
|
||||
peerDependencies:
|
||||
react-native-b4a: '*'
|
||||
peerDependenciesMeta:
|
||||
@@ -277,6 +286,36 @@ packages:
|
||||
bare-abort-controller:
|
||||
optional: true
|
||||
|
||||
bare-fs@4.5.5:
|
||||
resolution: {integrity: sha512-XvwYM6VZqKoqDll8BmSww5luA5eflDzY0uEFfBJtFKe4PAAtxBjU3YIxzIBzhyaEQBy1VXEQBto4cpN5RZJw+w==}
|
||||
engines: {bare: '>=1.16.0'}
|
||||
peerDependencies:
|
||||
bare-buffer: '*'
|
||||
peerDependenciesMeta:
|
||||
bare-buffer:
|
||||
optional: true
|
||||
|
||||
bare-os@3.7.0:
|
||||
resolution: {integrity: sha512-64Rcwj8qlnTZU8Ps6JJEdSmxBEUGgI7g8l+lMtsJLl4IsfTcHMTfJ188u2iGV6P6YPRZrtv72B2kjn+hp+Yv3g==}
|
||||
engines: {bare: '>=1.14.0'}
|
||||
|
||||
bare-path@3.0.0:
|
||||
resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==}
|
||||
|
||||
bare-stream@2.8.0:
|
||||
resolution: {integrity: sha512-reUN0M2sHRqCdG4lUK3Fw8w98eeUIZHL5c3H7Mbhk2yVBL+oofgaIp0ieLfD5QXwPCypBpmEEKU2WZKzbAk8GA==}
|
||||
peerDependencies:
|
||||
bare-buffer: '*'
|
||||
bare-events: '*'
|
||||
peerDependenciesMeta:
|
||||
bare-buffer:
|
||||
optional: true
|
||||
bare-events:
|
||||
optional: true
|
||||
|
||||
bare-url@2.3.2:
|
||||
resolution: {integrity: sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==}
|
||||
|
||||
base64-js@1.5.1:
|
||||
resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
|
||||
|
||||
@@ -403,6 +442,9 @@ packages:
|
||||
resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
dayjs@1.11.19:
|
||||
resolution: {integrity: sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==}
|
||||
|
||||
db-errors@0.2.3:
|
||||
resolution: {integrity: sha512-OOgqgDuCavHXjYSJoV2yGhv6SeG8nk42aoCSoyXLZUH7VwFG27rxbavU1z+VrZbZjphw5UkDQwUlD21MwZpUng==}
|
||||
|
||||
@@ -523,6 +565,12 @@ packages:
|
||||
resolution: {integrity: sha512-wxUJn2vTHvj/kZCVmc5/bJO15C7aSMyHeuXYY3geKpeKibaAoQGcEv5+sM6nHS2T7VF+QHS4hTWPiY2mKofEdg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
express-rate-limit@8.2.1:
|
||||
resolution: {integrity: sha512-PCZEIEIxqwhzw4KF0n7QF4QqruVTcF73O5kFKUnGOyjbCCgizBBiFaYpd/fnBLUMPw/BWw9OsiN7GgrNYr7j6g==}
|
||||
engines: {node: '>= 16'}
|
||||
peerDependencies:
|
||||
express: '>= 4.11'
|
||||
|
||||
express@5.2.1:
|
||||
resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==}
|
||||
engines: {node: '>= 18'}
|
||||
@@ -635,6 +683,10 @@ packages:
|
||||
resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
ip-address@10.0.1:
|
||||
resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
ipaddr.js@1.9.1:
|
||||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
@@ -660,10 +712,6 @@ packages:
|
||||
resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-stream@4.0.1:
|
||||
resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
isarray@1.0.0:
|
||||
resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
|
||||
|
||||
@@ -799,36 +847,35 @@ packages:
|
||||
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minimatch@5.1.6:
|
||||
resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
|
||||
minimatch@5.1.9:
|
||||
resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
minimatch@9.0.5:
|
||||
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
|
||||
minimatch@9.0.9:
|
||||
resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
minipass@7.1.2:
|
||||
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
|
||||
minipass@7.1.3:
|
||||
resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==}
|
||||
engines: {node: '>=16 || 14 >=14.17'}
|
||||
|
||||
mkdirp-classic@0.5.3:
|
||||
resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
|
||||
|
||||
moment@2.30.1:
|
||||
resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
|
||||
|
||||
ms@2.1.2:
|
||||
resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
mysql2@3.17.1:
|
||||
resolution: {integrity: sha512-UzIzdVwPXPoZm+FaJ4lNsRt28HtUwt68gpLH7NP1oSjd91M5Qn1XJzbIsSRMRc5CV3pvktLNshmbaFfMYqPBhQ==}
|
||||
mysql2@3.18.2:
|
||||
resolution: {integrity: sha512-UfEShBFAZZEAKjySnTUuE7BgqkYT4mx+RjoJ5aqtmwSSvNcJ/QxQPXz/y3jSxNiVRedPfgccmuBtiPCSiEEytw==}
|
||||
engines: {node: '>= 8.0'}
|
||||
peerDependencies:
|
||||
'@types/node': '>= 8'
|
||||
|
||||
named-placeholders@1.1.6:
|
||||
resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==}
|
||||
@@ -849,8 +896,8 @@ packages:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
oauth4webapi@3.8.4:
|
||||
resolution: {integrity: sha512-EKlVEgav8zH31IXxvhCqjEgQws6S9QmnmJyLXmeV5REf59g7VmqRVa5l/rhGWtUqGm2rLVTNwukn9hla5kJ2WQ==}
|
||||
oauth4webapi@3.8.5:
|
||||
resolution: {integrity: sha512-A8jmyUckVhRJj5lspguklcl90Ydqk61H3dcU0oLhH3Yv13KpAliKTt5hknpGGPZSSfOwGyraNEFmofDYH+1kSg==}
|
||||
|
||||
object-inspect@1.13.4:
|
||||
resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==}
|
||||
@@ -932,20 +979,20 @@ packages:
|
||||
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pg-pool@3.11.0:
|
||||
resolution: {integrity: sha512-MJYfvHwtGp870aeusDh+hg9apvOe2zmpZJpyt+BMtzUWlVqbhFmMK6bOBXLBUPd7iRtIF9fZplDc7KrPN3PN7w==}
|
||||
pg-pool@3.12.0:
|
||||
resolution: {integrity: sha512-eIJ0DES8BLaziFHW7VgJEBPi5hg3Nyng5iKpYtj3wbcAUV9A1wLgWiY7ajf/f/oO1wfxt83phXPY8Emztg7ITg==}
|
||||
peerDependencies:
|
||||
pg: '>=8.0'
|
||||
|
||||
pg-protocol@1.11.0:
|
||||
resolution: {integrity: sha512-pfsxk2M9M3BuGgDOfuy37VNRRX3jmKgMjcvAcWqNDpZSf4cUmv8HSOl5ViRQFsfARFn0KuUQTgLxVMbNq5NW3g==}
|
||||
pg-protocol@1.12.0:
|
||||
resolution: {integrity: sha512-uOANXNRACNdElMXJ0tPz6RBM0XQ61nONGAwlt8da5zs/iUOOCLBQOHSXnrC6fMsvtjxbOJrZZl5IScGv+7mpbg==}
|
||||
|
||||
pg-types@2.2.0:
|
||||
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pg@8.18.0:
|
||||
resolution: {integrity: sha512-xqrUDL1b9MbkydY/s+VZ6v+xiMUmOUk7SS9d/1kpyQxoJ6U9AO1oIJyUWVZojbfe5Cc/oluutcgFG4L9RDP1iQ==}
|
||||
pg@8.19.0:
|
||||
resolution: {integrity: sha512-QIcLGi508BAHkQ3pJNptsFz5WQMlpGbuBGBaIaXsWK8mel2kQ/rThYI+DbgjUvZrIr7MiuEuc9LcChJoEZK1xQ==}
|
||||
engines: {node: '>= 16.0.0'}
|
||||
peerDependencies:
|
||||
pg-native: '>=3.0.1'
|
||||
@@ -983,6 +1030,7 @@ packages:
|
||||
prebuild-install@7.1.3:
|
||||
resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==}
|
||||
engines: {node: '>=10'}
|
||||
deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available.
|
||||
hasBin: true
|
||||
|
||||
process-nextick-args@2.0.1:
|
||||
@@ -996,11 +1044,11 @@ packages:
|
||||
resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
pump@3.0.3:
|
||||
resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
|
||||
pump@3.0.4:
|
||||
resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==}
|
||||
|
||||
qs@6.14.2:
|
||||
resolution: {integrity: sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==}
|
||||
qs@6.15.0:
|
||||
resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
range-parser@1.2.1:
|
||||
@@ -1068,9 +1116,6 @@ packages:
|
||||
resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==}
|
||||
engines: {node: '>= 18'}
|
||||
|
||||
seq-queue@0.0.5:
|
||||
resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==}
|
||||
|
||||
serve-static@2.2.1:
|
||||
resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==}
|
||||
engines: {node: '>= 18'}
|
||||
@@ -1120,8 +1165,8 @@ packages:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
sql-escaper@1.3.2:
|
||||
resolution: {integrity: sha512-lp+ZDVfSjHt+qAK1jXBTIXBNYnbo7gnaAGwoYTH9bE89kNkXwcu6g0WjJGRsdTKVpY1z70u3Y0IgmnBOoRybHw==}
|
||||
sql-escaper@1.3.3:
|
||||
resolution: {integrity: sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==}
|
||||
engines: {bun: '>=1.0.0', deno: '>=2.0.0', node: '>=12.0.0'}
|
||||
|
||||
statuses@2.0.2:
|
||||
@@ -1153,8 +1198,8 @@ packages:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
strip-ansi@7.1.2:
|
||||
resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==}
|
||||
strip-ansi@7.2.0:
|
||||
resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
strip-bom@3.0.0:
|
||||
@@ -1173,6 +1218,15 @@ packages:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
swagger-ui-dist@5.32.0:
|
||||
resolution: {integrity: sha512-nKZB0OuDvacB0s/lC2gbge+RigYvGRGpLLMWMFxaTUwfM+CfndVk9Th2IaTinqXiz6Mn26GK2zriCpv6/+5m3Q==}
|
||||
|
||||
swagger-ui-express@5.0.1:
|
||||
resolution: {integrity: sha512-SrNU3RiBGTLLmFU8GIJdOdanJTl4TOmT27tt3bWWHppqYmAZ6IDuEuBvMU6nZq0zLEe6b/1rACXCgLZqO6ZfrA==}
|
||||
engines: {node: '>= v0.10.32'}
|
||||
peerDependencies:
|
||||
express: '>=4.0.0 || >=5.0.0-beta'
|
||||
|
||||
tar-fs@2.1.4:
|
||||
resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==}
|
||||
|
||||
@@ -1180,23 +1234,18 @@ packages:
|
||||
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
tar-stream@3.1.7:
|
||||
resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
|
||||
tar-stream@3.1.8:
|
||||
resolution: {integrity: sha512-U6QpVRyCGHva435KoNWy9PRoi2IFYCgtEhq9nmrPPpbRacPs9IH4aJ3gbrFC8dPcXvdSZ4XXfXT5Fshbp2MtlQ==}
|
||||
|
||||
tarn@3.0.2:
|
||||
resolution: {integrity: sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
temp-dir@3.0.0:
|
||||
resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==}
|
||||
engines: {node: '>=14.16'}
|
||||
teex@1.0.1:
|
||||
resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==}
|
||||
|
||||
temp-write@6.0.1:
|
||||
resolution: {integrity: sha512-6bj9LlNld+knzEOQvnZK6YxiPF+foOUjvG/WoWj1/Mt9c6f2kQCPsh8KZ+NyTk0AejubTQSPpx2alcswE1bF8g==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
text-decoder@1.2.6:
|
||||
resolution: {integrity: sha512-27FeW5GQFDfw0FpwMQhMagB7BztOOlmjcSRi97t2oplhKVTZtp0DZbSegSaXS5IIC6mxMvBG4AR1Sgc6BX3CQg==}
|
||||
text-decoder@1.2.7:
|
||||
resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==}
|
||||
|
||||
tildify@2.0.0:
|
||||
resolution: {integrity: sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==}
|
||||
@@ -1213,6 +1262,9 @@ packages:
|
||||
resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
undici-types@7.18.2:
|
||||
resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==}
|
||||
|
||||
unpipe@1.0.0:
|
||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
@@ -1255,7 +1307,7 @@ snapshots:
|
||||
'@types/json-schema': 7.0.15
|
||||
js-yaml: 4.1.1
|
||||
|
||||
'@apidevtools/json-schema-ref-parser@15.2.2(@types/json-schema@7.0.15)':
|
||||
'@apidevtools/json-schema-ref-parser@15.3.1(@types/json-schema@7.0.15)':
|
||||
dependencies:
|
||||
'@types/json-schema': 7.0.15
|
||||
js-yaml: 4.1.1
|
||||
@@ -1274,46 +1326,46 @@ snapshots:
|
||||
call-me-maybe: 1.0.2
|
||||
openapi-types: 12.1.3
|
||||
|
||||
'@biomejs/biome@2.3.15':
|
||||
'@biomejs/biome@2.4.5':
|
||||
optionalDependencies:
|
||||
'@biomejs/cli-darwin-arm64': 2.3.15
|
||||
'@biomejs/cli-darwin-x64': 2.3.15
|
||||
'@biomejs/cli-linux-arm64': 2.3.15
|
||||
'@biomejs/cli-linux-arm64-musl': 2.3.15
|
||||
'@biomejs/cli-linux-x64': 2.3.15
|
||||
'@biomejs/cli-linux-x64-musl': 2.3.15
|
||||
'@biomejs/cli-win32-arm64': 2.3.15
|
||||
'@biomejs/cli-win32-x64': 2.3.15
|
||||
'@biomejs/cli-darwin-arm64': 2.4.5
|
||||
'@biomejs/cli-darwin-x64': 2.4.5
|
||||
'@biomejs/cli-linux-arm64': 2.4.5
|
||||
'@biomejs/cli-linux-arm64-musl': 2.4.5
|
||||
'@biomejs/cli-linux-x64': 2.4.5
|
||||
'@biomejs/cli-linux-x64-musl': 2.4.5
|
||||
'@biomejs/cli-win32-arm64': 2.4.5
|
||||
'@biomejs/cli-win32-x64': 2.4.5
|
||||
|
||||
'@biomejs/cli-darwin-arm64@2.3.15':
|
||||
'@biomejs/cli-darwin-arm64@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-darwin-x64@2.3.15':
|
||||
'@biomejs/cli-darwin-x64@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-arm64-musl@2.3.15':
|
||||
'@biomejs/cli-linux-arm64-musl@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-arm64@2.3.15':
|
||||
'@biomejs/cli-linux-arm64@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-x64-musl@2.3.15':
|
||||
'@biomejs/cli-linux-x64-musl@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-linux-x64@2.3.15':
|
||||
'@biomejs/cli-linux-x64@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-win32-arm64@2.3.15':
|
||||
'@biomejs/cli-win32-arm64@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@biomejs/cli-win32-x64@2.3.15':
|
||||
'@biomejs/cli-win32-x64@2.4.5':
|
||||
optional: true
|
||||
|
||||
'@isaacs/cliui@8.0.2':
|
||||
dependencies:
|
||||
string-width: 5.1.2
|
||||
string-width-cjs: string-width@4.2.3
|
||||
strip-ansi: 7.1.2
|
||||
strip-ansi: 7.2.0
|
||||
strip-ansi-cjs: strip-ansi@6.0.1
|
||||
wrap-ansi: 8.1.0
|
||||
wrap-ansi-cjs: wrap-ansi@7.0.0
|
||||
@@ -1350,10 +1402,16 @@ snapshots:
|
||||
'@pkgjs/parseargs@0.11.0':
|
||||
optional: true
|
||||
|
||||
'@scarf/scarf@1.4.0': {}
|
||||
|
||||
'@scure/base@2.0.0': {}
|
||||
|
||||
'@types/json-schema@7.0.15': {}
|
||||
|
||||
'@types/node@25.3.3':
|
||||
dependencies:
|
||||
undici-types: 7.18.2
|
||||
|
||||
abort-controller@3.0.0:
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
@@ -1409,10 +1467,11 @@ snapshots:
|
||||
buffer-crc32: 1.0.0
|
||||
readable-stream: 4.7.0
|
||||
readdir-glob: 1.1.3
|
||||
tar-stream: 3.1.7
|
||||
tar-stream: 3.1.8
|
||||
zip-stream: 6.0.1
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
|
||||
argparse@2.0.1: {}
|
||||
@@ -1421,12 +1480,43 @@ snapshots:
|
||||
|
||||
aws-ssl-profiles@1.1.2: {}
|
||||
|
||||
b4a@1.7.4: {}
|
||||
b4a@1.8.0: {}
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
bare-events@2.8.2: {}
|
||||
|
||||
bare-fs@4.5.5:
|
||||
dependencies:
|
||||
bare-events: 2.8.2
|
||||
bare-path: 3.0.0
|
||||
bare-stream: 2.8.0(bare-events@2.8.2)
|
||||
bare-url: 2.3.2
|
||||
fast-fifo: 1.3.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
bare-os@3.7.0: {}
|
||||
|
||||
bare-path@3.0.0:
|
||||
dependencies:
|
||||
bare-os: 3.7.0
|
||||
|
||||
bare-stream@2.8.0(bare-events@2.8.2):
|
||||
dependencies:
|
||||
streamx: 2.23.0
|
||||
teex: 1.0.1
|
||||
optionalDependencies:
|
||||
bare-events: 2.8.2
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
bare-url@2.3.2:
|
||||
dependencies:
|
||||
bare-path: 3.0.0
|
||||
|
||||
base64-js@1.5.1: {}
|
||||
|
||||
bcryptjs@3.0.3: {}
|
||||
@@ -1454,7 +1544,7 @@ snapshots:
|
||||
http-errors: 2.0.1
|
||||
iconv-lite: 0.7.2
|
||||
on-finished: 2.4.1
|
||||
qs: 6.14.2
|
||||
qs: 6.15.0
|
||||
raw-body: 3.0.2
|
||||
type-is: 2.0.1
|
||||
transitivePeerDependencies:
|
||||
@@ -1558,6 +1648,8 @@ snapshots:
|
||||
shebang-command: 2.0.0
|
||||
which: 2.0.2
|
||||
|
||||
dayjs@1.11.19: {}
|
||||
|
||||
db-errors@0.2.3: {}
|
||||
|
||||
debug@4.3.4:
|
||||
@@ -1642,6 +1734,11 @@ snapshots:
|
||||
dependencies:
|
||||
busboy: 1.6.0
|
||||
|
||||
express-rate-limit@8.2.1(express@5.2.1):
|
||||
dependencies:
|
||||
express: 5.2.1
|
||||
ip-address: 10.0.1
|
||||
|
||||
express@5.2.1:
|
||||
dependencies:
|
||||
accepts: 2.0.0
|
||||
@@ -1664,7 +1761,7 @@ snapshots:
|
||||
once: 1.4.0
|
||||
parseurl: 1.3.3
|
||||
proxy-addr: 2.0.7
|
||||
qs: 6.14.2
|
||||
qs: 6.15.0
|
||||
range-parser: 1.2.1
|
||||
router: 2.2.0
|
||||
send: 1.2.1
|
||||
@@ -1747,8 +1844,8 @@ snapshots:
|
||||
dependencies:
|
||||
foreground-child: 3.3.1
|
||||
jackspeak: 3.4.3
|
||||
minimatch: 9.0.5
|
||||
minipass: 7.1.2
|
||||
minimatch: 9.0.9
|
||||
minipass: 7.1.3
|
||||
package-json-from-dist: 1.0.1
|
||||
path-scurry: 1.11.1
|
||||
|
||||
@@ -1784,6 +1881,8 @@ snapshots:
|
||||
|
||||
interpret@2.2.0: {}
|
||||
|
||||
ip-address@10.0.1: {}
|
||||
|
||||
ipaddr.js@1.9.1: {}
|
||||
|
||||
is-arrayish@0.2.1: {}
|
||||
@@ -1800,8 +1899,6 @@ snapshots:
|
||||
|
||||
is-stream@2.0.1: {}
|
||||
|
||||
is-stream@4.0.1: {}
|
||||
|
||||
isarray@1.0.0: {}
|
||||
|
||||
isexe@2.0.0: {}
|
||||
@@ -1846,7 +1943,7 @@ snapshots:
|
||||
jwa: 2.0.1
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
knex@3.1.0(better-sqlite3@12.6.2)(mysql2@3.17.1)(pg@8.18.0):
|
||||
knex@3.1.0(better-sqlite3@12.6.2)(mysql2@3.18.2(@types/node@25.3.3))(pg@8.19.0):
|
||||
dependencies:
|
||||
colorette: 2.0.19
|
||||
commander: 10.0.1
|
||||
@@ -1864,8 +1961,8 @@ snapshots:
|
||||
tildify: 2.0.0
|
||||
optionalDependencies:
|
||||
better-sqlite3: 12.6.2
|
||||
mysql2: 3.17.1
|
||||
pg: 8.18.0
|
||||
mysql2: 3.18.2(@types/node@25.3.3)
|
||||
pg: 8.19.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -1925,28 +2022,27 @@ snapshots:
|
||||
|
||||
mimic-response@3.1.0: {}
|
||||
|
||||
minimatch@5.1.6:
|
||||
minimatch@5.1.9:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimatch@9.0.5:
|
||||
minimatch@9.0.9:
|
||||
dependencies:
|
||||
brace-expansion: 2.0.2
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minipass@7.1.2: {}
|
||||
minipass@7.1.3: {}
|
||||
|
||||
mkdirp-classic@0.5.3: {}
|
||||
|
||||
moment@2.30.1: {}
|
||||
|
||||
ms@2.1.2: {}
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
mysql2@3.17.1:
|
||||
mysql2@3.18.2(@types/node@25.3.3):
|
||||
dependencies:
|
||||
'@types/node': 25.3.3
|
||||
aws-ssl-profiles: 1.1.2
|
||||
denque: 2.1.0
|
||||
generate-function: 2.3.1
|
||||
@@ -1954,8 +2050,7 @@ snapshots:
|
||||
long: 5.3.2
|
||||
lru.min: 1.1.4
|
||||
named-placeholders: 1.1.6
|
||||
seq-queue: 0.0.5
|
||||
sql-escaper: 1.3.2
|
||||
sql-escaper: 1.3.3
|
||||
|
||||
named-placeholders@1.1.6:
|
||||
dependencies:
|
||||
@@ -1971,16 +2066,16 @@ snapshots:
|
||||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
oauth4webapi@3.8.4: {}
|
||||
oauth4webapi@3.8.5: {}
|
||||
|
||||
object-inspect@1.13.4: {}
|
||||
|
||||
objection@3.1.5(knex@3.1.0(better-sqlite3@12.6.2)(mysql2@3.17.1)(pg@8.18.0)):
|
||||
objection@3.1.5(knex@3.1.0(better-sqlite3@12.6.2)(mysql2@3.18.2(@types/node@25.3.3))(pg@8.19.0)):
|
||||
dependencies:
|
||||
ajv: 8.18.0
|
||||
ajv-formats: 2.1.1(ajv@8.18.0)
|
||||
db-errors: 0.2.3
|
||||
knex: 3.1.0(better-sqlite3@12.6.2)(mysql2@3.17.1)(pg@8.18.0)
|
||||
knex: 3.1.0(better-sqlite3@12.6.2)(mysql2@3.18.2(@types/node@25.3.3))(pg@8.19.0)
|
||||
|
||||
on-finished@2.4.1:
|
||||
dependencies:
|
||||
@@ -1995,7 +2090,7 @@ snapshots:
|
||||
openid-client@6.8.2:
|
||||
dependencies:
|
||||
jose: 6.1.3
|
||||
oauth4webapi: 3.8.4
|
||||
oauth4webapi: 3.8.5
|
||||
|
||||
otplib@13.3.0:
|
||||
dependencies:
|
||||
@@ -2034,7 +2129,7 @@ snapshots:
|
||||
path-scurry@1.11.1:
|
||||
dependencies:
|
||||
lru-cache: 10.4.3
|
||||
minipass: 7.1.2
|
||||
minipass: 7.1.3
|
||||
|
||||
path-to-regexp@8.3.0: {}
|
||||
|
||||
@@ -2047,11 +2142,11 @@ snapshots:
|
||||
|
||||
pg-int8@1.0.1: {}
|
||||
|
||||
pg-pool@3.11.0(pg@8.18.0):
|
||||
pg-pool@3.12.0(pg@8.19.0):
|
||||
dependencies:
|
||||
pg: 8.18.0
|
||||
pg: 8.19.0
|
||||
|
||||
pg-protocol@1.11.0: {}
|
||||
pg-protocol@1.12.0: {}
|
||||
|
||||
pg-types@2.2.0:
|
||||
dependencies:
|
||||
@@ -2061,11 +2156,11 @@ snapshots:
|
||||
postgres-date: 1.0.7
|
||||
postgres-interval: 1.2.0
|
||||
|
||||
pg@8.18.0:
|
||||
pg@8.19.0:
|
||||
dependencies:
|
||||
pg-connection-string: 2.11.0
|
||||
pg-pool: 3.11.0(pg@8.18.0)
|
||||
pg-protocol: 1.11.0
|
||||
pg-pool: 3.12.0(pg@8.19.0)
|
||||
pg-protocol: 1.12.0
|
||||
pg-types: 2.2.0
|
||||
pgpass: 1.0.5
|
||||
optionalDependencies:
|
||||
@@ -2101,7 +2196,7 @@ snapshots:
|
||||
mkdirp-classic: 0.5.3
|
||||
napi-build-utils: 2.0.0
|
||||
node-abi: 3.87.0
|
||||
pump: 3.0.3
|
||||
pump: 3.0.4
|
||||
rc: 1.2.8
|
||||
simple-get: 4.0.1
|
||||
tar-fs: 2.1.4
|
||||
@@ -2116,12 +2211,12 @@ snapshots:
|
||||
forwarded: 0.2.0
|
||||
ipaddr.js: 1.9.1
|
||||
|
||||
pump@3.0.3:
|
||||
pump@3.0.4:
|
||||
dependencies:
|
||||
end-of-stream: 1.4.5
|
||||
once: 1.4.0
|
||||
|
||||
qs@6.14.2:
|
||||
qs@6.15.0:
|
||||
dependencies:
|
||||
side-channel: 1.1.0
|
||||
|
||||
@@ -2167,7 +2262,7 @@ snapshots:
|
||||
|
||||
readdir-glob@1.1.3:
|
||||
dependencies:
|
||||
minimatch: 5.1.6
|
||||
minimatch: 5.1.9
|
||||
|
||||
rechoir@0.8.0:
|
||||
dependencies:
|
||||
@@ -2217,8 +2312,6 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
seq-queue@0.0.5: {}
|
||||
|
||||
serve-static@2.2.1:
|
||||
dependencies:
|
||||
encodeurl: 2.0.0
|
||||
@@ -2282,7 +2375,7 @@ snapshots:
|
||||
|
||||
split2@4.2.0: {}
|
||||
|
||||
sql-escaper@1.3.2: {}
|
||||
sql-escaper@1.3.3: {}
|
||||
|
||||
statuses@2.0.2: {}
|
||||
|
||||
@@ -2292,7 +2385,7 @@ snapshots:
|
||||
dependencies:
|
||||
events-universal: 1.0.1
|
||||
fast-fifo: 1.3.2
|
||||
text-decoder: 1.2.6
|
||||
text-decoder: 1.2.7
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
@@ -2307,7 +2400,7 @@ snapshots:
|
||||
dependencies:
|
||||
eastasianwidth: 0.2.0
|
||||
emoji-regex: 9.2.2
|
||||
strip-ansi: 7.1.2
|
||||
strip-ansi: 7.2.0
|
||||
|
||||
string_decoder@1.1.1:
|
||||
dependencies:
|
||||
@@ -2321,7 +2414,7 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
|
||||
strip-ansi@7.1.2:
|
||||
strip-ansi@7.2.0:
|
||||
dependencies:
|
||||
ansi-regex: 6.2.2
|
||||
|
||||
@@ -2335,11 +2428,20 @@ snapshots:
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
swagger-ui-dist@5.32.0:
|
||||
dependencies:
|
||||
'@scarf/scarf': 1.4.0
|
||||
|
||||
swagger-ui-express@5.0.1(express@5.2.1):
|
||||
dependencies:
|
||||
express: 5.2.1
|
||||
swagger-ui-dist: 5.32.0
|
||||
|
||||
tar-fs@2.1.4:
|
||||
dependencies:
|
||||
chownr: 1.1.4
|
||||
mkdirp-classic: 0.5.3
|
||||
pump: 3.0.3
|
||||
pump: 3.0.4
|
||||
tar-stream: 2.2.0
|
||||
|
||||
tar-stream@2.2.0:
|
||||
@@ -2350,28 +2452,29 @@ snapshots:
|
||||
inherits: 2.0.4
|
||||
readable-stream: 3.6.2
|
||||
|
||||
tar-stream@3.1.7:
|
||||
tar-stream@3.1.8:
|
||||
dependencies:
|
||||
b4a: 1.7.4
|
||||
b4a: 1.8.0
|
||||
bare-fs: 4.5.5
|
||||
fast-fifo: 1.3.2
|
||||
streamx: 2.23.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- bare-buffer
|
||||
- react-native-b4a
|
||||
|
||||
tarn@3.0.2: {}
|
||||
|
||||
teex@1.0.1:
|
||||
dependencies:
|
||||
streamx: 2.23.0
|
||||
transitivePeerDependencies:
|
||||
- bare-abort-controller
|
||||
- react-native-b4a
|
||||
|
||||
tarn@3.0.2: {}
|
||||
|
||||
temp-dir@3.0.0: {}
|
||||
|
||||
temp-write@6.0.1:
|
||||
text-decoder@1.2.7:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
is-stream: 4.0.1
|
||||
temp-dir: 3.0.0
|
||||
|
||||
text-decoder@1.2.6:
|
||||
dependencies:
|
||||
b4a: 1.7.4
|
||||
b4a: 1.8.0
|
||||
transitivePeerDependencies:
|
||||
- react-native-b4a
|
||||
|
||||
@@ -2389,6 +2492,8 @@ snapshots:
|
||||
media-typer: 1.1.0
|
||||
mime-types: 3.0.2
|
||||
|
||||
undici-types@7.18.2: {}
|
||||
|
||||
unpipe@1.0.0: {}
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
@@ -2409,7 +2514,7 @@ snapshots:
|
||||
dependencies:
|
||||
ansi-styles: 6.2.3
|
||||
string-width: 5.1.2
|
||||
strip-ansi: 7.1.2
|
||||
strip-ansi: 7.2.0
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
|
||||
36
backend/routes/docs.js
Normal file
36
backend/routes/docs.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import express from "express";
|
||||
import swaggerUi from "swagger-ui-express";
|
||||
import { debug, express as logger } from "../logger.js";
|
||||
import PACKAGE from "../package.json" with { type: "json" };
|
||||
import { getCompiledSchema } from "../schema/index.js";
|
||||
|
||||
const router = express.Router({
|
||||
caseSensitive: true,
|
||||
strict: true,
|
||||
mergeParams: true,
|
||||
});
|
||||
|
||||
router.use("/", swaggerUi.serve);
|
||||
|
||||
router
|
||||
.route("/")
|
||||
.options((_, res) => {
|
||||
res.sendStatus(204);
|
||||
})
|
||||
|
||||
/**
|
||||
* GET / (Now serves the Swagger UI interface)
|
||||
*/
|
||||
.get(async (req, res, next) => {
|
||||
try {
|
||||
const swaggerJSON = await getCompiledSchema();
|
||||
swaggerJSON.info.version = PACKAGE.version;
|
||||
swaggerJSON.servers[0].url = `${req.protocol}://${req.get("host")}/api`;
|
||||
res.status(200).send(swaggerUi.generateHTML(swaggerJSON));
|
||||
} catch (err) {
|
||||
debug(logger, `${req.method.toUpperCase()} ${req.originalUrl}: ${err}`);
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -10,6 +10,7 @@ import proxyHostsRoutes from "./nginx/proxy_hosts.js";
|
||||
import redirectionHostsRoutes from "./nginx/redirection_hosts.js";
|
||||
import streamsRoutes from "./nginx/streams.js";
|
||||
import reportsRoutes from "./reports.js";
|
||||
import docsRoutes from "./docs.js";
|
||||
import schemaRoutes from "./schema.js";
|
||||
import settingsRoutes from "./settings.js";
|
||||
import tokensRoutes from "./tokens.js";
|
||||
@@ -44,6 +45,7 @@ router.get(["/api", "/api/"], async (_, res /*, next*/) => {
|
||||
});
|
||||
});
|
||||
|
||||
router.use("/api/docs", docsRoutes);
|
||||
router.use("/api/schema", schemaRoutes);
|
||||
router.use("/api/tokens", tokensRoutes);
|
||||
if (isOIDCenabled) router.use("/api/oidc", oidcRoutes);
|
||||
|
||||
@@ -155,8 +155,8 @@ router
|
||||
* Validate certificates
|
||||
*/
|
||||
.post(async (req, res, next) => {
|
||||
if (!req.files) {
|
||||
res.status(400).send({ error: "No files were uploaded" });
|
||||
if (!req.files || Object.keys(req.files).length !== 2 || !req.files.certificate || !req.files.certificate_key) {
|
||||
res.status(400).send({ error: "certificate and certificate_key were not uploaded" });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -254,8 +254,8 @@ router
|
||||
* Upload certificates
|
||||
*/
|
||||
.post(async (req, res, next) => {
|
||||
if (!req.files) {
|
||||
res.status(400).send({ error: "No files were uploaded" });
|
||||
if (!req.files || Object.keys(req.files).length !== 2 || !req.files.certificate || !req.files.certificate_key) {
|
||||
res.status(400).send({ error: "certificate and certificate_key were not uploaded" });
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as client from "openid-client";
|
||||
import express from "express";
|
||||
import { rateLimit } from "express-rate-limit";
|
||||
import errs from "../lib/error.js";
|
||||
import internalToken from "../internal/token.js";
|
||||
import { oidc as logger } from "../logger.js";
|
||||
@@ -10,6 +11,18 @@ const router = express.Router({
|
||||
mergeParams: true,
|
||||
});
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 10 * 60 * 1000,
|
||||
limit: 10,
|
||||
standardHeaders: "draft-8",
|
||||
legacyHeaders: false,
|
||||
ipv6Subnet: 64,
|
||||
skipSuccessfulRequests: true,
|
||||
validate: { trustProxy: false },
|
||||
});
|
||||
|
||||
router.use(limiter);
|
||||
|
||||
router
|
||||
.route("/")
|
||||
.options((_, res) => {
|
||||
@@ -39,30 +52,30 @@ router
|
||||
code_challenge: await client.calculatePKCECodeChallenge(code_verifier),
|
||||
};
|
||||
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "lax" });
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "Strict" });
|
||||
res.cookie("npmplus_oidc_code_verifier", code_verifier, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Lax",
|
||||
path: "/api/oidc",
|
||||
});
|
||||
res.cookie("npmplus_oidc_state", parameters.state, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Lax",
|
||||
path: "/api/oidc",
|
||||
});
|
||||
res.cookie("npmplus_oidc_nonce", parameters.nonce, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Lax",
|
||||
path: "/api/oidc",
|
||||
});
|
||||
|
||||
res.redirect(await client.buildAuthorizationUrl(config, parameters).toString());
|
||||
} catch (err) {
|
||||
logger.error(`Callback error: ${err.message}`);
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "lax" });
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "Strict" });
|
||||
res.clearCookie("npmplus_oidc_state", { path: "/api/oidc" });
|
||||
res.clearCookie("npmplus_oidc_nonce", { path: "/api/oidc" });
|
||||
res.clearCookie("npmplus_oidc_code_verifier", { path: "/api/oidc" });
|
||||
@@ -115,7 +128,7 @@ router
|
||||
res.cookie("token", data.token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Strict",
|
||||
path: "/api",
|
||||
expires: new Date(data.expires),
|
||||
});
|
||||
|
||||
@@ -18,22 +18,11 @@ router
|
||||
/**
|
||||
* GET /schema
|
||||
*/
|
||||
.get(async (req, res) => {
|
||||
.get(async (req, res, next) => {
|
||||
try {
|
||||
const swaggerJSON = await getCompiledSchema();
|
||||
|
||||
let proto = req.protocol;
|
||||
if (typeof req.headers["x-forwarded-proto"] !== "undefined" && req.headers["x-forwarded-proto"]) {
|
||||
proto = req.headers["x-forwarded-proto"];
|
||||
}
|
||||
|
||||
let origin = `${proto}://${req.hostname}`;
|
||||
if (typeof req.headers.origin !== "undefined" && req.headers.origin) {
|
||||
origin = req.headers.origin;
|
||||
}
|
||||
|
||||
swaggerJSON.info.version = PACKAGE.version;
|
||||
swaggerJSON.servers[0].url = `${origin}/api`;
|
||||
swaggerJSON.servers[0].url = `${req.protocol}://${req.get("host")}/api`;
|
||||
res.status(200).send(swaggerJSON);
|
||||
} catch (err) {
|
||||
debug(logger, `${req.method.toUpperCase()} ${req.originalUrl}: ${err}`);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import express from "express";
|
||||
import { rateLimit } from "express-rate-limit";
|
||||
import internalToken from "../internal/token.js";
|
||||
import errs from "../lib/error.js";
|
||||
import jwtdecode from "../lib/express/jwt-decode.js";
|
||||
@@ -12,6 +13,19 @@ const router = express.Router({
|
||||
mergeParams: true,
|
||||
});
|
||||
|
||||
const limiter = rateLimit({
|
||||
windowMs: 5 * 60 * 1000,
|
||||
limit: 10,
|
||||
message: { error: { message: "Too many requests, please try again later." } },
|
||||
standardHeaders: "draft-8",
|
||||
legacyHeaders: false,
|
||||
ipv6Subnet: 64,
|
||||
skipSuccessfulRequests: true,
|
||||
validate: { trustProxy: false },
|
||||
});
|
||||
|
||||
router.use(limiter);
|
||||
|
||||
router
|
||||
.route("/")
|
||||
.options((_, res) => {
|
||||
@@ -28,7 +42,7 @@ router
|
||||
.get(jwtdecode(), async (req, res, next) => {
|
||||
if (!req.cookies?.token) {
|
||||
res.clearCookie("token", { path: "/api" });
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "lax" });
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "Strict" });
|
||||
return res.status(401).send({ expires: new Date(0).toISOString() });
|
||||
}
|
||||
|
||||
@@ -41,7 +55,7 @@ router
|
||||
res.cookie("token", data.token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Strict",
|
||||
path: "/api",
|
||||
expires: new Date(data.expires),
|
||||
});
|
||||
@@ -72,7 +86,7 @@ router
|
||||
res.cookie("token", result.token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Strict",
|
||||
path: "/api",
|
||||
expires: new Date(result.expires),
|
||||
});
|
||||
@@ -93,7 +107,7 @@ router
|
||||
.delete(async (req, res, next) => {
|
||||
try {
|
||||
res.clearCookie("token", { path: "/api" });
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "lax" });
|
||||
res.cookie("npmplus_oidc_no_redirect", "true", { secure: true, sameSite: "Strict" });
|
||||
res.status(200).send({ expires: new Date(0).toISOString() });
|
||||
} catch (err) {
|
||||
debug(logger, `${req.method.toUpperCase()} ${req.originalUrl}: ${err}`);
|
||||
|
||||
@@ -297,7 +297,7 @@ router
|
||||
res.cookie("token", result.token, {
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "lax",
|
||||
sameSite: "Strict",
|
||||
path: "/api",
|
||||
expires: new Date(result.expires),
|
||||
});
|
||||
|
||||
@@ -127,17 +127,17 @@
|
||||
"example": true
|
||||
},
|
||||
"block_exploits": {
|
||||
"description": "Should we block common exploits",
|
||||
"description": "This is always disabled. Your value will be ignored",
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"caching_enabled": {
|
||||
"description": "Should we cache assets",
|
||||
"description": "This is always disabled. Your value will be ignored",
|
||||
"type": "boolean",
|
||||
"example": false
|
||||
},
|
||||
"allow_websocket_upgrade": {
|
||||
"description": "Allow Websocket Upgrade for all paths",
|
||||
"description": "This is always enabled. Your value will be ignored",
|
||||
"type": "boolean",
|
||||
"example": true
|
||||
},
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
{
|
||||
"bearerAuth": {
|
||||
"type": "http",
|
||||
"scheme": "bearer",
|
||||
"bearerFormat": "JWT",
|
||||
"description": "JWT Bearer Token authentication"
|
||||
"cookieAuth": {
|
||||
"type": "apiKey",
|
||||
"in": "cookie",
|
||||
"name": "token"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
"type": "object",
|
||||
"description": "Token object",
|
||||
"required": [
|
||||
"expires",
|
||||
"token"
|
||||
"expires"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -11,11 +10,6 @@
|
||||
"description": "Token Expiry ISO Time String",
|
||||
"example": "2025-02-04T20:40:46.340Z",
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"description": "JWT Token",
|
||||
"example": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"admin"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"admin"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"access_lists.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"access_lists.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"access_lists.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"access_lists.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"access_lists.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"certificates.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"dead_hosts.manage"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"proxy_hosts.view"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
],
|
||||
"security": [
|
||||
{
|
||||
"bearerAuth": [
|
||||
"cookieAuth": [
|
||||
"proxy_hosts.manage"
|
||||
]
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user