Moved v3 code from NginxProxyManager/nginx-proxy-manager-3 to NginxProxyManager/nginx-proxy-manager

This commit is contained in:
Jamie Curnow
2022-05-12 08:47:31 +10:00
parent 4db34f5894
commit 2110ecc382
830 changed files with 38168 additions and 36635 deletions

8
backend/.editorconfig Normal file
View File

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

View File

@ -1,73 +0,0 @@
{
"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
View File

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

92
backend/.golangci.yml Normal file
View File

@ -0,0 +1,92 @@
linters:
enable:
# Prevents against memory leaks in production caused by not closing file handle
- bodyclose
# Detects unused declarations in a go package
- deadcode
# 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
# 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
# Detcts 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.
- golint
# Detects ineffectual assignments in code
- ineffassign
# 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
# Detects unused global variables and constants
- varcheck
# Remove unnecessary type conversions
- unconvert
# Remove unnecessary(unused) function parameters
- unparam
linters-settings:
goconst:
# minimal length of string constant
# default: 3
min-len: 2
# minimum number of occurrences of string constant
# default: 3
min-occurences: 2
misspell:
locale: UK
ignore-words:
- color
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

22
backend/.nancy-ignore Normal file
View File

@ -0,0 +1,22 @@
# If you need to ignore any of nancy's warnings add them
# here with a reference to the package/version that
# triggers them and rational for ignoring it.
# pkg:golang/github.com/coreos/etcd@3.3.10
# etcd before versions 3.3.23 and 3.4.10 does not perform any password length validation
CVE-2020-15115
# pkg:golang/github.com/coreos/etcd@3.3.10
# In ectd before versions 3.4.10 and 3.3.23, gateway TLS authentication is only applied to endpoints detected in DNS SRV records
CVE-2020-15136
# pkg:golang/github.com/coreos/etcd@3.3.10
# In etcd before versions 3.3.23 and 3.4.10, the etcd gateway is a simple TCP proxy to allow for basic service discovery and access
CVE-2020-15114
# pkg:golang/github.com/gorilla/websocket@1.4.0
# Integer Overflow or Wraparound
CWE-190
# jwt-go before 4.0.0-preview1 allows attackers to bypass intended access restrict...
CVE-2020-26160

View File

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

View File

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

6
backend/README.md Normal file
View File

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

69
backend/Taskfile.yml Normal file
View File

@ -0,0 +1,69 @@
version: "2"
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
- 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 -ldflags="-X main.commit={{.GIT_COMMIT}} -X main.version={{.VERSION}}" -o ../dist/bin/server ./cmd/server/main.go
silent: true
- task: lint
vars:
GIT_COMMIT:
sh: git log -n 1 --format=%h
VERSION:
sh: cat ../.version
env:
GO111MODULE: on
CGO_ENABLED: 1
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

View File

@ -1,89 +0,0 @@
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

@ -0,0 +1,47 @@
package main
import (
"os"
"os/signal"
"syscall"
"npm/internal/api"
"npm/internal/config"
"npm/internal/database"
"npm/internal/entity/setting"
"npm/internal/logger"
"npm/internal/state"
"npm/internal/worker"
)
var commit string
var version string
var sentryDSN string
func main() {
config.InitArgs(&version, &commit)
config.Init(&version, &commit, &sentryDSN)
appstate := state.NewState()
database.Migrate(func() {
setting.ApplySettings()
database.CheckSetup()
go worker.StartCertificateWorker(appstate)
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
err := database.GetInstance().Close()
if err != nil {
logger.Error("DatabaseCloseError", err)
}
break
}
}
})
}

View File

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

View File

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

View File

@ -1,26 +0,0 @@
{
"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"
}
}
}
}

View File

@ -1,33 +0,0 @@
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);

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,243 @@
{
"openapi": "3.0.0",
"info": {
"title": "Nginx Proxy Manager API",
"version": "{{VERSION}}"
},
"paths": {
"/": {
"get": {
"$ref": "file://./paths/get.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"
}
},
"/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"
}
},
"/tokens": {
"get": {
"$ref": "file://./paths/tokens/get.json"
},
"post": {
"$ref": "file://./paths/tokens/post.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": {
"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"
},
"HostTemplateList": {
"$ref": "file://./components/HostTemplateList.json"
},
"HostTemplateObject": {
"$ref": "file://./components/HostTemplateObject.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"
},
"UserAuthObject": {
"$ref": "file://./components/UserAuthObject.json"
},
"UserList": {
"$ref": "file://./components/UserList.json"
},
"UserObject": {
"$ref": "file://./components/UserObject.json"
}
}
}
}

View File

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,55 @@
{
"type": "object",
"description": "CertificateAuthorityObject",
"additionalProperties": false,
"required": [
"id",
"created_on",
"modified_on",
"name",
"acmesh_server",
"ca_bundle",
"max_domains",
"is_wildcard_supported",
"is_readonly"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"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

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,82 @@
{
"type": "object",
"description": "CertificateObject",
"additionalProperties": false,
"required": [
"id",
"created_on",
"modified_on",
"expires_on",
"type",
"user_id",
"certificate_authority_id",
"dns_provider_id",
"name",
"is_ecc",
"status",
"domain_names"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"expires_on": {
"type": "integer",
"minimum": 1,
"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
},
"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": "integer",
"minimum": 0,
"maximum": 1
},
"error_message": {
"type": "string"
}
}
}

View File

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

View File

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,49 @@
{
"type": "object",
"description": "DNSProviderObject",
"additionalProperties": false,
"required": [
"id",
"created_on",
"modified_on",
"user_id",
"name",
"acmesh_name",
"dns_sleep",
"meta"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"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

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

View File

@ -0,0 +1,17 @@
{
"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

@ -0,0 +1,24 @@
{
"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

@ -0,0 +1,41 @@
{
"type": "object",
"description": "HealthObject",
"additionalProperties": false,
"required": ["version", "commit", "healthy", "setup", "error_reporting"],
"properties": {
"version": {
"type": "string",
"description": "Version",
"example": "3.0.0",
"minLength": 1
},
"commit": {
"type": "string",
"description": "Commit hash",
"example": "946b88f",
"minLength": 7
},
"healthy": {
"type": "boolean",
"description": "Healthy?",
"example": true
},
"setup": {
"type": "boolean",
"description": "Is the application set up?",
"example": true
},
"error_reporting": {
"type": "boolean",
"description": "Will the application send any error reporting?",
"example": true
},
"acme.sh": {
"type": "string",
"description": "Acme.sh version",
"example": "v3.0.0",
"minLength": 1
}
}
}

View File

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,55 @@
{
"type": "object",
"description": "HostObject",
"additionalProperties": false,
"required": [
"id",
"created_on",
"modified_on",
"expires_on",
"user_id",
"provider",
"name",
"domain_names"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"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

@ -0,0 +1,40 @@
{
"type": "object",
"description": "HostTemplateList",
"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/HostTemplateObject"
}
}
}
}

View File

@ -0,0 +1,44 @@
{
"type": "object",
"description": "HostTemplateObject",
"additionalProperties": false,
"required": [
"id",
"created_on",
"modified_on",
"user_id",
"name",
"host_type",
"template"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"user_id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 1
},
"host_type": {
"type": "string",
"pattern": "^proxy|redirect|dead|stream$"
},
"template": {
"type": "string",
"minLength": 20
}
}
}

View File

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,49 @@
{
"type": "object",
"description": "SettingObject",
"additionalProperties": false,
"required": ["id", "name", "value"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"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

@ -0,0 +1,17 @@
{
"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

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,55 @@
{
"type": "object",
"description": "StreamObject",
"additionalProperties": false,
"required": [
"id",
"created_on",
"modified_on",
"expires_on",
"user_id",
"provider",
"name",
"domain_names"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"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

@ -0,0 +1,19 @@
{
"type": "object",
"description": "TokenObject",
"additionalProperties": false,
"required": ["expires", "token"],
"properties": {
"expires": {
"type": "number",
"description": "Token Expiry Unix Time",
"example": 1566540249,
"minimum": 1
},
"token": {
"type": "string",
"description": "JWT Token",
"example": "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.ey...xaHKYr3Kk6MvkUjcC4"
}
}
}

View File

@ -0,0 +1,28 @@
{
"type": "object",
"description": "UserAuthObject",
"additionalProperties": false,
"required": ["id", "user_id", "type", "created_on", "modified_on"],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"user_id": {
"type": "integer",
"minimum": 1
},
"type": {
"type": "string",
"pattern": "^password$"
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
}
}
}

View File

@ -0,0 +1,40 @@
{
"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

@ -0,0 +1,73 @@
{
"type": "object",
"description": "UserObject",
"additionalProperties": false,
"required": [
"id",
"name",
"nickname",
"email",
"created_on",
"modified_on",
"is_disabled"
],
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"name": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"nickname": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"email": {
"type": "string",
"minLength": 5,
"maxLength": 150
},
"created_on": {
"type": "integer",
"minimum": 1
},
"modified_on": {
"type": "integer",
"minimum": 1
},
"gravatar_url": {
"type": "string"
},
"is_disabled": {
"type": "boolean"
},
"is_deleted": {
"type": "boolean"
},
"auth": {
"type": "object",
"required": ["type"],
"properties": {
"id": {
"type": "integer"
},
"type": {
"type": "string",
"pattern": "^password$"
}
}
},
"capabilities": {
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"minLength": 1
}
}
}
}

View File

@ -0,0 +1,9 @@
package doc
import "embed"
// SwaggerFiles contain all the files used for swagger schema generation
//go:embed api.swagger.json
//go:embed components
//go:embed paths
var SwaggerFiles embed.FS

View File

@ -0,0 +1,39 @@
{
"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

@ -0,0 +1,52 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1627531400,
"modified_on": 1627531400,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_readonly": false
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,61 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1627531400,
"modified_on": 1627531400,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_readonly": false
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,92 @@
{
"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": {
"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_on": 1627531400,
"modified_on": 1627531400,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_setup": true
},
{
"id": 2,
"created_on": 1627531400,
"modified_on": 1627531400,
"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

@ -0,0 +1,48 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateAuthorityObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1627531400,
"modified_on": 1627531400,
"name": "ZeroSSL",
"acmesh_server": "zerossl",
"ca_bundle": "",
"max_domains": 10,
"is_wildcard_supported": true,
"is_readonly": false
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,60 @@
{
"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

@ -0,0 +1,61 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1604536109,
"modified_on": 1604536109,
"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

@ -0,0 +1,70 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1604536109,
"modified_on": 1604536109,
"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

@ -0,0 +1,90 @@
{
"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": {
"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_on": 1604536109,
"modified_on": 1604536109,
"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

@ -0,0 +1,57 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/CertificateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1604536109,
"modified_on": 1604536109,
"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

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

View File

@ -0,0 +1,82 @@
{
"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": {
"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_on": 1602593653,
"modified_on": 1602593653,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
]
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,49 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1602593653,
"modified_on": 1602593653,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,60 @@
{
"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

@ -0,0 +1,53 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1602593653,
"modified_on": 1602593653,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,64 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/DNSProviderObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"result": {
"id": 1,
"created_on": 1602593653,
"modified_on": 1602593653,
"user_id": 1,
"name": "Route53",
"acmesh_name": "dns_aws",
"meta": {
"AWS_ACCESS_KEY_ID": "abc123",
"AWS_SECRET_ACCESS_KEY": "def098"
}
}
}
}
}
}
}
}
}
}
}

View File

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

View File

@ -0,0 +1,79 @@
{
"operationId": "getHostTemplates",
"summary": "Get a list of Host Templates",
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostTemplateList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 1,
"offset": 0,
"limit": 10,
"sort": [
{
"field": "created_on",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"created_on": 1646218093,
"modified_on": 1646218093,
"user_id": 1,
"name": "Default Proxy Template",
"host_type": "proxy",
"template": "# this is a proxy template"
}
]
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,58 @@
{
"operationId": "deleteHostTemplate",
"summary": "Delete a Host Template",
"tags": ["Host Templates"],
"parameters": [
{
"in": "path",
"name": "hostTemplateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the Host 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 host template that is in use!"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,50 @@
{
"operationId": "getHostTemplate",
"summary": "Get a Host Template object by ID",
"tags": ["Hosts"],
"parameters": [
{
"in": "path",
"name": "hostTemplateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Host Template",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostTemplateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1646218093,
"modified_on": 1646218093,
"user_id": 1,
"name": "Default Host Template",
"host_type": "proxy",
"template": "# this is a proxy template"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,59 @@
{
"operationId": "updateHostTemplate",
"summary": "Update an existing Host Template",
"tags": ["Hosts"],
"parameters": [
{
"in": "path",
"name": "hostTemplateID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "ID of the Host Template",
"example": 1
}
],
"requestBody": {
"description": "Host Template details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateHostTemplate}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostTemplateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1646218093,
"modified_on": 1646218093,
"user_id": 1,
"name": "My renamed proxy template",
"host_type": "proxy",
"template": "# this is a proxy template"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,46 @@
{
"operationId": "createHost",
"summary": "Create a new Host",
"tags": ["Hosts"],
"requestBody": {
"description": "Host to Create",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.CreateHostTemplate}}"
}
}
},
"responses": {
"201": {
"description": "201 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostTemplateObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 10,
"created_on": 1646218093,
"modified_on": 1646218093,
"user_id": 1,
"name": "My proxy template",
"host_type": "proxy",
"template": "# this is a proxy template"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,94 @@
{
"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": {
"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_on": 1646279455,
"modified_on": 1646279455,
"user_id": 2,
"type": "proxy",
"host_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": "",
"upstream_options": "",
"advanced_config": "",
"is_disabled": false
}
]
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,60 @@
{
"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

@ -0,0 +1,65 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1646279455,
"modified_on": 1646279455,
"user_id": 2,
"type": "proxy",
"host_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": "",
"upstream_options": "",
"advanced_config": "",
"is_disabled": false
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,74 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1646279455,
"modified_on": 1646279455,
"user_id": 2,
"type": "proxy",
"host_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": "",
"upstream_options": "",
"advanced_config": "",
"is_disabled": false
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,61 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/HostObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"created_on": 1645700556,
"modified_on": 1645700556,
"user_id": 2,
"type": "proxy",
"host_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": "",
"upstream_options": "",
"advanced_config": "",
"is_disabled": false
}
}
}
}
}
}
}
}
}

View File

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

View File

@ -0,0 +1,84 @@
{
"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": {
"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_on": 1578010090,
"modified_on": 1578010095,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
]
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,55 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"created_on": 1578010090,
"modified_on": 1578010095,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,64 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"created_on": 1578010090,
"modified_on": 1578010090,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,51 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/SettingObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"created_on": 1578010090,
"modified_on": 1578010090,
"name": "default-site",
"value": {
"html": "<p>not found</p>",
"type": "custom"
}
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,75 @@
{
"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": {
"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

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

View File

@ -0,0 +1,60 @@
{
"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

@ -0,0 +1,46 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": "TODO"
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,55 @@
{
"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": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamObject"
}
}
},
"examples": {
"default": {
"value": {
"result": "TODO"
}
}
}
}
}
}
}
}

View File

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

View File

@ -0,0 +1,79 @@
{
"operationId": "requestToken",
"summary": "Request a new access token from credentials",
"tags": [
"Tokens"
],
"requestBody": {
"description": "Credentials Payload",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.GetToken}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": [
"result"
],
"properties": {
"result": {
"$ref": "#/components/schemas/StreamObject"
}
}
},
"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": {
"nullable": true
},
"error": {
"$ref": "#/components/schemas/ErrorObject"
}
}
},
"examples": {
"default": {
"value": {
"result": null,
"error": {
"code": 403,
"message": "Not available during setup phase"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,117 @@
{
"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,nickname.desc,email.asc"
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserList"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"total": 3,
"offset": 0,
"limit": 100,
"sort": [
{
"field": "name",
"direction": "ASC"
},
{
"field": "nickname",
"direction": "DESC"
},
{
"field": "email",
"direction": "ASC"
}
],
"items": [
{
"id": 1,
"name": "Jamie Curnow",
"nickname": "James",
"email": "jc@jc21.com",
"created_on": 1578010090,
"modified_on": 1578010095,
"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",
"nickname": "John",
"email": "johdoe@example.com",
"created_on": 1578010100,
"modified_on": 1578010105,
"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",
"nickname": "Jane",
"email": "janedoe@example.com",
"created_on": 1578010110,
"modified_on": 1578010115,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"capabilities": [
"hosts.view",
"hosts.manage"
]
}
]
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,79 @@
{
"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": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"name": "Jamie Curnow",
"nickname": "James",
"email": "jc@jc21.com",
"created_on": 1578010100,
"modified_on": 1578010100,
"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": {
"required": ["error"],
"properties": {
"result": {
"nullable": true
},
"error": {
"$ref": "#/components/schemas/ErrorObject"
}
}
},
"examples": {
"default": {
"value": {
"error": {
"code": 400,
"message": "An user already exists with this email address"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,65 @@
{
"operationId": "setPassword",
"summary": "Set a User's password",
"tags": ["Users"],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"oneOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "string",
"pattern": "^me$"
}
]
},
"required": true,
"description": "Numeric ID of the user or 'me' to set yourself",
"example": 1
}
],
"requestBody": {
"description": "Credentials to set",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.SetAuth}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserAuthObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 2,
"user_id": 3,
"type": "password",
"created_on": 1648422222,
"modified_on": 1648423979
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,60 @@
{
"operationId": "deleteUser",
"summary": "Delete a User",
"tags": [
"Users"
],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"type": "integer",
"minimum": 1
},
"required": true,
"description": "Numeric ID of the user",
"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 yourself!"
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,60 @@
{
"operationId": "getUser",
"summary": "Get a user object by ID or 'me'",
"tags": ["Users"],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"anyOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "string",
"pattern": "^me$"
}
]
},
"required": true,
"description": "Numeric ID of the user or 'me' to get yourself",
"example": 1
}
],
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"name": "Jamie Curnow",
"nickname": "James",
"email": "jc@jc21.com",
"created_on": 1578010100,
"modified_on": 1578010105,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"capabilities": ["full-admin"]
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,107 @@
{
"operationId": "updateUser",
"summary": "Update an existing User",
"tags": ["Users"],
"parameters": [
{
"in": "path",
"name": "userID",
"schema": {
"anyOf": [
{
"type": "integer",
"minimum": 1
},
{
"type": "string",
"pattern": "^me$"
}
]
},
"required": true,
"description": "Numeric ID of the user or 'me' to update yourself",
"example": 1
}
],
"requestBody": {
"description": "User details to update",
"required": true,
"content": {
"application/json": {
"schema": "{{schema.UpdateUser}}"
}
}
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"required": ["result"],
"properties": {
"result": {
"$ref": "#/components/schemas/UserObject"
}
}
},
"examples": {
"default": {
"value": {
"result": {
"id": 1,
"name": "Jamie Curnow",
"nickname": "James",
"email": "jc@jc21.com",
"created_on": 1578010100,
"modified_on": 1578010110,
"gravatar_url": "https://www.gravatar.com/avatar/6193176330f8d38747f038c170ddb193?d=mm&r=pg&s=128",
"is_disabled": false,
"capabilities": ["full-admin"]
}
}
}
}
}
}
},
"400": {
"description": "400 response",
"content": {
"application/json": {
"schema": {
"required": ["error"],
"properties": {
"result": {
"nullable": true
},
"error": {
"$ref": "#/components/schemas/ErrorObject"
}
}
},
"examples": {
"duplicateemail": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "A user already exists with this email address"
}
}
},
"nodisable": {
"value": {
"result": null,
"error": {
"code": 400,
"message": "You cannot disable yourself!"
}
}
}
}
}
}
}
}
}

19
backend/embed/main.go Normal file
View File

@ -0,0 +1,19 @@
package embed
import "embed"
// APIDocFiles contain all the files used for swagger schema generation
//go:embed api_docs
var APIDocFiles embed.FS
// Assets are frontend assets served from within this app
//go:embed assets
var Assets embed.FS
// MigrationFiles are database migrations
//go:embed migrations/*.sql
var MigrationFiles embed.FS
// NginxFiles hold nginx config templates
//go:embed nginx
var NginxFiles embed.FS

View File

@ -0,0 +1,209 @@
-- migrate:up
CREATE TABLE IF NOT EXISTS `user`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
name TEXT NOT NULL,
nickname TEXT NOT NULL,
email TEXT NOT NULL,
is_system INTEGER NOT NULL DEFAULT 0,
is_disabled INTEGER NOT NULL DEFAULT 0,
is_deleted INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS `capability`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS `user_has_capability`
(
user_id INTEGER NOT NULL,
capability_id INTEGER NOT NULL,
UNIQUE (user_id, capability_id),
FOREIGN KEY (capability_id) REFERENCES capability (id)
);
CREATE TABLE IF NOT EXISTS `auth`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
type TEXT NOT NULL,
secret TEXT NOT NULL,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id),
UNIQUE (user_id, type)
);
CREATE TABLE IF NOT EXISTS `setting`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
name TEXT NOT NULL,
description TEXT NOT NULL DEFAULT "",
value TEXT NOT NULL,
UNIQUE (name)
);
CREATE TABLE IF NOT EXISTS `audit_log`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
object_type TEXT NOT NULL,
object_id INTEGER NOT NULL,
action TEXT NOT NULL,
meta TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS `certificate_authority`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
name TEXT NOT NULL,
acmesh_server TEXT NOT NULL DEFAULT "",
ca_bundle TEXT NOT NULL DEFAULT "",
is_wildcard_supported INTEGER NOT NULL DEFAULT 0, -- specific to each CA, acme v1 doesn't usually have wildcards
max_domains INTEGER NOT NULL DEFAULT 5, -- per request
is_readonly INTEGER NOT NULL DEFAULT 0,
is_deleted INTEGER NOT NULL DEFAULT 0
);
CREATE TABLE IF NOT EXISTS `dns_provider`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
name TEXT NOT NULL,
acmesh_name TEXT NOT NULL,
dns_sleep INTEGER NOT NULL DEFAULT 0,
meta TEXT NOT NULL,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS `certificate`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
type TEXT NOT NULL, -- custom,dns,http
user_id INTEGER NOT NULL,
certificate_authority_id INTEGER, -- 0 for a custom cert
dns_provider_id INTEGER, -- 0, for a http or custom cert
name TEXT NOT NULL,
domain_names TEXT NOT NULL,
expires_on INTEGER DEFAULT 0,
status TEXT NOT NULL, -- ready,requesting,failed,provided
error_message text NOT NULL DEFAULT "",
meta TEXT NOT NULL,
is_ecc INTEGER NOT NULL DEFAULT 0,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id),
FOREIGN KEY (certificate_authority_id) REFERENCES certificate_authority (id),
FOREIGN KEY (dns_provider_id) REFERENCES dns_provider (id)
);
CREATE TABLE IF NOT EXISTS `stream`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
listen_interface TEXT NOT NULL,
incoming_port INTEGER NOT NULL,
upstream_options TEXT NOT NULL,
tcp_forwarding INTEGER NOT NULL DEFAULT 0,
udp_forwarding INTEGER NOT NULL DEFAULT 0,
advanced_config TEXT NOT NULL,
is_disabled INTEGER NOT NULL DEFAULT 0,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS `upstream`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
hosts TEXT NOT NULL,
balance_method TEXT NOT NULL,
max_fails INTEGER NOT NULL DEFAULT 1,
fail_timeout INTEGER NOT NULL DEFAULT 10,
advanced_config TEXT NOT NULL,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS `access_list`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
name TEXT NOT NULL,
meta TEXT NOT NULL,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS `host_template`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
name TEXT NOT NULL,
host_type TEXT NOT NULL,
template TEXT NOT NULL,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id)
);
CREATE TABLE IF NOT EXISTS `host`
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
created_on INTEGER NOT NULL DEFAULT 0,
modified_on INTEGER NOT NULL DEFAULT 0,
user_id INTEGER NOT NULL,
type TEXT NOT NULL,
host_template_id INTEGER NOT NULL,
listen_interface TEXT NOT NULL,
domain_names TEXT NOT NULL,
upstream_id INTEGER NOT NULL,
certificate_id INTEGER,
access_list_id INTEGER,
ssl_forced INTEGER NOT NULL DEFAULT 0,
caching_enabled INTEGER NOT NULL DEFAULT 0,
block_exploits INTEGER NOT NULL DEFAULT 0,
allow_websocket_upgrade INTEGER NOT NULL DEFAULT 0,
http2_support INTEGER NOT NULL DEFAULT 0,
hsts_enabled INTEGER NOT NULL DEFAULT 0,
hsts_subdomains INTEGER NOT NULL DEFAULT 0,
paths TEXT NOT NULL,
upstream_options TEXT NOT NULL DEFAULT "",
advanced_config TEXT NOT NULL DEFAULT "",
is_disabled INTEGER NOT NULL DEFAULT 0,
is_deleted INTEGER NOT NULL DEFAULT 0,
FOREIGN KEY (user_id) REFERENCES user (id),
FOREIGN KEY (host_template_id) REFERENCES host_template (id),
FOREIGN KEY (upstream_id) REFERENCES upstream (id),
FOREIGN KEY (certificate_id) REFERENCES certificate (id),
FOREIGN KEY (access_list_id) REFERENCES access_list (id)
);
-- migrate:down
-- Not allowed to go down from initial

View File

@ -0,0 +1,171 @@
-- migrate:up
-- User permissions
INSERT INTO `capability` (
name
) VALUES
("full-admin"),
("access-lists.view"),
("access-lists.manage"),
("audit-log.view"),
("certificates.view"),
("certificates.manage"),
("certificate-authorities.view"),
("certificate-authorities.manage"),
("dns-providers.view"),
("dns-providers.manage"),
("hosts.view"),
("hosts.manage"),
("host-templates.view"),
("host-templates.manage"),
("settings.manage"),
("streams.view"),
("streams.manage"),
("users.manage");
-- Default error reporting setting
INSERT INTO `setting` (
created_on,
modified_on,
name,
description,
value
) VALUES (
strftime('%s', 'now'),
strftime('%s', 'now'),
"error-reporting",
"If enabled, any application errors are reported to Sentry. Sensitive information is not sent.",
"true" -- remember this is json
);
-- Default site
INSERT INTO `setting` (
created_on,
modified_on,
name,
description,
value
) VALUES (
strftime('%s', 'now'),
strftime('%s', 'now'),
"default-site",
"What to show users who hit your Nginx server by default",
'"welcome"' -- remember this is json
);
-- Default Certificate Authorities
INSERT INTO `certificate_authority` (
created_on,
modified_on,
name,
acmesh_server,
is_wildcard_supported,
max_domains,
is_readonly
) VALUES (
strftime('%s', 'now'),
strftime('%s', 'now'),
"ZeroSSL",
"zerossl",
1,
10,
1
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
"Let's Encrypt",
"https://acme-v02.api.letsencrypt.org/directory",
1,
10,
1
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
"Buypass Go SSL",
"https://api.buypass.com/acme/directory",
0,
5,
1
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
"Let's Encrypt (Testing)",
"https://acme-staging-v02.api.letsencrypt.org/directory",
1,
10,
1
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
"Buypass Go SSL (Testing)",
"https://api.test4.buypass.no/acme/directory",
0,
5,
1
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
"SSL.com",
"ssl.com",
0,
10,
1
);
-- System User
INSERT INTO `user` (
created_on,
modified_on,
name,
nickname,
email,
is_system
) VALUES (
strftime('%s', 'now'),
strftime('%s', 'now'),
"System",
"System",
"system@localhost",
1
);
-- Host Templates
INSERT INTO `host_template` (
created_on,
modified_on,
user_id,
name,
host_type,
template
) VALUES (
strftime('%s', 'now'),
strftime('%s', 'now'),
(SELECT id FROM user WHERE is_system = 1 LIMIT 1),
"Default Proxy Template",
"proxy",
"# this is a proxy template"
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
(SELECT id FROM user WHERE is_system = 1 LIMIT 1),
"Default Redirect Template",
"redirect",
"# this is a redirect template"
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
(SELECT id FROM user WHERE is_system = 1 LIMIT 1),
"Default Dead Template",
"dead",
"# this is a dead template"
), (
strftime('%s', 'now'),
strftime('%s', 'now'),
(SELECT id FROM user WHERE is_system = 1 LIMIT 1),
"Default Stream Template",
"stream",
"# this is a stream template"
);
-- migrate:down

View File

@ -0,0 +1,4 @@
{{#if caching_enabled}}
# Asset Caching
include conf.d/include/assets.conf;
{{/if}}

View File

@ -0,0 +1,13 @@
{{#if certificate}}
{{#if (equal certificate.certificate_authority_id "0")}}
# Custom SSL
ssl_certificate {{npm_data_dir}}/custom_ssl/npm-{{certificate.id}}/fullchain.pem;
ssl_certificate_key {{npm_data_dir}}/custom_ssl/npm-{{certificate.id}}/privkey.pem;
{{else}}
# Acme SSL
include {{nginx_conf_dir}}/npm/conf.d/acme-challenge.conf;
include {{nginx_conf_dir}}/npm/conf.d/include/ssl-ciphers.conf;
ssl_certificate {{acme_certs_dir}}/npm-{{certificate.id}}/fullchain.pem;
ssl_certificate_key {{acme_certs_dir}}/npm-{{certificate.id}}/privkey.pem;
{{/if}}
{{/if}}

View File

@ -0,0 +1,6 @@
{{#if certificate}}
{{#if ssl_forced}}
# Force SSL
include {{nginx_conf_dir}}/npm/conf.d/include/force-ssl.conf;
{{/if}}
{{/if}}

View File

@ -0,0 +1,8 @@
{{#if certificate}}
{{#if ssl_forced}}
{{#if hsts_enabled}}
# HSTS (ngx_http_headers_module is required) (63072000 seconds = 2 years)
add_header Strict-Transport-Security "max-age=63072000;{{#if hsts_subdomains}} includeSubDomains;{{/if}} preload" always;
{{/if}}
{{/if}}
{{/if}}

View File

@ -0,0 +1,18 @@
listen 80;
{{#if ipv6}}
listen [::]:80;
{{else}}
#listen [::]:80;
{{/if}}
{{#if certificate}}
listen 443 ssl{% if http2_support %} http2{% endif %};
{{#if ipv6}}
listen [::]:443;
{{else}}
#listen [::]:443;
{{/if}}
{{/if}}
server_name{{#each domain_names}} {{this}}{{/each}};

View File

@ -0,0 +1,40 @@
location {{path}} {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Scheme $scheme;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass {{forward_scheme}}://{{forward_host}}:{{forward_port}}{{forward_path}};
{{#if access_list}}
{{#if access_list.items}}
# Authorization
auth_basic "Authorization required";
auth_basic_user_file {{npm_data_dir}}/access/{{access_list.id}};
{{access_list.passauth}}
{{/if}}
# Access Rules
{{#each access_list.clients as |client clientIdx|}}
{{client.rule}};
{{/each}}deny all;
# Access checks must...
{{#if access_list.satisfy}}
{{access_list.satisfy}};
{{/if}}
{{/if}}
{{> inc_assets}}
{{> inc_forced_ssl}}
{{> inc_hsts}}
{{#if allow_websocket_upgrade}}
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
proxy_http_version 1.1;
{{/if}}
{{advanced_config}}
}

View File

@ -0,0 +1,15 @@
server {
listen 80;
{{#if ipv6}}
listen [::]:80;
{{/if}}
server_name{{#each domain_names}} {{this}}{{/each}};
access_log {{npm_data_dir}}/logs/acme-requests_access.log standard;
error_log {{npm_data_dir}}/logs/acme-requests_error.log warn;
{{nginx_conf_dir}}/npm/conf.d/include/letsencrypt-acme-challenge.conf;
location / {
return 404;
}
}

View File

@ -0,0 +1,20 @@
{{#if enabled}}
server {
{{> inc_listen}}
{{> inc_certificates}}
{{> inc_hsts}}
{{> inc_forced_ssl}}
access_log {{npm_data_dir}}/logs/dead-host-{{id}}_access.log standard;
error_log {{npm_data_dir}}/logs/dead-host-{{id}}_error.log warn;
{{advanced_config}}
{{#if use_default_location}}
location / {
{{> inc_hsts}}
return 404;
}
{{/if}}
}
{{/if}}

View File

@ -0,0 +1,35 @@
{{#if (equal value "congratulations")}}
# Skipping output, congratulations page configration is baked in.
{{else}}
server {
listen 80 default;
{{#if ipv6}}
listen [::]:80;
{{else}}
#listen [::]:80;
{{/if}}
server_name default-host.localhost;
access_log {{npm_data_dir}}/logs/default-host_access.log combined;
error_log {{npm_data_dir}}/logs/default-host_error.log warn;
{{#if (equal value "404")}}
location / {
return 404;
}
{{/if}}
{{#if (equal value "redirect")}}
location / {
return 301 {{meta.redirect}};
}
{{/if}}
{{#if (equal value "html")}}
root {{npm_data_dir}}/nginx/default_www;
location / {
try_files $uri /index.html;
}
{{/if}}
}
{{/if}}

View File

@ -0,0 +1,3 @@
{{#each ip_ranges as |range rangeIdx|}}
set_real_ip_from {{range}};
{{/each}}

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