Compare commits

..

1 Commits
v3 ... v2.9.17

Author SHA1 Message Date
063ac4619f Merge pull request #1966 from NginxProxyManager/develop
v2.9.17
2022-03-31 11:32:05 +10:00
1283 changed files with 49765 additions and 57829 deletions

View File

@ -1,8 +0,0 @@
# Ignore everything
*
# Only allow the following for docker build:
!backend/
!docker/
!scripts/
!test/

28
.gitignore vendored
View File

@ -1,29 +1,5 @@
git.idea
.env
.DS_Store
.idea
._*
*.code-workspace
vendor
bin/*
backend/config.json
backend/embed/assets
backend/.task
backend/coverage.out
backend/coverage.html
test/node_modules
*/node_modules
docs/.vuepress/dist
frontend/build
frontend/yarn-error.log
frontend/.npmrc
frontend/src/locale/lang
test/cypress/fixtures/example.json
.vscode
docker-build
data
dist
backend/embed/acme.sh
docker/dev/resolv.conf
docker/dev/dnsrouter-config.json.tmp
thunder-tests
test/cypress/videos
certbot-help.txt

View File

@ -1 +1 @@
3.0.0a
2.9.17

367
Jenkinsfile vendored
View File

@ -1,36 +1,21 @@
import groovy.transform.Field
@Field
def buildxPushTags = ""
def getVersion() {
ver = sh(script: 'cat .version', returnStdout: true)
return ver.trim()
}
def getCommit() {
ver = sh(script: 'git log -n 1 --format=%h', returnStdout: true)
return ver.trim()
}
pipeline {
agent {
label 'docker-multiarch'
}
options {
buildDiscarder(logRotator(numToKeepStr: '10'))
buildDiscarder(logRotator(numToKeepStr: '5'))
disableConcurrentBuilds()
ansiColor('xterm')
}
environment {
DOCKER_ORG = 'jc21'
IMAGE = 'nginx-proxy-manager'
IMAGE = "nginx-proxy-manager"
BUILD_VERSION = getVersion()
BUILD_COMMIT = getCommit()
MAJOR_VERSION = '3'
BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('\\\\', '-').replaceAll('/', '-').replaceAll('\\.', '-')}"
BUILDX_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}"
MAJOR_VERSION = "2"
BRANCH_LOWER = "${BRANCH_NAME.toLowerCase().replaceAll('/', '-')}"
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}"
COMPOSE_FILE = 'docker/docker-compose.ci.yml'
COMPOSE_INTERACTIVE_NO_CLI = 1
BUILDX_NAME = "${COMPOSE_PROJECT_NAME}"
}
stages {
stage('Environment') {
@ -41,9 +26,7 @@ pipeline {
}
steps {
script {
buildxPushTags = "-t docker.io/${DOCKER_ORG}/${IMAGE}:${BUILD_VERSION} -t docker.io/${DOCKER_ORG}/${IMAGE}:${MAJOR_VERSION} -t docker.io/${DOCKER_ORG}/${IMAGE}:latest"
echo 'Building on Master is disabled!'
sh 'exit 1'
env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:${BUILD_VERSION} -t docker.io/jc21/${IMAGE}:${MAJOR_VERSION} -t docker.io/jc21/${IMAGE}:latest"
}
}
}
@ -56,148 +39,123 @@ pipeline {
steps {
script {
// Defaults to the Branch name, which is applies to all branches AND pr's
// buildxPushTags = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}"
buildxPushTags = "-t docker.io/${DOCKER_ORG}/${IMAGE}:v3"
env.BUILDX_PUSH_TAGS = "-t docker.io/jc21/${IMAGE}:github-${BRANCH_LOWER}"
}
}
}
}
}
stage('Build') {
parallel {
stage('Project') {
stage('Versions') {
steps {
sh './scripts/ci/build-frontend'
sh './scripts/ci/test-backend'
// Temporarily disable building backend binaries
// sh './scripts/ci/build-backend'
// Build the docker image used for testing below
sh '''docker build --pull --no-cache \\
-t "${IMAGE}:${BRANCH_LOWER}-ci-${BUILD_NUMBER}" \\
-f docker/Dockerfile \\
--build-arg BUILD_COMMIT="${BUILD_COMMIT}" \\
--build-arg BUILD_DATE="$(date '+%Y-%m-%d %T %Z')" \\
--build-arg BUILD_VERSION="${BUILD_VERSION}" \\
.
'''
}
post {
success {
junit 'test/results/junit/*'
// archiveArtifacts allowEmptyArchive: false, artifacts: 'bin/*'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: false,
keepAll: false,
reportDir: 'test/results/html-reports',
reportFiles: 'backend-coverage.html',
reportName: 'HTML Reports',
useWrapperFileDirectly: true
])
}
}
}
stage('Docs') {
steps {
dir(path: 'docs') {
sh 'yarn install'
sh 'yarn build'
}
sh 'cat frontend/package.json | jq --arg BUILD_VERSION "${BUILD_VERSION}" \'.version = $BUILD_VERSION\' | sponge frontend/package.json'
sh 'echo -e "\\E[1;36mFrontend Version is:\\E[1;33m $(cat frontend/package.json | jq -r .version)\\E[0m"'
sh 'cat backend/package.json | jq --arg BUILD_VERSION "${BUILD_VERSION}" \'.version = $BUILD_VERSION\' | sponge backend/package.json'
sh 'echo -e "\\E[1;36mBackend Version is:\\E[1;33m $(cat backend/package.json | jq -r .version)\\E[0m"'
sh 'sed -i -E "s/(version-)[0-9]+\\.[0-9]+\\.[0-9]+(-green)/\\1${BUILD_VERSION}\\2/" README.md'
}
}
}
}
stage('Test Sqlite') {
environment {
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_sqlite"
COMPOSE_FILE = 'docker/docker-compose.ci.yml'
}
when {
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
stage('Frontend') {
steps {
sh 'rm -rf ./test/results/junit/*'
sh './scripts/ci/fulltest-cypress'
// Adding this here as the schema needs to come from a running stack, but this will be used by docs later
sh 'docker-compose exec -T fullstack curl -s --output /temp-docs/api-schema.json "http://fullstack:81/api/schema"'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug/sqlite'
sh 'docker logs $(docker-compose ps --all -q fullstack) > debug/sqlite/docker_fullstack.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q stepca) > debug/sqlite/docker_stepca.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q pdns) > debug/sqlite/docker_pdns.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q pdns-db) > debug/sqlite/docker_pdns-db.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q dnsrouter) > debug/sqlite/docker_dnsrouter.log 2>&1'
junit 'test/results/junit/*'
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
}
sh './scripts/frontend-build'
}
}
stage('Test Mysql') {
environment {
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_mysql"
COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.mysql.yml'
}
when {
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
stage('Backend') {
steps {
sh 'rm -rf ./test/results/junit/*'
sh './scripts/ci/fulltest-cypress'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug/mysql'
sh 'docker logs $(docker-compose ps --all -q fullstack) > debug/mysql/docker_fullstack.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q stepca) > debug/mysql/docker_stepca.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q pdns) > debug/mysql/docker_pdns.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q pdns-db) > debug/mysql/docker_pdns-db.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q dnsrouter) > debug/mysql/docker_dnsrouter.log 2>&1'
junit 'test/results/junit/*'
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
}
}
}
stage('Test Postgres') {
environment {
COMPOSE_PROJECT_NAME = "npm_${BRANCH_LOWER}_${BUILD_NUMBER}_postgres"
COMPOSE_FILE = 'docker/docker-compose.ci.yml:docker/docker-compose.ci.postgres.yml'
}
when {
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
steps {
sh 'rm -rf ./test/results/junit/*'
sh './scripts/ci/fulltest-cypress'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug/postgres'
sh 'docker logs $(docker-compose ps --all -q fullstack) > debug/postgres/docker_fullstack.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q stepca) > debug/postgres/docker_stepca.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q pdns) > debug/postgres/docker_pdns.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q pdns-db) > debug/postgres/docker_pdns-db.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q dnsrouter) > debug/postgres/docker_dnsrouter.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q db-postgres) > debug/postgres/docker_db.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q authentik) > debug/postgres/docker_authentik.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q authentik-redis) > debug/postgres/docker_authentik-redis.log 2>&1'
sh 'docker logs $(docker-compose ps --all -q authentik-ldap) > debug/postgres/docker_authentik-ldap.log 2>&1'
echo 'Checking Syntax ...'
sh 'docker pull nginxproxymanager/nginx-full:certbot-node'
// See: https://github.com/yarnpkg/yarn/issues/3254
sh '''docker run --rm \\
-v "$(pwd)/backend:/app" \\
-v "$(pwd)/global:/app/global" \\
-w /app \\
nginxproxymanager/nginx-full:certbot-node \\
sh -c "yarn install && yarn eslint . && rm -rf node_modules"
'''
echo 'Docker Build ...'
sh '''docker build --pull --no-cache --squash --compress \\
-t "${IMAGE}:ci-${BUILD_NUMBER}" \\
-f docker/Dockerfile \\
--build-arg TARGETPLATFORM=linux/amd64 \\
--build-arg BUILDPLATFORM=linux/amd64 \\
--build-arg BUILD_VERSION="${BUILD_VERSION}" \\
--build-arg BUILD_COMMIT="${BUILD_COMMIT}" \\
--build-arg BUILD_DATE="$(date '+%Y-%m-%d %T %Z')" \\
.
'''
}
}
stage('Integration Tests Sqlite') {
steps {
// Bring up a stack
sh 'docker-compose up -d fullstack-sqlite'
sh './scripts/wait-healthy $(docker-compose ps -q fullstack-sqlite) 120'
// Run tests
sh 'rm -rf test/results'
sh 'docker-compose up cypress-sqlite'
// Get results
sh 'docker cp -L "$(docker-compose ps -q cypress-sqlite):/test/results" test/'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug'
sh 'docker-compose logs fullstack-sqlite | gzip > debug/docker_fullstack_sqlite.log.gz'
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
// Cypress videos and screenshot artifacts
dir(path: 'test/results') {
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
}
junit 'test/results/junit/*'
sh 'docker-compose down --remove-orphans --volumes -t 30 || true'
}
}
}
stage('Integration Tests Mysql') {
steps {
// Bring up a stack
sh 'docker-compose up -d fullstack-mysql'
sh './scripts/wait-healthy $(docker-compose ps -q fullstack-mysql) 120'
// Run tests
sh 'rm -rf test/results'
sh 'docker-compose up cypress-mysql'
// Get results
sh 'docker cp -L "$(docker-compose ps -q cypress-mysql):/test/results" test/'
}
post {
always {
// Dumps to analyze later
sh 'mkdir -p debug'
sh 'docker-compose logs fullstack-mysql | gzip > debug/docker_fullstack_mysql.log.gz'
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
// Cypress videos and screenshot artifacts
dir(path: 'test/results') {
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
}
junit 'test/results/junit/*'
}
}
}
stage('Docs') {
when {
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
steps {
dir(path: 'docs') {
sh 'yarn install'
sh 'yarn build'
}
dir(path: 'docs/.vuepress/dist') {
sh 'tar -czf ../../docs.tgz *'
}
archiveArtifacts(artifacts: 'docs/docs.tgz', allowEmptyArchive: false)
}
}
stage('MultiArch Build') {
when {
not {
@ -206,63 +164,90 @@ pipeline {
}
steps {
withCredentials([usernamePassword(credentialsId: 'jc21-dockerhub', passwordVariable: 'dpass', usernameVariable: 'duser')]) {
sh 'docker login -u "${duser}" -p "${dpass}"'
sh "./scripts/buildx --push ${buildxPushTags}"
// sh './scripts/buildx -o type=local,dest=docker-build'
// Docker Login
sh "docker login -u '${duser}' -p '${dpass}'"
// Buildx with push from cache
sh "./scripts/buildx --push ${BUILDX_PUSH_TAGS}"
}
}
}
stage('Docs / Comment') {
parallel {
stage('Docs Job') {
when {
allOf {
branch pattern: "^(develop|master|v3)\$", comparator: "REGEXP"
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
}
steps {
build wait: false, job: 'nginx-proxy-manager-docs', parameters: [string(name: 'docs_branch', value: "$BRANCH_NAME")]
stage('Docs Deploy') {
when {
allOf {
branch 'master'
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
stage('PR Comment') {
when {
allOf {
changeRequest()
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
}
steps {
script {
npmGithubPrComment("Docker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.", true)
}
}
steps {
withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', accessKeyVariable: 'AWS_ACCESS_KEY_ID', credentialsId: 'npm-s3-docs', secretKeyVariable: 'AWS_SECRET_ACCESS_KEY']]) {
sh """docker run --rm \\
--name \${COMPOSE_PROJECT_NAME}-docs-upload \\
-e S3_BUCKET=jc21-npm-site \\
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \\
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \\
-v \$(pwd):/app \\
-w /app \\
jc21/ci-tools \\
scripts/docs-upload /app/docs/.vuepress/dist/
"""
sh """docker run --rm \\
--name \${COMPOSE_PROJECT_NAME}-docs-invalidate \\
-e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \\
-e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \\
jc21/ci-tools \\
aws cloudfront create-invalidation --distribution-id EN1G6DEWZUTDT --paths '/*'
"""
}
}
}
stage('PR Comment') {
when {
allOf {
changeRequest()
not {
equals expected: 'UNSTABLE', actual: currentBuild.result
}
}
}
steps {
script {
def comment = pullRequest.comment("This is an automated message from CI:\n\nDocker Image for build ${BUILD_NUMBER} is available on [DockerHub](https://cloud.docker.com/repository/docker/jc21/${IMAGE}) as `jc21/${IMAGE}:github-${BRANCH_LOWER}`\n\n**Note:** ensure you backup your NPM instance before testing this PR image! Especially if this PR contains database changes.")
}
}
}
}
post {
always {
sh './scripts/ci/build-cleanup'
echo 'Reverting ownership'
sh 'docker run --rm -v $(pwd):/data jc21/gotools:latest chown -R "$(id -u):$(id -g)" /data'
printResult()
sh 'docker-compose down --rmi all --remove-orphans --volumes -t 30'
sh 'echo Reverting ownership'
sh 'docker run --rm -v $(pwd):/data jc21/ci-tools chown -R $(id -u):$(id -g) /data'
}
success {
juxtapose event: 'success'
sh 'figlet "SUCCESS"'
}
failure {
archiveArtifacts(artifacts: 'debug/**/*', allowEmptyArchive: true)
dir(path: 'test') {
archiveArtifacts allowEmptyArchive: true, artifacts: 'results/**/*', excludes: '**/*.xml'
}
archiveArtifacts(artifacts: 'debug/**.*', allowEmptyArchive: true)
juxtapose event: 'failure'
sh 'figlet "FAILURE"'
}
unstable {
archiveArtifacts(artifacts: 'debug/**/*', allowEmptyArchive: true)
dir(path: 'test') {
archiveArtifacts allowEmptyArchive: true, artifacts: 'results/**/*', excludes: '**/*.xml'
}
archiveArtifacts(artifacts: 'debug/**.*', allowEmptyArchive: true)
juxtapose event: 'unstable'
sh 'figlet "UNSTABLE"'
}
}
}
def getVersion() {
ver = sh(script: 'cat .version', returnStdout: true)
return ver.trim()
}
def getCommit() {
ver = sh(script: 'git log -n 1 --format=%h', returnStdout: true)
return ver.trim()
}

469
README.md
View File

@ -1,13 +1,19 @@
<p align="center">
<img src="https://nginxproxymanager.com/github.png">
<br><br>
<img src="https://img.shields.io/badge/version-2.9.19-green.svg?style=for-the-badge">
<img src="https://img.shields.io/badge/version-2.9.17-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a>
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager">
<img src="https://img.shields.io/docker/pulls/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a>
<a href="https://gitter.im/nginx-proxy-manager/community">
<img alt="Gitter" src="https://img.shields.io/gitter/room/nginx-proxy-manager/community?style=for-the-badge">
</a>
<a href="https://reddit.com/r/nginxproxymanager">
<img alt="Reddit" src="https://img.shields.io/reddit/subreddit-subscribers/nginxproxymanager?label=Reddit%20Community&style=for-the-badge">
</a>
</p>
This project comes as a pre-built docker image that enables you to easily forward to your websites
@ -29,7 +35,7 @@ so that the barrier for entry here is low.
## Features
- Beautiful and Secure Admin Interface based on [Chakra UI](https://chakra-ui.com/)
- Beautiful and Secure Admin Interface based on [Tabler](https://tabler.github.io/)
- Easily create forwarding domains, redirections, streams and 404 hosts without knowing anything about Nginx
- Free SSL using Let's Encrypt or provide your own custom SSL certificates
- Access Lists and basic HTTP Authentication for your hosts
@ -46,8 +52,7 @@ I won't go in to too much detail here but here are the basics for someone new to
3. Configure your domain name details to point to your home, either with a static ip or a service like DuckDNS or [Amazon Route53](https://github.com/jc21/route53-ddns)
4. Use the Nginx Proxy Manager as your gateway to forward to your other web based services
## Quickest Setup
## Quick Setup
1. Install Docker and Docker-Compose
@ -60,7 +65,7 @@ I won't go in to too much detail here but here are the basics for someone new to
version: '3'
services:
app:
image: 'jc21/nginx-proxy-manager:v3'
image: 'jc21/nginx-proxy-manager:latest'
restart: unless-stopped
ports:
- '80:80'
@ -68,34 +73,460 @@ services:
- '443:443'
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
```
3. Bring up your stack by running
```bash
docker-compose up -d
# If using docker-compose-plugin
docker compose up -d
```
4. Log in to the Admin UI
When your docker container is running, connect to it on port `81` for the admin interface.
Sometimes this can take a little bit because of the entropy of keys.
[http://127.0.0.1:81](http://127.0.0.1:81)
Default Admin User:
```
Email: admin@example.com
Password: changeme
```
Immediately after logging in with this default user you will be asked to modify your details and change your password.
## Contributors
Special thanks to [all of our contributors](https://github.com/NginxProxyManager/nginx-proxy-manager/graphs/contributors).
Special thanks to the following contributors:
## Getting Support
1. [Found a bug?](https://github.com/NginxProxyManager/nginx-proxy-manager/issues)
2. [Discussions](https://github.com/NginxProxyManager/nginx-proxy-manager/discussions)
3. [Development Gitter](https://gitter.im/nginx-proxy-manager/community)
4. [Reddit](https://reddit.com/r/nginxproxymanager)
## Become a Contributor
A guide to setting up your own development environment [is found here](DEV-README.md).
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center">
<a href="https://github.com/chaptergy">
<img src="https://avatars2.githubusercontent.com/u/26956711?s=460&u=7d9adebabb6b4e7af7cb05d98d751087a372304b&v=4" width="80" alt=""/>
<br /><sub><b>chaptergy</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Indemnity83">
<img src="https://avatars3.githubusercontent.com/u/35218?s=460&u=7082004ff35138157c868d7d9c683ccebfce5968&v=4" width="80" alt=""/>
<br /><sub><b>Kyle Klaus</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/theraw">
<img src="https://avatars1.githubusercontent.com/u/32969774?s=460&u=6b359971e15685fb0359e6a8c065a399b40dc228&v=4" width="80" alt=""/>
<br /><sub><b>ƬHE ЯAW</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/spalger">
<img src="https://avatars2.githubusercontent.com/u/1329312?s=400&u=565223e38f1c052afb4c5dcca3fcf1c63ba17ae7&v=4" width="80" alt=""/>
<br /><sub><b>Spencer</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Xantios">
<img src="https://avatars3.githubusercontent.com/u/1507836?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Xantios Krugor</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/dpanesso">
<img src="https://avatars2.githubusercontent.com/u/2687121?s=460&v=4" width="80" alt=""/>
<br /><sub><b>David Panesso</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/IronTooch">
<img src="https://avatars3.githubusercontent.com/u/27360514?s=460&u=69bf854a6647c55725f62ecb8d39249c6c0b2602&v=4" width="80" alt=""/>
<br /><sub><b>IronTooch</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/damianog">
<img src="https://avatars1.githubusercontent.com/u/2786682?s=460&u=76c6136fae797abb76b951cd8a246dcaecaf21af&v=4" width="80" alt=""/>
<br /><sub><b>Damiano</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/tfmm">
<img src="https://avatars3.githubusercontent.com/u/6880538?s=460&u=ce0160821cc4aa802df8395200f2d4956a5bc541&v=4" width="80" alt=""/>
<br /><sub><b>Russ</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/margaale">
<img src="https://avatars3.githubusercontent.com/u/20794934?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Marcelo Castagna</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Steven-Harris">
<img src="https://avatars2.githubusercontent.com/u/7720242?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Steven Harris</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/jlesage">
<img src="https://avatars0.githubusercontent.com/u/1791123?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Jocelyn Le Sage</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/cmer">
<img src="https://avatars0.githubusercontent.com/u/412?s=460&u=67dd8b2e3661bfd6f68ec1eaa5b9821bd8a321cd&v=4" width="80" alt=""/>
<br /><sub><b>Carl Mercier</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/the1ts">
<img src="https://avatars1.githubusercontent.com/u/84956?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Paul Mansfield</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/OhHeyAlan">
<img src="https://avatars0.githubusercontent.com/u/11955126?s=460&u=fbaa5a1a4f73ef8960132c703349bfd037fe2630&v=4" width="80" alt=""/>
<br /><sub><b>OhHeyAlan</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/dogmatic69">
<img src="https://avatars2.githubusercontent.com/u/94674?s=460&u=ca7647de53145c6283b6373ade5dc94ba99347db&v=4" width="80" alt=""/>
<br /><sub><b>Carl Sutton</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/tg44">
<img src="https://avatars0.githubusercontent.com/u/31839?s=460&u=ad32f4cadfef5e5fb09cdfa4b7b7b36a99ba6811&v=4" width="80" alt=""/>
<br /><sub><b>Gergő Törcsvári</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/vrenjith">
<img src="https://avatars3.githubusercontent.com/u/2093241?s=460&u=96ce93a9bebabdd0a60a2dc96cd093a41d5edaba&v=4" width="80" alt=""/>
<br /><sub><b>vrenjith</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/duhruh">
<img src="https://avatars2.githubusercontent.com/u/1133969?s=460&u=c0691e6131ec6d516416c1c6fcedb5034f877bbe&v=4" width="80" alt=""/>
<br /><sub><b>David Rivera</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/jipjan">
<img src="https://avatars2.githubusercontent.com/u/1384618?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Jaap-Jan de Wit</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/jmwebslave">
<img src="https://avatars2.githubusercontent.com/u/6118262?s=460&u=7db409c47135b1e141c366bbb03ed9fae6ac2638&v=4" width="80" alt=""/>
<br /><sub><b>James Morgan</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/Subv">
<img src="https://avatars1.githubusercontent.com/u/357072?s=460&u=d8adcdc91d749ae53e177973ed9b6bb6c4c894a3&v=4" width="80" alt=""/>
<br /><sub><b>Sebastian Valle</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Philip-Mooney">
<img src="https://avatars0.githubusercontent.com/u/48624631?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Philip Mooney</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/WaterCalm">
<img src="https://avatars1.githubusercontent.com/u/23502129?s=400&v=4" width="80" alt=""/>
<br /><sub><b>WaterCalm</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/lebrou34">
<img src="https://avatars1.githubusercontent.com/u/16373103?s=460&v=4" width="80" alt=""/>
<br /><sub><b>lebrou34</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/lightglitch">
<img src="https://avatars0.githubusercontent.com/u/196953?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Mário Franco</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/klutchell">
<img src="https://avatars3.githubusercontent.com/u/20458272?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Kyle Harding</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ahgraber">
<img src="https://avatars.githubusercontent.com/u/24922003?s=460&u=8376c9f00af9b6057ba4d2fb03b4f1b20a75277f&v=4" width="80" alt=""/>
<br /><sub><b>Alex Graber</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/MooBaloo">
<img src="https://avatars.githubusercontent.com/u/9493496?s=460&v=4" width="80" alt=""/>
<br /><sub><b>MooBaloo</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Shuro">
<img src="https://avatars.githubusercontent.com/u/944030?s=460&v=4" width="80" alt=""/>
<br /><sub><b>Shuro</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/lorisbergeron">
<img src="https://avatars.githubusercontent.com/u/51918567?s=460&u=778e4ff284b7d7304450f98421c99f79298371fb&v=4" width="80" alt=""/>
<br /><sub><b>Loris Bergeron</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/hepelayo">
<img src="https://avatars.githubusercontent.com/u/8243119?v=4" width="80" alt=""/>
<br /><sub><b>hepelayo</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/jonasled">
<img src="https://avatars.githubusercontent.com/u/46790650?v=4" width="80" alt=""/>
<br /><sub><b>Jonas Leder</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/stegmannb">
<img src="https://avatars.githubusercontent.com/u/12850482?v=4" width="80" alt=""/>
<br /><sub><b>Bastian Stegmann</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Stealthii">
<img src="https://avatars.githubusercontent.com/u/998920?v=4" width="80" alt=""/>
<br /><sub><b>Stealthii</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/thegamingninja">
<img src="https://avatars.githubusercontent.com/u/8020534?v=4" width="80" alt=""/>
<br /><sub><b>THEGamingninja</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/italobb">
<img src="https://avatars.githubusercontent.com/u/1801687?v=4" width="80" alt=""/>
<br /><sub><b>Italo Borssatto</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/GurjinderSingh">
<img src="https://avatars.githubusercontent.com/u/3470709?v=4" width="80" alt=""/>
<br /><sub><b>Gurjinder Singh</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/phantomski77">
<img src="https://avatars.githubusercontent.com/u/69464125?v=4" width="80" alt=""/>
<br /><sub><b>David Dosoudil</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ijaron">
<img src="https://avatars.githubusercontent.com/u/5156472?v=4" width="80" alt=""/>
<br /><sub><b>ijaron</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/nielscil">
<img src="https://avatars.githubusercontent.com/u/9073152?v=4" width="80" alt=""/>
<br /><sub><b>Niels Bouma</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ogarai">
<img src="https://avatars.githubusercontent.com/u/2949572?v=4" width="80" alt=""/>
<br /><sub><b>Orko Garai</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/baruffaldi">
<img src="https://avatars.githubusercontent.com/u/36949?v=4" width="80" alt=""/>
<br /><sub><b>Filippo Baruffaldi</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bikram990">
<img src="https://avatars.githubusercontent.com/u/6782131?v=4" width="80" alt=""/>
<br /><sub><b>Bikramjeet Singh</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/razvanstoica89">
<img src="https://avatars.githubusercontent.com/u/28236583?v=4" width="80" alt=""/>
<br /><sub><b>Razvan Stoica</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/psharma04">
<img src="https://avatars.githubusercontent.com/u/22587474?v=4" width="80" alt=""/>
<br /><sub><b>RBXII3</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/demize">
<img src="https://avatars.githubusercontent.com/u/264914?v=4" width="80" alt=""/>
<br /><sub><b>demize</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/PUP-Loki">
<img src="https://avatars.githubusercontent.com/u/75944209?v=4" width="80" alt=""/>
<br /><sub><b>PUP-Loki</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/DSorlov">
<img src="https://avatars.githubusercontent.com/u/8133650?v=4" width="80" alt=""/>
<br /><sub><b>Daniel Sörlöv</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/Theyooo">
<img src="https://avatars.githubusercontent.com/u/58510131?v=4" width="80" alt=""/>
<br /><sub><b>Theyooo</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/mrdink">
<img src="https://avatars.githubusercontent.com/u/514751?v=4" width="80" alt=""/>
<br /><sub><b>Justin Peacock</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ChrisTracy">
<img src="https://avatars.githubusercontent.com/u/58871574?v=4" width="80" alt=""/>
<br /><sub><b>Chris Tracy</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/Fuechslein">
<img src="https://avatars.githubusercontent.com/u/15112818?v=4" width="80" alt=""/>
<br /><sub><b>Fuechslein</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/nightah">
<img src="https://avatars.githubusercontent.com/u/3339418?v=4" width="80" alt=""/>
<br /><sub><b>Amir Zarrinkafsh</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/gabbe">
<img src="https://avatars.githubusercontent.com/u/156397?v=4" width="80" alt=""/>
<br /><sub><b>gabbe</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bmbvenom">
<img src="https://avatars.githubusercontent.com/u/20530371?v=4" width="80" alt=""/>
<br /><sub><b>bmbvenom</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/FMeinicke">
<img src="https://avatars.githubusercontent.com/u/42121639?v=4" width="80" alt=""/>
<br /><sub><b>Florian Meinicke</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ssrahul96">
<img src="https://avatars.githubusercontent.com/u/15570570?v=4" width="80" alt=""/>
<br /><sub><b>Rahul Somasundaram</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/BjoernAkAManf">
<img src="https://avatars.githubusercontent.com/u/833043?v=4" width="80" alt=""/>
<br /><sub><b>Björn Heinrichs</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/realJoshByrnes">
<img src="https://avatars.githubusercontent.com/u/204185?v=4" width="80" alt=""/>
<br /><sub><b>Josh Byrnes</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/bergi9">
<img src="https://avatars.githubusercontent.com/u/5556750?v=4" width="80" alt=""/>
<br /><sub><b>bergi9</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/luoweihua7">
<img src="https://avatars.githubusercontent.com/u/3157520?v=4" width="80" alt=""/>
<br /><sub><b>luoweihua7</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/TobiasKneidl">
<img src="https://avatars.githubusercontent.com/u/26301707?v=4" width="80" alt=""/>
<br /><sub><b>Tobias Kneidl</b></sub>
</a>
</td>
</tr>
<tr>
<td align="center">
<a href="https://github.com/piuswalter">
<img src="https://avatars.githubusercontent.com/u/64539242?v=4" width="80" alt=""/>
<br /><sub><b>Pius Walter</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/troykelly">
<img src="https://avatars.githubusercontent.com/u/4564803?v=4" width="80" alt=""/>
<br /><sub><b>Troy Kelly</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/ivankristianto">
<img src="https://avatars.githubusercontent.com/u/656006?v=4" width="80" alt=""/>
<br /><sub><b>Ivan Kristianto</b></sub>
</a>
</td>
<td align="center">
<a href="https://github.com/omercnet">
<img src="https://avatars.githubusercontent.com/u/639682?v=4" width="80" alt=""/>
<br /><sub><b>Omer Cohen</b></sub>
</a>
</td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

View File

@ -1,8 +0,0 @@
root = true
[*]
indent_style = tab
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = false

73
backend/.eslintrc.json Normal file
View File

@ -0,0 +1,73 @@
{
"env": {
"node": true,
"es6": true
},
"extends": [
"eslint:recommended"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"align-assignments"
],
"rules": {
"arrow-parens": [
"error",
"always"
],
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"key-spacing": [
"error",
{
"align": "value"
}
],
"comma-spacing": [
"error",
{
"before": false,
"after": true
}
],
"func-call-spacing": [
"error",
"never"
],
"keyword-spacing": [
"error",
{
"before": true
}
],
"no-irregular-whitespace": "error",
"no-unused-expressions": 0,
"align-assignments/align-assignments": [
2,
{
"requiresOnly": false
}
]
}
}

8
backend/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
config/development.json
data/*
yarn-error.log
tmp
certbot.log
node_modules
core.*

View File

@ -1,166 +0,0 @@
---
linters:
enable:
# Prevents against memory leaks in production caused by not closing
# file handle
- bodyclose
# Detects cloned code. DRY is good programming practice. Can cause issues
# with testing code where simplicity is preferred over duplication.
# Disabled for test code.
# - dupl
# Detects unchecked errors in go programs. These unchecked errors can be
# critical bugs in some cases.
- errcheck
# Simplifies go code.
- gosimple
# Controls Go package import order and makes it always deterministic.
- gci
# Reports suspicious constructs, maintained by goteam. e.g. Printf unused
# params not caught at compile time.
- govet
# Detect security issues with gocode. Use of secrets in code or obsolete
# security algorithms. It's imaged heuristic methods are used in finding
# problems. If issues with rules are found particular rules can be disabled
# as required. Could possibility cause issues with testing.
# Disabled for test code.
- gosec
# Detect repeated strings that could be replaced by a constant
- goconst
# Misc linters missing from other projects. Grouped into 3 categories
# diagnostics, style and performance
- gocritic
# Limits code cyclomatic complexity
- gocyclo
# Detects if code needs to be gofmt'd
- gofmt
# Detects unused go package imports
- goimports
# Detects style mistakes not correctness. Golint is meant to carry out the
# stylistic conventions put forth in Effective Go and CodeReviewComments.
# golint has false positives and false negatives and can be tweaked.
- revive
# Detects ineffectual assignments in code
- ineffassign
# Reports long lines
# - lll
# Detect commonly misspelled english words in comments
- misspell
# Detect naked returns on non-trivial functions, and conform with
# Go CodeReviewComments
- nakedret
# Detect slice allocations that can be preallocated
- prealloc
# Misc collection of static analysis tools
- staticcheck
# Detects unused struct fields
# - structcheck
# Parses and typechecks the code like the go compiler
- typecheck
# Detects unused constants, variables, functions and types
- unused
# Remove unnecessary type conversions
- unconvert
# Remove unnecessary(unused) function parameters
- unparam
linters-settings:
errcheck:
exclude-functions:
- fmt.Fprint
- fmt.Fprintf
gci:
sections:
- standard # Standard section: captures all standard packages.
- localmodule # Local module section: contains all local packages.
# - prefix(gogs.jc21.com) # Prefixed gerrit.lan packages (jumgo).
- default # Everything else (github.com, golang.org, etc).
- blank # Blank section: contains all blank imports.
custom-order: true
goconst:
# minimal length of string constant
# default: 3
min-len: 2
# minimum number of occurrences of string constant
# default: 3
min-occurences: 2
revive:
enable-all-rules: true
rules:
- name: unchecked-type-assertion
disabled: true
# handled by goconst
- name: add-constant
disabled: true
# cant limit this arbitrarily
- name: argument-limit
disabled: true
# handled by gocyclo
- name: cognitive-complexity
disabled: true
# false positive for Exported vs non-exported functions of the same name
- name: confusing-naming
disabled: true
# false positives for "" - which is the nil value of a string (also 0)
- name: confusing-results
disabled: true
# handled by gocyclo
- name: cyclomatic
disabled: true
# have comments on exported functions but not on vars/types/constants
- name: exported
arguments:
- "disableChecksOnConstants"
- "disableChecksOnTypes"
- "disableChecksOnVariables"
# false positives on bool params
- name: flag-parameter
disabled: true
# extreme verticalization can happen
- name: function-length
disabled: true
# can false positive for non-getters
- name: get-return
disabled: true
# only allows lowercase names
- name: import-alias-naming
disabled: true
# handled by lll
- name: line-length-limit
disabled: true
# don't want to arbitrarily limit this
# many places have specific model.go files to contain all structs
- name: max-public-structs
disabled: true
# disable package-comments
- name: package-comments
disabled: true
# this is handled by errcheck
- name: unhandled-error
disabled: true
- name: function-result-limit
disabled: true
issues:
# Maximum count of issues with the same text. Set to 0 to disable. Default
# is 3. We have chosen an arbitrary value that works based on practical usage.
max-same: 20
# See cmdline flag documentation for more info about default excludes
# --exclude-use-default. Nothing is excluded by default
exclude-use-default: false
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
# Exclude some linters from running on tests files.
# TODO: Add examples why this is good
- path: _test\.go
linters:
# Tests should be simple? Add example why this is good?
- gocyclo
# Error checking adds verbosity and complexity for minimal value
- errcheck
# Table test encourage duplication in defining the table tests.
- dupl
# Hard coded example tokens, SQL injection and other bad practices may
# want to be tested
- gosec
# Test data can long
# - lll
run:
go: '1.23'

View File

@ -1,11 +1,11 @@
{
"printWidth": 80,
"tabWidth": 2,
"printWidth": 320,
"tabWidth": 4,
"useTabs": true,
"semi": true,
"singleQuote": false,
"singleQuote": true,
"bracketSpacing": true,
"bracketSameLine": true,
"jsxBracketSameLine": true,
"trailingComma": "all",
"proseWrap": "always"
}

View File

@ -1,21 +0,0 @@
---
# (mandatory)
# Path to coverprofile file (output of `go test -coverprofile` command).
profile: coverage.out
# (optional; but recommended to set)
# When specified reported file paths will not contain local prefix in the output
local-prefix: "npm"
# Holds coverage thresholds percentages, values should be in range [0-100]
threshold:
# (optional; default 0)
# The minimum coverage that each file should have
# file: 70
# (optional; default 0)
# The minimum coverage that each package should have
# package: 30
# (optional; default 0)
# The minimum total coverage project should have
total: 30

8
backend/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"editor.insertSpaces": false,
"editor.formatOnSave": true,
"files.trimTrailingWhitespace": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
}
}

View File

@ -1,6 +0,0 @@
# Backend
## Guides and materials
- [Nginx Proxy Protocol](https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/)
-

View File

@ -1,70 +0,0 @@
version: "3"
tasks:
default:
cmds:
- task: run
run:
desc: Build and run
sources:
- internal/**/*.go
- cmd/**/*.go
- ../frontend/src/locale/src/*.json
cmds:
- task: locale
- task: build
force: true
- cmd: echo -e "==> Running..."
silent: true
- cmd: ../dist/bin/server
ignore_error: true
silent: true
env:
LOG_LEVEL: debug
build:
desc: Build the server
cmds:
- cmd: echo -e "==> Building..."
silent: true
- cmd: rm -f dist/bin/*
silent: true
- cmd: go build -tags 'json1' -buildvcs=false -ldflags="-X main.commit={{.GIT_COMMIT}} -X main.version={{.VERSION}}" -o ../dist/bin/server ./cmd/server/main.go
silent: true
- cmd: go build -buildvcs=false -ldflags="-X main.commit={{.GIT_COMMIT}} -X main.version={{.VERSION}}" -o ../dist/bin/ipranges ./cmd/ipranges/main.go
silent: true
- cmd: rm -f /etc/nginx/conf.d/include/ipranges.conf && /app/dist/bin/ipranges > /etc/nginx/conf.d/include/ipranges.conf
- task: lint
vars:
GIT_COMMIT:
sh: git log -n 1 --format=%h
VERSION:
sh: cat ../.version
lint:
desc: Linting
cmds:
- cmd: echo -e "==> Linting..."
silent: true
- cmd: bash scripts/lint.sh
silent: true
test:
desc: Testing
cmds:
- cmd: echo -e "==> Testing..."
silent: true
- cmd: bash scripts/test.sh
silent: true
locale:
desc: Locale
dir: /app/frontend
cmds:
- cmd: yarn locale-compile
silent: true
ignore_error: true
- cmd: chown -R "$PUID:$PGID" src/locale/lang
silent: true
ignore_error: true

89
backend/app.js Normal file
View File

@ -0,0 +1,89 @@
const express = require('express');
const bodyParser = require('body-parser');
const fileUpload = require('express-fileupload');
const compression = require('compression');
const log = require('./logger').express;
/**
* App
*/
const app = express();
app.use(fileUpload());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// Gzip
app.use(compression());
/**
* General Logging, BEFORE routes
*/
app.disable('x-powered-by');
app.enable('trust proxy', ['loopback', 'linklocal', 'uniquelocal']);
app.enable('strict routing');
// pretty print JSON when not live
if (process.env.NODE_ENV !== 'production') {
app.set('json spaces', 2);
}
// CORS for everything
app.use(require('./lib/express/cors'));
// General security/cache related headers + server header
app.use(function (req, res, next) {
let x_frame_options = 'DENY';
if (typeof process.env.X_FRAME_OPTIONS !== 'undefined' && process.env.X_FRAME_OPTIONS) {
x_frame_options = process.env.X_FRAME_OPTIONS;
}
res.set({
'X-XSS-Protection': '1; mode=block',
'X-Content-Type-Options': 'nosniff',
'X-Frame-Options': x_frame_options,
'Cache-Control': 'no-cache, no-store, max-age=0, must-revalidate',
Pragma: 'no-cache',
Expires: 0
});
next();
});
app.use(require('./lib/express/jwt')());
app.use('/', require('./routes/api/main'));
// production error handler
// no stacktraces leaked to user
// eslint-disable-next-line
app.use(function (err, req, res, next) {
let payload = {
error: {
code: err.status,
message: err.public ? err.message : 'Internal Error'
}
};
if (process.env.NODE_ENV === 'development' || (req.baseUrl + req.path).includes('nginx/certificates')) {
payload.debug = {
stack: typeof err.stack !== 'undefined' && err.stack ? err.stack.split('\n') : null,
previous: err.previous
};
}
// Not every error is worth logging - but this is good for now until it gets annoying.
if (typeof err.stack !== 'undefined' && err.stack) {
if (process.env.NODE_ENV === 'development' || process.env.DEBUG) {
log.debug(err.stack);
} else if (typeof err.public == 'undefined' || !err.public) {
log.warn(err.message);
}
}
res
.status(err.status || 500)
.send(payload);
});
module.exports = app;

View File

@ -1,125 +0,0 @@
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"npm/internal/config"
"npm/internal/model"
"github.com/rotisserie/eris"
)
var commit string
var version string
var cloudfrontURL = "https://ip-ranges.amazonaws.com/ip-ranges.json"
var cloudflare4URL = "https://www.cloudflare.com/ips-v4"
var cloudflare6URL = "https://www.cloudflare.com/ips-v6"
func main() {
config.InitArgs(&version, &commit)
if err := config.InitIPRanges(&version, &commit); err != nil {
fmt.Printf("# Config ERROR: %v\n", err)
os.Exit(1)
}
exitCode := 0
// Cloudfront
fmt.Printf("# Cloudfront Ranges from: %s\n", cloudfrontURL)
if ranges, err := parseCloudfront(); err == nil {
for _, item := range ranges {
fmt.Printf("set_real_ip_from %s;\n", item)
}
} else {
fmt.Printf("# ERROR: %v\n", err)
}
// Cloudflare ipv4
if !config.Configuration.DisableIPV4 {
fmt.Printf("\n# Cloudflare Ranges from: %s\n", cloudflare4URL)
if ranges, err := parseCloudflare(cloudflare4URL); err == nil {
for _, item := range ranges {
fmt.Printf("set_real_ip_from %s;\n", item)
}
} else {
fmt.Printf("# ERROR: %v\n", err)
}
}
// Cloudflare ipv6
if !config.Configuration.DisableIPV6 {
fmt.Printf("\n# Cloudflare Ranges from: %s\n", cloudflare6URL)
if ranges, err := parseCloudflare(cloudflare6URL); err == nil {
for _, item := range ranges {
fmt.Printf("set_real_ip_from %s;\n", item)
}
} else {
fmt.Printf("# ERROR: %v\n", err)
}
}
// Done
os.Exit(exitCode)
}
func parseCloudfront() ([]string, error) {
// nolint: gosec
resp, err := http.Get(cloudfrontURL)
if err != nil {
return nil, eris.Wrapf(err, "Failed to download Cloudfront IP Ranges from %s", cloudfrontURL)
}
// nolint: errcheck, gosec
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, eris.Wrapf(err, "Failed to read Cloudfront IP Ranges body")
}
var result model.CloudfrontIPRanges
if err := json.Unmarshal(body, &result); err != nil {
return nil, eris.Wrapf(err, "Failed to unmarshal Cloudfront IP Ranges file")
}
ranges := make([]string, 0)
if !config.Configuration.DisableIPV4 {
for _, item := range result.IPV4Prefixes {
ranges = append(ranges, item.Value)
}
}
if !config.Configuration.DisableIPV6 {
for _, item := range result.IPV6Prefixes {
ranges = append(ranges, item.Value)
}
}
return ranges, nil
}
func parseCloudflare(url string) ([]string, error) {
// nolint: gosec
resp, err := http.Get(url)
if err != nil {
return nil, eris.Wrapf(err, "Failed to download Cloudflare IP Ranges from %s", url)
}
// nolint: errcheck, gosec
defer resp.Body.Close()
scanner := bufio.NewScanner(resp.Body)
scanner.Split(bufio.ScanLines)
ranges := make([]string, 0)
for scanner.Scan() {
if scanner.Text() != "" {
ranges = append(ranges, scanner.Text())
}
}
return ranges, nil
}

View File

@ -1,87 +0,0 @@
package main
import (
"os"
"os/signal"
"syscall"
"npm/internal/api"
"npm/internal/config"
"npm/internal/database"
"npm/internal/entity/certificate"
"npm/internal/entity/host"
"npm/internal/entity/user"
"npm/internal/errors"
"npm/internal/jobqueue"
"npm/internal/jwt"
"npm/internal/logger"
// properly respect available cpu cores
_ "go.uber.org/automaxprocs"
)
var commit string
var version string
func main() {
config.InitArgs(&version, &commit)
config.Init(&version, &commit)
config.CreateDataFolders()
logger.Info("Build Version: %s (%s)", version, commit)
database.Migrate(func() {
if err := jwt.LoadKeys(); err != nil {
logger.Error("KeysError", err)
os.Exit(1)
}
checkSetup()
// Internal Job Queue
jobqueue.Start()
certificate.AddPendingJobs()
host.AddPendingJobs()
// Http server
api.StartServer()
irqchan := make(chan os.Signal, 1)
signal.Notify(irqchan, syscall.SIGINT, syscall.SIGTERM)
for irq := range irqchan {
if irq == syscall.SIGINT || irq == syscall.SIGTERM {
logger.Info("Got ", irq, " shutting server down ...")
// Close db
sqlDB, _ := database.GetDB().DB()
err := sqlDB.Close()
if err != nil {
logger.Error("DatabaseCloseError", err)
}
// nolint
jobqueue.Shutdown()
break
}
}
})
}
// checkSetup Quick check by counting the number of users in the database
func checkSetup() {
db := database.GetDB()
var count int64
if db != nil {
db.Model(&user.Model{}).
Where("is_disabled = ?", false).
Where("is_system = ?", false).
Count(&count)
if count == 0 {
logger.Warn("No users found, starting in Setup Mode")
} else {
config.IsSetup = true
logger.Info("Application is setup")
}
} else {
logger.Error("DatabaseError", errors.ErrDatabaseUnavailable)
}
}

2
backend/config/README.md Normal file
View File

@ -0,0 +1,2 @@
These files are use in development and are not deployed as part of the final product.

View File

@ -0,0 +1,10 @@
{
"database": {
"engine": "mysql",
"host": "db",
"name": "npm",
"user": "npm",
"password": "npm",
"port": 3306
}
}

View File

@ -0,0 +1,26 @@
{
"database": {
"engine": "knex-native",
"knex": {
"client": "sqlite3",
"connection": {
"filename": "/app/config/mydb.sqlite"
},
"pool": {
"min": 0,
"max": 1,
"createTimeoutMillis": 3000,
"acquireTimeoutMillis": 30000,
"idleTimeoutMillis": 30000,
"reapIntervalMillis": 1000,
"createRetryIntervalMillis": 100,
"propagateCreateError": false
},
"migrations": {
"tableName": "migrations",
"stub": "src/backend/lib/migrate_template.js",
"directory": "src/backend/migrations"
}
}
}
}

33
backend/db.js Normal file
View File

@ -0,0 +1,33 @@
const config = require('config');
if (!config.has('database')) {
throw new Error('Database config does not exist! Please read the instructions: https://github.com/jc21/nginx-proxy-manager/blob/master/doc/INSTALL.md');
}
function generateDbConfig() {
if (config.database.engine === 'knex-native') {
return config.database.knex;
} else
return {
client: config.database.engine,
connection: {
host: config.database.host,
user: config.database.user,
password: config.database.password,
database: config.database.name,
port: config.database.port
},
migrations: {
tableName: 'migrations'
}
};
}
let data = generateDbConfig();
if (typeof config.database.version !== 'undefined') {
data.version = config.database.version;
}
module.exports = require('knex')(data);

1254
backend/doc/api.swagger.json Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,310 +0,0 @@
{
"openapi": "3.0.0",
"info": {
"title": "Nginx Proxy Manager API",
"version": "{{VERSION}}"
},
"paths": {
"/": {
"get": {
"$ref": "file://./paths/get.json"
}
},
"/auth": {
"get": {
"$ref": "file://./paths/auth/get.json"
},
"post": {
"$ref": "file://./paths/auth/post.json"
}
},
"/auth/refresh": {
"post": {
"$ref": "file://./paths/auth/refresh/post.json"
}
},
"/auth/sse": {
"post": {
"$ref": "file://./paths/auth/sse/post.json"
}
},
"/certificates": {
"get": {
"$ref": "file://./paths/certificates/get.json"
},
"post": {
"$ref": "file://./paths/certificates/post.json"
}
},
"/certificates/{certificateID}": {
"get": {
"$ref": "file://./paths/certificates/certificateID/get.json"
},
"put": {
"$ref": "file://./paths/certificates/certificateID/put.json"
},
"delete": {
"$ref": "file://./paths/certificates/certificateID/delete.json"
}
},
"/certificates-authorities": {
"get": {
"$ref": "file://./paths/certificates-authorities/get.json"
},
"post": {
"$ref": "file://./paths/certificates-authorities/post.json"
}
},
"/certificates-authorities/{caID}": {
"get": {
"$ref": "file://./paths/certificates-authorities/caID/get.json"
},
"put": {
"$ref": "file://./paths/certificates-authorities/caID/put.json"
},
"delete": {
"$ref": "file://./paths/certificates-authorities/caID/delete.json"
}
},
"/config": {
"get": {
"$ref": "file://./paths/config/get.json"
}
},
"/dns-providers": {
"get": {
"$ref": "file://./paths/dns-providers/get.json"
},
"post": {
"$ref": "file://./paths/dns-providers/post.json"
}
},
"/dns-providers/{providerID}": {
"get": {
"$ref": "file://./paths/dns-providers/providerID/get.json"
},
"put": {
"$ref": "file://./paths/dns-providers/providerID/put.json"
},
"delete": {
"$ref": "file://./paths/dns-providers/providerID/delete.json"
}
},
"/hosts": {
"get": {
"$ref": "file://./paths/hosts/get.json"
},
"post": {
"$ref": "file://./paths/hosts/post.json"
}
},
"/hosts/{hostID}": {
"get": {
"$ref": "file://./paths/hosts/hostID/get.json"
},
"put": {
"$ref": "file://./paths/hosts/hostID/put.json"
},
"delete": {
"$ref": "file://./paths/hosts/hostID/delete.json"
}
},
"/hosts/{hostID}/nginx-config": {
"get": {
"$ref": "file://./paths/hosts/hostID/nginx-config/get.json"
}
},
"/nginx-templates": {
"get": {
"$ref": "file://./paths/nginx-templates/get.json"
},
"post": {
"$ref": "file://./paths/nginx-templates/post.json"
}
},
"/nginx-templates/{templateID}": {
"get": {
"$ref": "file://./paths/nginx-templates/templateID/get.json"
},
"put": {
"$ref": "file://./paths/nginx-templates/templateID/put.json"
},
"delete": {
"$ref": "file://./paths/nginx-templates/templateID/delete.json"
}
},
"/schema": {
"get": {
"$ref": "file://./paths/schema/get.json"
}
},
"/settings": {
"get": {
"$ref": "file://./paths/settings/get.json"
},
"post": {
"$ref": "file://./paths/settings/post.json"
}
},
"/settings/{name}": {
"get": {
"$ref": "file://./paths/settings/name/get.json"
},
"put": {
"$ref": "file://./paths/settings/name/put.json"
}
},
"/streams": {
"get": {
"$ref": "file://./paths/streams/get.json"
},
"post": {
"$ref": "file://./paths/streams/post.json"
}
},
"/streams/{streamID}": {
"get": {
"$ref": "file://./paths/streams/streamID/get.json"
},
"put": {
"$ref": "file://./paths/streams/streamID/put.json"
},
"delete": {
"$ref": "file://./paths/streams/streamID/delete.json"
}
},
"/upstreams": {
"get": {
"$ref": "file://./paths/upstreams/get.json"
},
"post": {
"$ref": "file://./paths/upstreams/post.json"
}
},
"/upstreams/{upstreamID}": {
"get": {
"$ref": "file://./paths/upstreams/upstreamID/get.json"
},
"put": {
"$ref": "file://./paths/upstreams/upstreamID/put.json"
},
"delete": {
"$ref": "file://./paths/upstreams/upstreamID/delete.json"
}
},
"/upstreams/{upstreamID}/nginx-config": {
"get": {
"$ref": "file://./paths/upstreams/upstreamID/nginx-config/get.json"
}
},
"/users": {
"get": {
"$ref": "file://./paths/users/get.json"
},
"post": {
"$ref": "file://./paths/users/post.json"
}
},
"/users/{userID}": {
"get": {
"$ref": "file://./paths/users/userID/get.json"
},
"put": {
"$ref": "file://./paths/users/userID/put.json"
},
"delete": {
"$ref": "file://./paths/users/userID/delete.json"
}
},
"/users/{userID}/auth": {
"post": {
"$ref": "file://./paths/users/userID/auth/post.json"
}
}
},
"components": {
"schemas": {
"AuthConfigObject": {
"$ref": "file://./components/AuthConfigObject.json"
},
"CertificateAuthorityList": {
"$ref": "file://./components/CertificateAuthorityList.json"
},
"CertificateAuthorityObject": {
"$ref": "file://./components/CertificateAuthorityObject.json"
},
"CertificateList": {
"$ref": "file://./components/CertificateList.json"
},
"CertificateObject": {
"$ref": "file://./components/CertificateObject.json"
},
"ConfigObject": {
"$ref": "file://./components/ConfigObject.json"
},
"DeletedItemResponse": {
"$ref": "file://./components/DeletedItemResponse.json"
},
"DNSProviderList": {
"$ref": "file://./components/DNSProviderList.json"
},
"DNSProviderObject": {
"$ref": "file://./components/DNSProviderObject.json"
},
"ErrorObject": {
"$ref": "file://./components/ErrorObject.json"
},
"FilterObject": {
"$ref": "file://./components/FilterObject.json"
},
"HealthObject": {
"$ref": "file://./components/HealthObject.json"
},
"HostList": {
"$ref": "file://./components/HostList.json"
},
"HostObject": {
"$ref": "file://./components/HostObject.json"
},
"NginxTemplateList": {
"$ref": "file://./components/NginxTemplateList.json"
},
"NginxTemplateObject": {
"$ref": "file://./components/NginxTemplateObject.json"
},
"SettingList": {
"$ref": "file://./components/SettingList.json"
},
"SettingObject": {
"$ref": "file://./components/SettingObject.json"
},
"SortObject": {
"$ref": "file://./components/SortObject.json"
},
"StreamList": {
"$ref": "file://./components/StreamList.json"
},
"StreamObject": {
"$ref": "file://./components/StreamObject.json"
},
"TokenObject": {
"$ref": "file://./components/TokenObject.json"
},
"UpstreamList": {
"$ref": "file://./components/UpstreamList.json"
},
"UpstreamObject": {
"$ref": "file://./components/UpstreamObject.json"
},
"UserAuthObject": {
"$ref": "file://./components/UserAuthObject.json"
},
"UserList": {
"$ref": "file://./components/UserList.json"
},
"UserObject": {
"$ref": "file://./components/UserObject.json"
}
}
}
}

View File

@ -1,13 +0,0 @@
{
"type": "array",
"description": "AuthConfigObject",
"minItems": 1,
"items": {
"type": "string",
"enum": [
"local",
"ldap",
"oauth"
]
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "CertificateAuthorityList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
}
}

View File

@ -1,57 +0,0 @@
{
"type": "object",
"description": "CertificateAuthorityObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"name",
"acmesh_server",
"ca_bundle",
"max_domains",
"is_wildcard_supported",
"is_readonly"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"acmesh_server": {
"type": "string",
"minLength": 2,
"maxLength": 255
},
"ca_bundle": {
"type": "string",
"minLength": 0,
"maxLength": 255
},
"max_domains": {
"type": "integer",
"minimum": 1
},
"is_wildcard_supported": {
"type": "boolean"
},
"is_readonly": {
"type": "boolean"
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "CertificateList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CertificateObject"
}
}
}
}

View File

@ -1,86 +0,0 @@
{
"type": "object",
"description": "CertificateObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"expires_on",
"type",
"user_id",
"certificate_authority_id",
"dns_provider_id",
"name",
"is_ecc",
"status",
"domain_names"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"expires_on": {
"type": "integer",
"minimum": 0,
"nullable": true
},
"type": {
"type": "string",
"enum": ["custom", "http", "dns"]
},
"user_id": {
"type": "integer",
"minimum": 1
},
"certificate_authority_id": {
"type": "integer",
"minimum": 0
},
"certificate_authority": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
},
"dns_provider_id": {
"type": "integer",
"minimum": 0,
"nullable": true
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"domain_names": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 4
}
},
"status": {
"type": "string",
"enum": ["ready", "requesting", "failed", "provided"]
},
"is_ecc": {
"type": "boolean"
},
"error_message": {
"type": "string"
},
"user": {
"$ref": "#/components/schemas/UserObject"
}
}
}

View File

@ -1,4 +0,0 @@
{
"type": "object",
"description": "ConfigObject"
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "DNSProviderList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
}
}

View File

@ -1,51 +0,0 @@
{
"type": "object",
"description": "DNSProviderObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"user_id",
"name",
"acmesh_name",
"dns_sleep",
"meta"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"user_id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"acmesh_name": {
"type": "string",
"minLength": 4,
"maxLength": 50
},
"dns_sleep": {
"type": "integer"
},
"meta": {
"type": "object"
}
}
}

View File

@ -1,15 +0,0 @@
{
"type": "object",
"description": "DeletedItemResponse",
"additionalProperties": false,
"required": ["result"],
"properties": {
"result": {
"type": "boolean",
"nullable": true
},
"error": {
"$ref": "#/components/schemas/ErrorObject"
}
}
}

View File

@ -1,17 +0,0 @@
{
"type": "object",
"description": "ErrorObject",
"additionalProperties": false,
"required": ["code", "message"],
"properties": {
"code": {
"type": "integer",
"description": "Error code",
"minimum": 0
},
"message": {
"type": "string",
"description": "Error message"
}
}
}

View File

@ -1,24 +0,0 @@
{
"type": "object",
"description": "FilterObject",
"additionalProperties": false,
"required": ["field", "modifier", "value"],
"properties": {
"field": {
"type": "string",
"description": "Field to filter with"
},
"modifier": {
"type": "string",
"description": "Filter modifier",
"pattern": "^(equals|not|min|max|greater|lesser|contains|starts|ends|in|notin)$"
},
"value": {
"type": "array",
"description": "Values used for filtering",
"items": {
"type": "string"
}
}
}
}

View File

@ -1,31 +0,0 @@
{
"type": "object",
"description": "HealthObject",
"additionalProperties": false,
"required": ["version", "commit", "healthy", "setup"],
"properties": {
"version": {
"type": "string",
"description": "Version",
"minLength": 1
},
"commit": {
"type": "string",
"description": "Commit hash",
"minLength": 7
},
"healthy": {
"type": "boolean",
"description": "Healthy?"
},
"setup": {
"type": "boolean",
"description": "Is the application set up?"
},
"acme.sh": {
"type": "string",
"description": "Acme.sh version",
"minLength": 1
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "HostList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/HostObject"
}
}
}
}

View File

@ -1,55 +0,0 @@
{
"type": "object",
"description": "HostObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"user_id",
"provider",
"name",
"domain_names"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"user_id": {
"type": "integer",
"minimum": 1
},
"provider": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"domain_names": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 4
}
},
"user": {
"$ref": "#/components/schemas/UserObject"
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "NginxTemplateList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/NginxTemplateObject"
}
}
}
}

View File

@ -1,46 +0,0 @@
{
"type": "object",
"description": "NginxTemplateObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"user_id",
"name",
"type",
"template"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"user_id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1
},
"type": {
"type": "string",
"pattern": "^proxy|redirect|dead|stream|upstream$"
},
"template": {
"type": "string",
"minLength": 20
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "SettingList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/SettingObject"
}
}
}
}

View File

@ -1,51 +0,0 @@
{
"type": "object",
"description": "SettingObject",
"additionalProperties": false,
"required": ["id", "created_at", "updated_at", "name", "value"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"name": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"description": {
"type": "string",
"minLength": 0,
"maxLength": 100
},
"value": {
"oneOf": [
{
"type": "array"
},
{
"type": "boolean"
},
{
"type": "object"
},
{
"type": "integer"
},
{
"type": "string"
}
]
}
}
}

View File

@ -1,17 +0,0 @@
{
"type": "object",
"description": "SortObject",
"additionalProperties": false,
"required": ["field", "direction"],
"properties": {
"field": {
"type": "string",
"description": "Field for sorting on"
},
"direction": {
"type": "string",
"description": "Sort order",
"pattern": "^(ASC|DESC)$"
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "StreamList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/StreamObject"
}
}
}
}

View File

@ -1,57 +0,0 @@
{
"type": "object",
"description": "StreamObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"expires_on",
"user_id",
"provider",
"name",
"domain_names"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"expires_on": {
"type": "integer",
"minimum": 1
},
"user_id": {
"type": "integer",
"minimum": 1
},
"provider": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"domain_names": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 4
}
}
}
}

View File

@ -1,17 +0,0 @@
{
"type": "object",
"description": "TokenObject",
"additionalProperties": false,
"required": ["expires", "token"],
"properties": {
"expires": {
"type": "number",
"description": "Token Expiry Unix Time",
"minimum": 1
},
"token": {
"type": "string",
"description": "JWT Token"
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "UpstreamList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UpstreamObject"
}
}
}
}

View File

@ -1,140 +0,0 @@
{
"type": "object",
"description": "UpstreamObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"user_id",
"name",
"nginx_template_id",
"ip_hash",
"ntlm",
"keepalive",
"keepalive_requests",
"keepalive_time",
"keepalive_timeout",
"advanced_config",
"status",
"error_message",
"servers"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"user_id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"nginx_template_id": {
"type": "integer",
"minimum": 1
},
"ip_hash": {
"type": "boolean"
},
"ntlm": {
"type": "boolean"
},
"keepalive": {
"type": "integer"
},
"keepalive_requests": {
"type": "integer"
},
"keepalive_time": {
"type": "string"
},
"keepalive_timeout": {
"type": "string"
},
"advanced_config": {
"type": "string"
},
"status": {
"type": "string"
},
"error_message": {
"type": "string"
},
"user": {
"$ref": "#/components/schemas/UserObject"
},
"servers": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"upstream_id",
"server",
"weight",
"max_conns",
"max_fails",
"fail_timeout",
"backup"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"upstream_id": {
"type": "integer",
"minimum": 1
},
"server": {
"type": "string",
"minLength": 2
},
"weight": {
"type": "integer"
},
"max_conns": {
"type": "integer"
},
"max_fails": {
"type": "integer"
},
"fail_timeout": {
"type": "integer"
},
"backup": {
"type": "boolean"
}
}
}
}
}
}

View File

@ -1,30 +0,0 @@
{
"type": "object",
"description": "UserAuthObject",
"additionalProperties": false,
"required": ["id", "user_id", "type", "created_at", "updated_at"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"user_id": {
"type": "integer",
"minimum": 1
},
"type": {
"type": "string",
"pattern": "^(local|ldap|oauth)$"
}
}
}

View File

@ -1,40 +0,0 @@
{
"type": "object",
"description": "UserList",
"additionalProperties": false,
"required": ["total", "offset", "limit", "sort"],
"properties": {
"total": {
"type": "integer",
"description": "Total number of rows"
},
"offset": {
"type": "integer",
"description": "Pagination Offset"
},
"limit": {
"type": "integer",
"description": "Pagination Limit"
},
"sort": {
"type": "array",
"description": "Sorting",
"items": {
"$ref": "#/components/schemas/SortObject"
}
},
"filter": {
"type": "array",
"description": "Filters",
"items": {
"$ref": "#/components/schemas/FilterObject"
}
},
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/UserObject"
}
}
}
}

View File

@ -1,69 +0,0 @@
{
"type": "object",
"description": "UserObject",
"additionalProperties": false,
"required": [
"id",
"created_at",
"updated_at",
"name",
"email",
"is_disabled"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_at": {
"type": "integer",
"minimum": 1,
"description": "Created Unix time with milliseconds"
},
"updated_at": {
"type": "integer",
"minimum": 1,
"description": "Updated Unix time with milliseconds"
},
"name": {
"type": "string",
"minLength": 2,
"maxLength": 50
},
"email": {
"type": "string",
"minLength": 5,
"maxLength": 150
},
"gravatar_url": {
"type": "string"
},
"is_disabled": {
"type": "boolean"
},
"is_system": {
"type": "boolean"
},
"auth": {
"type": "object",
"required": ["type"],
"properties": {
"id": {
"type": "integer"
},
"type": {
"type": "string",
"pattern": "^(local|ldap|oauth)$"
}
}
},
"capabilities": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
}
}
}
}

View File

@ -1,28 +0,0 @@
{
"operationId": "getAuthConfig",
"summary": "Returns auth configuration",
"tags": ["Auth"],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/AuthConfigObject"
}
}
},
"examples": {
"default": {
"value": "todo"
}
}
}
}
}
}
}

View File

@ -1,75 +0,0 @@
{
"operationId": "requestToken",
"summary": "Request a new access token from credentials",
"tags": ["Auth"],
"requestBody": {
"description": "Credentials Payload",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.GetToken}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/TokenObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"expires": 1566540510,
"token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4",
"scope": "user"
}
}
}
}
}
}
},
"403": {
"description": "403 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["error"],
"properties": {
"result": {
"type": "object",
"nullable": true
},
"error": {
"$ref": "#/components/schemas/ErrorObject"
}
}
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 403,
"message": "Not available during setup phase"
}
}
}
}
}
}
}
}
}

View File

@ -1,34 +0,0 @@
{
"operationId": "refreshToken",
"summary": "Refresh your access token",
"tags": ["Auth"],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/TokenObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"expires": 1566540510,
"token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4",
"scope": "user"
}
}
}
}
}
}
}
}
}

View File

@ -1,34 +0,0 @@
{
"operationId": "requestSSEToken",
"summary": "Request a new SSE token",
"tags": ["Auth"],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/TokenObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"expires": 1566540510,
"token": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4",
"scope": "user"
}
}
}
}
}
}
}
}
}

View File

@ -1,39 +0,0 @@
{
"operationId": "deleteCertificateAuthority",
"summary": "Delete a Certificate Authority",
"tags": [
"Certificate Authorities"
],
"parameters": [
{
"in": "path",
"name": "caID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the Certificate Authority",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
}
}
}

View File

@ -1,53 +0,0 @@
{
"operationId": "getCertificateAuthority",
"summary": "Get a Certificate Authority object by ID",
"tags": ["Certificate Authorities"],
"parameters": [
{
"in": "path",
"name": "caID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Certificate Authority",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1627531400000,
"updated_at": 1627531400000,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_readonly": false
}
}
}
}
}
}
}
}
}

View File

@ -1,62 +0,0 @@
{
"operationId": "updateCertificateAuthority",
"summary": "Update an existing Certificate Authority",
"tags": ["Certificate Authorities"],
"parameters": [
{
"in": "path",
"name": "caID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Certificate Authority",
"example": 1
}
],
"requestBody": {
"description": "Certificate Authority details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateCertificateAuthority}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1627531400000,
"updated_at": 1627531400000,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_readonly": false
}
}
}
}
}
}
}
}
}

View File

@ -1,93 +0,0 @@
{
"operationId": "getCertificateAuthorities",
"summary": "Get a list of Certificate Authorities",
"tags": ["Certificate Authorities"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 2,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "name",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1627531400000,
"updated_at": 1627531400000,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_setup": true
},
{
"id": 2,
"created_at": 1627531400000,
"updated_at": 1627531400000,
"name": "Let's Encrypt",
"acmesh_server": "https://acme-v02.api.letsencrypt.org/directory",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_setup": true
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,49 +0,0 @@
{
"operationId": "createCertificateAuthority",
"summary": "Create a new Certificate Authority",
"tags": ["Certificate Authorities"],
"requestBody": {
"description": "Certificate Authority to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateCertificateAuthority}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1627531400000,
"updated_at": 1627531400000,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_readonly": false
}
}
}
}
}
}
}
}
}

View File

@ -1,60 +0,0 @@
{
"operationId": "deleteCertificate",
"summary": "Delete a Certificate",
"tags": [
"Certificates"
],
"parameters": [
{
"in": "path",
"name": "certificateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the certificate",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot delete a certificate that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -1,56 +0,0 @@
{
"operationId": "getCertificate",
"summary": "Get a certificate object by ID",
"tags": ["Certificates"],
"parameters": [
{
"in": "path",
"name": "certificateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the certificate",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1604536109000,
"updated_at": 1604536109000,
"expires_on": null,
"type": "dns",
"user_id": 1,
"certificate_authority_id": 2,
"dns_provider_id": 1,
"name": "test1.jc21.com.au",
"domain_names": ["test1.jc21.com.au"],
"is_ecc": 0,
"status": "ready"
}
}
}
}
}
}
}
}
}

View File

@ -1,65 +0,0 @@
{
"operationId": "updateCertificate",
"summary": "Update an existing Certificate",
"tags": ["Certificates"],
"parameters": [
{
"in": "path",
"name": "certificateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the certificate",
"example": 1
}
],
"requestBody": {
"description": "Certificate details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateCertificate}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1604536109000,
"updated_at": 1604536109000,
"expires_on": null,
"type": "dns",
"user_id": 1,
"certificate_authority_id": 2,
"dns_provider_id": 1,
"name": "test1.jc21.com.au",
"domain_names": ["test1.jc21.com.au"],
"is_ecc": 0,
"status": "ready"
}
}
}
}
}
}
}
}
}

View File

@ -1,87 +0,0 @@
{
"operationId": "getCertificates",
"summary": "Get a list of certificates",
"tags": ["Certificates"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "name",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1604536109000,
"updated_at": 1604536109000,
"expires_on": null,
"type": "dns",
"user_id": 1,
"certificate_authority_id": 2,
"dns_provider_id": 1,
"name": "test1.jc21.com.au",
"domain_names": [
"test1.jc21.com.au"
],
"is_ecc": 0,
"status": "ready"
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,52 +0,0 @@
{
"operationId": "createCertificate",
"summary": "Create a new Certificate",
"tags": ["Certificates"],
"requestBody": {
"description": "Certificate to create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateCertificate}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1604536109000,
"updated_at": 1604536109000,
"expires_on": null,
"type": "dns",
"user_id": 1,
"certificate_authority_id": 2,
"dns_provider_id": 1,
"name": "test1.jc21.com.au",
"domain_names": ["test1.jc21.com.au"],
"is_ecc": 0,
"status": "ready"
}
}
}
}
}
}
}
}
}

View File

@ -1,35 +0,0 @@
{
"operationId": "config",
"summary": "Returns the API Service configuration",
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/ConfigObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"data": "/data",
"log": {
"level": "debug",
"format": "nice"
}
}
}
}
}
}
}
}
}
}

View File

@ -1,83 +0,0 @@
{
"operationId": "getDNSProviders",
"summary": "Get a list of DNS Providers",
"tags": ["DNS Providers"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "name",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1602593653000,
"updated_at": 1602593653000,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,50 +0,0 @@
{
"operationId": "createDNSProvider",
"summary": "Create a new DNS Provider",
"tags": ["DNS Providers"],
"requestBody": {
"description": "DNS Provider to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateDNSProvider}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1602593653000,
"updated_at": 1602593653000,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
}
}
}
}
}
}
}
}

View File

@ -1,60 +0,0 @@
{
"operationId": "deleteDNSProvider",
"summary": "Delete a DNS Provider",
"tags": [
"DNS Providers"
],
"parameters": [
{
"in": "path",
"name": "providerID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the DNS Provider",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot delete a DNS Provider that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -1,54 +0,0 @@
{
"operationId": "getDNSProvider",
"summary": "Get a DNS Provider object by ID",
"tags": ["DNS Providers"],
"parameters": [
{
"in": "path",
"name": "providerID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the DNS Provider",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1602593653000,
"updated_at": 1602593653000,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
}
}
}
}
}
}
}
}

View File

@ -1,65 +0,0 @@
{
"operationId": "updateDNSProvider",
"summary": "Update an existing DNS Provider",
"tags": ["DNS Providers"],
"parameters": [
{
"in": "path",
"name": "providerID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the DNS Provider",
"example": 1
}
],
"requestBody": {
"description": "DNS Provider details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateDNSProvider}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"result": {
"id": 1,
"created_at": 1602593653000,
"updated_at": 1602593653000,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
}
}
}
}
}
}
}
}
}

View File

@ -1,44 +0,0 @@
{
"operationId": "health",
"summary": "Returns the API health status",
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HealthObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"version": "3.0.0",
"commit": "9f119b6",
"healthy": true,
"setup": true
}
}
},
"unhealthy": {
"value": {
"result": {
"version": "3.0.0",
"commit": "9f119b6",
"healthy": false,
"setup": true
}
}
}
}
}
}
}
}
}

View File

@ -1,94 +0,0 @@
{
"operationId": "getHosts",
"summary": "Get a list of Hosts",
"tags": ["Hosts"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "domain_names",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1646279455000,
"updated_at": 1646279455000,
"user_id": 2,
"type": "proxy",
"nginx_template_id": 1,
"listen_interface": "",
"domain_names": ["jc21.com"],
"upstream_id": 0,
"certificate_id": 0,
"access_list_id": 0,
"ssl_forced": false,
"caching_enabled": false,
"block_exploits": false,
"allow_websocket_upgrade": false,
"http2_support": false,
"hsts_enabled": false,
"hsts_subdomains": false,
"paths": "",
"advanced_config": "",
"is_disabled": false
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,60 +0,0 @@
{
"operationId": "deleteHost",
"summary": "Delete a Host",
"tags": [
"Hosts"
],
"parameters": [
{
"in": "path",
"name": "hostID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the Host",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot delete a host that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -1,65 +0,0 @@
{
"operationId": "getHost",
"summary": "Get a Host object by ID",
"tags": ["Hosts"],
"parameters": [
{
"in": "path",
"name": "hostID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Host",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1646279455000,
"updated_at": 1646279455000,
"user_id": 2,
"type": "proxy",
"nginx_template_id": 1,
"listen_interface": "",
"domain_names": ["jc21.com"],
"upstream_id": 0,
"certificate_id": 0,
"access_list_id": 0,
"ssl_forced": false,
"caching_enabled": false,
"block_exploits": false,
"allow_websocket_upgrade": false,
"http2_support": false,
"hsts_enabled": false,
"hsts_subdomains": false,
"paths": "",
"advanced_config": "",
"is_disabled": false
}
}
}
}
}
}
}
}
}

View File

@ -1,43 +0,0 @@
{
"operationId": "getHostNginxConfig",
"summary": "Get a Host Nginx Config object by ID",
"tags": ["Hosts"],
"parameters": [
{
"in": "path",
"name": "hostID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Host",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"type": "string"
}
}
},
"examples": {
"default": {
"value": {
"result": "# ------------------------------------------------------------\n# a.example.com\n# ------------------------------------------------------------\nserver {\n listen 80;\n server_name a.example.com ;\n access_log /data/logs/host-1_access.log proxy;\n error_log /data/logs/host-1_error.log warn;\n # locations ?\n # default location:\n location / {\n # Access Rules ? todo\n # Access checks must...? todo\n # Proxy!\n add_header X-Served-By $host;\n proxy_set_header Host $host;\n proxy_set_header X-Forwarded-Scheme $scheme;\n proxy_set_header X-Forwarded-Proto $scheme;\n proxy_set_header X-Forwarded-For $remote_addr;\n proxy_http_version 1.1;\n # proxy a single host\n proxy_pass http://192.168.0.10:80;\n }\n # Legacy Custom Configuration\n include /data/nginx/custom/server_proxy[.]conf;\n}\n"
}
}
}
}
}
}
}
}

View File

@ -1,74 +0,0 @@
{
"operationId": "updateHost",
"summary": "Update an existing Host",
"tags": ["Hosts"],
"parameters": [
{
"in": "path",
"name": "hostID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Host",
"example": 1
}
],
"requestBody": {
"description": "Host details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateHost}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1646279455000,
"updated_at": 1646279455000,
"user_id": 2,
"type": "proxy",
"nginx_template_id": 1,
"listen_interface": "",
"domain_names": ["jc21.com"],
"upstream_id": 0,
"certificate_id": 0,
"access_list_id": 0,
"ssl_forced": false,
"caching_enabled": false,
"block_exploits": false,
"allow_websocket_upgrade": false,
"http2_support": false,
"hsts_enabled": false,
"hsts_subdomains": false,
"paths": "",
"advanced_config": "",
"is_disabled": false
}
}
}
}
}
}
}
}
}

View File

@ -1,61 +0,0 @@
{
"operationId": "createHost",
"summary": "Create a new Host",
"tags": ["Hosts"],
"requestBody": {
"description": "Host to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateHost}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1645700556000,
"updated_at": 1645700556000,
"user_id": 2,
"type": "proxy",
"nginx_template_id": 1,
"listen_interface": "",
"domain_names": ["jc21.com"],
"upstream_id": 0,
"certificate_id": 0,
"access_list_id": 0,
"ssl_forced": false,
"caching_enabled": false,
"block_exploits": false,
"allow_websocket_upgrade": false,
"http2_support": false,
"hsts_enabled": false,
"hsts_subdomains": false,
"paths": "",
"advanced_config": "",
"is_disabled": false
}
}
}
}
}
}
}
}
}

View File

@ -1,80 +0,0 @@
{
"operationId": "getNginxTemplates",
"summary": "Get a list of Nginx Templates",
"tags": ["Nginx Templates"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/NginxTemplateList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "created_at",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1646218093000,
"updated_at": 1646218093000,
"user_id": 1,
"name": "Default Proxy Template",
"type": "proxy",
"template": "# this is a proxy template"
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,47 +0,0 @@
{
"operationId": "createNginxTemplate",
"summary": "Create a new Nginx Template",
"tags": ["Nginx Templates"],
"requestBody": {
"description": "Template to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateNginxTemplate}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/NginxTemplateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 10,
"created_at": 1646218093000,
"updated_at": 1646218093000,
"user_id": 1,
"name": "My proxy template",
"type": "proxy",
"template": "# this is a proxy template"
}
}
}
}
}
}
}
}
}

View File

@ -1,58 +0,0 @@
{
"operationId": "deleteNginxTemplate",
"summary": "Delete a Nginx Template",
"tags": ["Nginx Templates"],
"parameters": [
{
"in": "path",
"name": "templateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the Template",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot delete a template that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -1,51 +0,0 @@
{
"operationId": "getNginxTemplate",
"summary": "Get a Nginx Template object by ID",
"tags": ["Nginx Templates"],
"parameters": [
{
"in": "path",
"name": "templateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Host Template",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/NginxTemplateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1646218093000,
"updated_at": 1646218093000,
"user_id": 1,
"name": "Default Proxy Template",
"type": "proxy",
"template": "# this is a proxy template"
}
}
}
}
}
}
}
}
}

View File

@ -1,60 +0,0 @@
{
"operationId": "updateNginxTemplate",
"summary": "Update an existing Nginx Template",
"tags": ["Nginx Templates"],
"parameters": [
{
"in": "path",
"name": "templateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Template",
"example": 1
}
],
"requestBody": {
"description": "Template details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateNginxTemplate}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/NginxTemplateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1646218093000,
"updated_at": 1646218093000,
"user_id": 1,
"name": "My renamed proxy template",
"type": "proxy",
"template": "# this is a proxy template"
}
}
}
}
}
}
}
}
}

View File

@ -1,9 +0,0 @@
{
"operationId": "schema",
"summary": "Returns this swagger API schema",
"responses": {
"200": {
"description": "200 response"
}
}
}

View File

@ -1,81 +0,0 @@
{
"operationId": "getSettings",
"summary": "Get a list of settings",
"tags": ["Settings"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "name",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1578010090000,
"updated_at": 1578010095000,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,52 +0,0 @@
{
"operationId": "getSetting",
"summary": "Get a setting object by name",
"tags": ["Settings"],
"parameters": [
{
"in": "path",
"name": "name",
"schema": {
"type": "string",
"minLength": 2
},
"required": true,
"description": "Name of the setting",
"example": "default-site"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"created_at": 1578010090000,
"updated_at": 1578010095000,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
}
}
}
}
}
}
}
}

View File

@ -1,61 +0,0 @@
{
"operationId": "updateSetting",
"summary": "Update an existing Setting",
"tags": ["Settings"],
"parameters": [
{
"in": "path",
"name": "name",
"schema": {
"type": "string",
"minLength": 2
},
"required": true,
"description": "Name of the setting",
"example": "default-site"
}
],
"requestBody": {
"description": "Setting details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateSetting}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"created_at": 1578010090000,
"updated_at": 1578010090000,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
}
}
}
}
}
}
}
}

View File

@ -1,48 +0,0 @@
{
"operationId": "createSetting",
"summary": "Create a new Setting",
"tags": ["Settings"],
"requestBody": {
"description": "Setting to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateSetting}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"created_at": 1578010090000,
"updated_at": 1578010090000,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
}
}
}
}
}
}
}
}

View File

@ -1,70 +0,0 @@
{
"operationId": "getStreams",
"summary": "Get a list of Streams",
"tags": ["Streams"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "name",
"direction": "ASC"
}
],
"items": ["TODO"]
}
}
}
}
}
}
}
}
}

View File

@ -1,39 +0,0 @@
{
"operationId": "createStream",
"summary": "Create a new Stream",
"tags": ["Streams"],
"requestBody": {
"description": "Stream to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateStream}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": "TODO"
}
}
}
}
}
}
}
}

View File

@ -1,60 +0,0 @@
{
"operationId": "deleteStream",
"summary": "Delete a Stream",
"tags": [
"Streams"
],
"parameters": [
{
"in": "path",
"name": "streamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the Stream",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot delete a Stream that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -1,43 +0,0 @@
{
"operationId": "getStream",
"summary": "Get a Stream object by ID",
"tags": ["Streams"],
"parameters": [
{
"in": "path",
"name": "streamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Stream",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": "TODO"
}
}
}
}
}
}
}
}

View File

@ -1,52 +0,0 @@
{
"operationId": "updateStream",
"summary": "Update an existing Stream",
"tags": ["Streams"],
"parameters": [
{
"in": "path",
"name": "streamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Stream",
"example": 1
}
],
"requestBody": {
"description": "Stream details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateStream}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": "TODO"
}
}
}
}
}
}
}
}

View File

@ -1,286 +0,0 @@
{
"operationId": "getUpstreams",
"summary": "Get a list of Upstreams",
"tags": ["Upstreams"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "id,name.asc,value.desc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UpstreamList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 5,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "name",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_at": 1672804124000,
"updated_at": 1672804124000,
"user_id": 2,
"name": "API servers",
"nginx_template_id": 5,
"ip_hash": true,
"ntlm": false,
"keepalive": 10,
"keepalive_requests": 10,
"keepalive_time": "60s",
"keepalive_timeout": "3s",
"advanced_config": "",
"status": "ok",
"error_message": "",
"servers": [
{
"id": 1,
"created_at": 1672804124000,
"updated_at": 1672804124000,
"upstream_group_id": 1,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 2,
"created_at": 1672804124000,
"updated_at": 1672804124000,
"upstream_group_id": 1,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
},
{
"id": 2,
"created_at": 1672804197000,
"updated_at": 1672804197000,
"user_id": 2,
"name": "API servers 2",
"nginx_template_id": 5,
"ip_hash": false,
"ntlm": false,
"keepalive": 0,
"keepalive_requests": 0,
"keepalive_time": "",
"keepalive_timeout": "",
"advanced_config": "",
"status": "ok",
"error_message": "",
"servers": [
{
"id": 3,
"created_at": 1672804197000,
"updated_at": 1672804197000,
"upstream_group_id": 2,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 4,
"created_at": 1672804197000,
"updated_at": 1672804197000,
"upstream_group_id": 2,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
},
{
"id": 3,
"created_at": 1672804200000,
"updated_at": 1672804200000,
"user_id": 2,
"name": "API servers 2",
"nginx_template_id": 5,
"ip_hash": false,
"ntlm": false,
"keepalive": 0,
"keepalive_requests": 0,
"keepalive_time": "",
"keepalive_timeout": "",
"advanced_config": "",
"status": "ok",
"error_message": "",
"servers": [
{
"id": 5,
"created_at": 1672804200000,
"updated_at": 1672804200000,
"upstream_group_id": 3,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 6,
"created_at": 1672804200000,
"updated_at": 1672804200000,
"upstream_group_id": 3,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
},
{
"id": 4,
"created_at": 1672804201000,
"updated_at": 1672804201000,
"user_id": 2,
"name": "API servers 2",
"nginx_template_id": 5,
"ip_hash": false,
"ntlm": false,
"keepalive": 0,
"keepalive_requests": 0,
"keepalive_time": "",
"keepalive_timeout": "",
"advanced_config": "",
"status": "ok",
"error_message": "",
"servers": [
{
"id": 7,
"created_at": 1672804201000,
"updated_at": 1672804201000,
"upstream_group_id": 4,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 8,
"created_at": 1672804201000,
"updated_at": 1672804201000,
"upstream_group_id": 4,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
},
{
"id": 5,
"created_at": 1672804201000,
"updated_at": 1672804201000,
"user_id": 2,
"name": "API servers 2",
"nginx_template_id": 5,
"ip_hash": false,
"ntlm": false,
"keepalive": 0,
"keepalive_requests": 0,
"keepalive_time": "",
"keepalive_timeout": "",
"advanced_config": "",
"status": "ok",
"error_message": "",
"servers": [
{
"id": 9,
"created_at": 1672804201000,
"updated_at": 1672804201000,
"upstream_group_id": 5,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 10,
"created_at": 1672804201000,
"updated_at": 1672804201000,
"upstream_group_id": 5,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,81 +0,0 @@
{
"operationId": "createUpstream",
"summary": "Create a new Upstream",
"tags": ["Upstreams"],
"requestBody": {
"description": "Upstream to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateUpstream}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UpstreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 6,
"created_at": 1672806857000,
"updated_at": 1672806857000,
"user_id": 2,
"name": "API servers 2",
"nginx_template_id": 5,
"ip_hash": false,
"ntlm": false,
"keepalive": 0,
"keepalive_requests": 0,
"keepalive_time": "",
"keepalive_timeout": "",
"advanced_config": "",
"status": "ready",
"error_message": "",
"servers": [
{
"id": 11,
"created_at": 1672806857000,
"updated_at": 1672806857000,
"upstream_id": 6,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 12,
"created_at": 1672806857000,
"updated_at": 1672806857000,
"upstream_id": 6,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,58 +0,0 @@
{
"operationId": "deleteUpstream",
"summary": "Delete a Upstream",
"tags": ["Upstreams"],
"parameters": [
{
"in": "path",
"name": "upstreamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the Upstream",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": true
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/DeletedItemResponse"
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot delete a Upstream that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -1,82 +0,0 @@
{
"operationId": "getUpstream",
"summary": "Get a Upstream object by ID",
"tags": ["Upstreams"],
"parameters": [
{
"in": "path",
"name": "upstreamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Upstream",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UpstreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1672786008000,
"updated_at": 1672786008000,
"user_id": 2,
"name": "API servers 3",
"ip_hash": true,
"ntlm": false,
"keepalive": 10,
"keepalive_requests": 10,
"keepalive_time": "60s",
"keepalive_timeout": "3s",
"advanced_config": "",
"servers": [
{
"id": 1,
"created_at": 1672786009000,
"updated_at": 1672786009000,
"upstream_id": 1,
"server": "api1.localhost:1234",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 2,
"created_at": 1672786009000,
"updated_at": 1672786009000,
"upstream_id": 1,
"server": "api2.localhost:1234",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": true
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,43 +0,0 @@
{
"operationId": "getUpstreamNginxConfig",
"summary": "Get a Upstream Nginx Config object by ID",
"tags": ["Upstreams"],
"parameters": [
{
"in": "path",
"name": "upstreamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Upstream",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"type": "string"
}
}
},
"examples": {
"default": {
"value": {
"result": "# ------------------------------------------------------------\n# Upstream 1: API servers\n# ------------------------------------------------------------\nupstream npm_upstream_1 {\nserver 192.168.0.10:80 weight=100 ;\n server 192.168.0.11:80 weight=50 ;\n}\n"
}
}
}
}
}
}
}
}

View File

@ -1,94 +0,0 @@
{
"operationId": "updateUpstream",
"summary": "Update an existing Upstream",
"tags": ["Upstreams"],
"parameters": [
{
"in": "path",
"name": "upstreamID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Upstream",
"example": 1
}
],
"requestBody": {
"description": "Upstream details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateUpstream}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UpstreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_at": 1673234177000,
"updated_at": 1673244559000,
"user_id": 2,
"name": "API servers 2",
"nginx_template_id": 5,
"ip_hash": false,
"ntlm": false,
"keepalive": 0,
"keepalive_requests": 0,
"keepalive_time": "",
"keepalive_timeout": "",
"advanced_config": "",
"status": "ready",
"error_message": "",
"servers": [
{
"id": 1,
"created_at": 1673234177000,
"updated_at": 1673244559000,
"upstream_id": 1,
"server": "192.168.0.10:80",
"weight": 100,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
},
{
"id": 2,
"created_at": 1673234177000,
"updated_at": 1673244559000,
"upstream_id": 1,
"server": "192.168.0.11:80",
"weight": 50,
"max_conns": 0,
"max_fails": 0,
"fail_timeout": 0,
"backup": false
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,111 +0,0 @@
{
"operationId": "getUsers",
"summary": "Get a list of users",
"tags": ["Users"],
"parameters": [
{
"in": "query",
"name": "offset",
"schema": {
"type": "number"
},
"description": "The pagination row offset, default 0",
"example": 0
},
{
"in": "query",
"name": "limit",
"schema": {
"type": "number"
},
"description": "The pagination row limit, default 10",
"example": 10
},
{
"in": "query",
"name": "sort",
"schema": {
"type": "string"
},
"description": "The sorting of the list",
"example": "name,email.asc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 3,
"offset": 0,
"limit": 100,
"sort": [
{
"field": "name",
"direction": "ASC"
},
{
"field": "email",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"name": "Jamie Curnow",
"email": "jc@jc21.com",
"created_at": 1578010090000,
"updated_at": 1578010095000,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"capabilities": ["full-admin"]
},
{
"id": 2,
"name": "John Doe",
"email": "johdoe@example.com",
"created_at": 1578010100000,
"updated_at": 1578010105000,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"capabilities": [
"hosts.view",
"hosts.manage"
]
},
{
"id": 3,
"name": "Jane Doe",
"email": "janedoe@example.com",
"created_at": 1578010110000,
"updated_at": 1578010115000,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"capabilities": [
"hosts.view",
"hosts.manage"
]
}
]
}
}
}
}
}
}
}
}
}

View File

@ -1,81 +0,0 @@
{
"operationId": "createUser",
"summary": "Create a new User",
"tags": ["Users"],
"requestBody": {
"description": "User to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateUser}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"name": "Jamie Curnow",
"email": "jc@jc21.com",
"created_at": 1578010100000,
"updated_at": 1578010100000,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"auth": {
"$ref": "#/components/schemas/UserAuthObject"
},
"capabilities": ["full-admin"]
}
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["error"],
"properties": {
"result": {
"type": "object",
"nullable": true
},
"error": {
"$ref": "#/components/schemas/ErrorObject"
}
}
},
"examples": {
"default": {
"value": {
"error": {
"code": 400,
"message": "An user already exists with this email address"
}
}
}
}
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More