Compare commits

..

17 Commits

Author SHA1 Message Date
jc21
39c9bbb167 Merge branch 'master' into develop
All checks were successful
Close stale issues and PRs / stale (push) Successful in 18s
2025-11-11 16:06:05 +10:00
jc21
30c2781a02 Merge pull request #4765 from mamasch19/develop
add MC-HOST24 DNS plugin
2025-11-11 16:05:32 +10:00
Jamie Curnow
53e78dcc17 Bump version 2025-11-11 16:01:06 +10:00
jc21
62092b2ddc Merge pull request #4859 from 7heMech/develop
Fix hamburger menu on mobile
2025-11-11 15:37:12 +10:00
Jamie Curnow
2c26ed8b11 Revert "Fix #4831 mobile header menu not working"
This reverts commit 4bd545c88e.
2025-11-11 15:36:46 +10:00
jc21
e3f5cd9a58 Merge pull request #4871 from prospo/develop
chore: Bump certbot-dns-leaseweb to 1.0.3
2025-11-11 15:24:11 +10:00
jc21
fba14817e7 Merge pull request #4894 from eduardpaul/feat-fix-pass_auth-template
Update _access.conf to fix access_list.pass_auth logic
2025-11-11 15:23:22 +10:00
Jamie Curnow
6825a9773b Fix #4854 Added missing forward http code for redirections 2025-11-11 15:17:43 +10:00
Jamie Curnow
8bc3078d87 Fix initial setup user bug, taking the fix from #4836 2025-11-11 14:52:39 +10:00
Jamie Curnow
8aeb2fa661 Fix #4692, #4856 - stick with auto for scheme in db, change it to $scheme when rendering 2025-11-11 14:46:25 +10:00
mamasch19
5e7276e65b Add MC-HOST24 DNS plugin configuration
added the MC-HOST24 configuration to the new plugin file
2025-11-09 22:31:48 +01:00
Eduard Paul
2bcb942f93 Update _access.conf to ensure Authorization header remove when pass_auth = false or 0
Fixing prev commit as it's negative logic.
2025-11-09 21:02:18 +01:00
Eduard Paul
b3dac3df08 Update _access.conf to fix access_list.pass_auth logic
Wrong logic to pass auth as header: when disabled (pass_auth=0) credentials are included in Authorization header. However as soon as you enable (pass_auth=1) they are not.
2025-11-09 20:11:33 +01:00
jc21
64c5a863f8 Merge pull request #4878 from NginxProxyManager/develop
v2.13.2
2025-11-09 21:16:26 +10:00
Emil
fd1d33444a chore: Bump certbot-dns-leaseweb to 1.0.3 2025-11-08 14:39:23 +01:00
7heMech
6fa2d6a98a Fix hamburger menu on mobile 2025-11-07 19:34:43 +00:00
jc21
e88d55f1d2 Merge pull request #4839 from NginxProxyManager/develop
v2.13.1
2025-11-05 15:40:32 +10:00
13 changed files with 209 additions and 114 deletions

View File

@@ -1 +1 @@
2.13.2 2.13.3

View File

@@ -1,7 +1,7 @@
<p align="center"> <p align="center">
<img src="https://nginxproxymanager.com/github.png"> <img src="https://nginxproxymanager.com/github.png">
<br><br> <br><br>
<img src="https://img.shields.io/badge/version-2.13.2-green.svg?style=for-the-badge"> <img src="https://img.shields.io/badge/version-2.13.3-green.svg?style=for-the-badge">
<a href="https://hub.docker.com/repository/docker/jc21/nginx-proxy-manager"> <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"> <img src="https://img.shields.io/docker/stars/jc21/nginx-proxy-manager.svg?style=for-the-badge">
</a> </a>

View File

@@ -370,7 +370,7 @@
"leaseweb": { "leaseweb": {
"name": "LeaseWeb", "name": "LeaseWeb",
"package_name": "certbot-dns-leaseweb", "package_name": "certbot-dns-leaseweb",
"version": "~=1.0.1", "version": "~=1.0.3",
"dependencies": "", "dependencies": "",
"credentials": "dns_leaseweb_api_token = 01234556789", "credentials": "dns_leaseweb_api_token = 01234556789",
"full_plugin_name": "dns-leaseweb" "full_plugin_name": "dns-leaseweb"
@@ -399,6 +399,14 @@
"credentials": "dns_luadns_email = user@example.com\ndns_luadns_token = 0123456789abcdef0123456789abcdef", "credentials": "dns_luadns_email = user@example.com\ndns_luadns_token = 0123456789abcdef0123456789abcdef",
"full_plugin_name": "dns-luadns" "full_plugin_name": "dns-luadns"
}, },
"mchost24": {
"name": "MC-HOST24",
"package_name": "certbot-dns-mchost24",
"version": "",
"dependencies": "",
"credentials": "# Obtain API token using https://github.com/JoeJoeTV/mchost24-api-python\ndns_mchost24_api_token=<insert obtained API token here>",
"full_plugin_name": "dns-mchost24"
},
"mijnhost": { "mijnhost": {
"name": "mijn.host", "name": "mijn.host",
"package_name": "certbot-dns-mijn-host", "package_name": "certbot-dns-mijn-host",

View File

@@ -216,6 +216,11 @@ const internalNginx = {
} }
} }
// For redirection hosts, if the scheme is not http or https, set it to $scheme
if (nice_host_type === "redirection_host" && ['http', 'https'].indexOf(host.forward_scheme.toLowerCase()) === -1) {
host.forward_scheme = "$scheme";
}
if (host.locations) { if (host.locations) {
//logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2)); //logger.info ('host.locations = ' + JSON.stringify(host.locations, null, 2));
origLocations = [].concat(host.locations); origLocations = [].concat(host.locations);

View File

@@ -0,0 +1,50 @@
import { migrate as logger } from "../logger.js";
const migrateName = "redirect_auto_scheme";
/**
* Migrate
*
* @see http://knexjs.org/#Schema
*
* @param {Object} knex
* @returns {Promise}
*/
const up = (knex) => {
logger.info(`[${migrateName}] Migrating Up...`);
return knex.schema
.table("redirection_host", async (table) => {
// change the column default from $scheme to auto
await table.string("forward_scheme").notNull().defaultTo("auto").alter();
await knex('redirection_host')
.where('forward_scheme', '$scheme')
.update({ forward_scheme: 'auto' });
})
.then(() => {
logger.info(`[${migrateName}] redirection_host Table altered`);
});
};
/**
* Undo Migrate
*
* @param {Object} knex
* @returns {Promise}
*/
const down = (knex) => {
logger.info(`[${migrateName}] Migrating Down...`);
return knex.schema
.table("redirection_host", async (table) => {
await table.string("forward_scheme").notNull().defaultTo("$scheme").alter();
await knex('redirection_host')
.where('forward_scheme', 'auto')
.update({ forward_scheme: '$scheme' });
})
.then(() => {
logger.info(`[${migrateName}] redirection_host Table altered`);
});
};
export { up, down };

View File

@@ -37,7 +37,7 @@ const setupDefaultUser = async () => {
const data = { const data = {
is_deleted: 0, is_deleted: 0,
email: email, email: initialAdminEmail,
name: "Administrator", name: "Administrator",
nickname: "Admin", nickname: "Admin",
avatar: "", avatar: "",
@@ -53,7 +53,7 @@ const setupDefaultUser = async () => {
.insert({ .insert({
user_id: user.id, user_id: user.id,
type: "password", type: "password",
secret: password, secret: initialAdminPassword,
meta: {}, meta: {},
}); });

View File

@@ -4,7 +4,7 @@
auth_basic "Authorization required"; auth_basic "Authorization required";
auth_basic_user_file /data/access/{{ access_list_id }}; auth_basic_user_file /data/access/{{ access_list_id }};
{% if access_list.pass_auth == 0 or access_list.pass_auth == true %} {% if access_list.pass_auth == 0 or access_list.pass_auth == false %}
proxy_set_header Authorization ""; proxy_set_header Authorization "";
{% endif %} {% endif %}

View File

@@ -1,6 +1,15 @@
import { lazy, Suspense } from "react"; import { lazy, Suspense } from "react";
import { BrowserRouter, Route, Routes } from "react-router-dom"; import { BrowserRouter, Route, Routes } from "react-router-dom";
import { ErrorNotFound, LoadingPage, Page, SiteContainer, SiteFooter, SiteHeader, Unhealthy } from "src/components"; import {
ErrorNotFound,
LoadingPage,
Page,
SiteContainer,
SiteFooter,
SiteHeader,
SiteMenu,
Unhealthy,
} from "src/components";
import { useAuthState } from "src/context"; import { useAuthState } from "src/context";
import { useHealth } from "src/hooks"; import { useHealth } from "src/hooks";
@@ -46,6 +55,7 @@ function Router() {
<Page> <Page>
<div> <div>
<SiteHeader /> <SiteHeader />
<SiteMenu />
</div> </div>
<SiteContainer> <SiteContainer>
<Suspense fallback={<LoadingPage noLogo />}> <Suspense fallback={<LoadingPage noLogo />}>

View File

@@ -1,7 +1,5 @@
import { IconLock, IconLogout, IconUser } from "@tabler/icons-react"; import { IconLock, IconLogout, IconUser } from "@tabler/icons-react";
import cs from "classnames"; import { LocalePicker, NavLink, ThemeSwitcher } from "src/components";
import { useState } from "react";
import { LocalePicker, NavLink, SiteMenu, ThemeSwitcher } from "src/components";
import { useAuthState } from "src/context"; import { useAuthState } from "src/context";
import { useUser } from "src/hooks"; import { useUser } from "src/hooks";
import { T } from "src/locale"; import { T } from "src/locale";
@@ -12,21 +10,18 @@ export function SiteHeader() {
const { data: currentUser } = useUser("me"); const { data: currentUser } = useUser("me");
const isAdmin = currentUser?.roles.includes("admin"); const isAdmin = currentUser?.roles.includes("admin");
const { logout } = useAuthState(); const { logout } = useAuthState();
const [expanded, setExpanded] = useState(false);
return ( return (
<>
<header className="navbar navbar-expand-md d-print-none"> <header className="navbar navbar-expand-md d-print-none">
<div className="container-xl"> <div className="container-xl">
<button <button
className={cs("navbar-toggler", { collapsed: !expanded })} className="navbar-toggler"
type="button" type="button"
data-bs-toggle="collapse" data-bs-toggle="collapse"
data-bs-target="#navbar-menu" data-bs-target="#navbar-menu"
aria-controls="navbar-menu" aria-controls="navbar-menu"
aria-expanded={expanded} aria-expanded="false"
aria-label="Toggle navigation" aria-label="Toggle navigation"
onClick={() => setExpanded(!expanded)}
> >
<span className="navbar-toggler-icon" /> <span className="navbar-toggler-icon" />
</button> </button>
@@ -115,7 +110,5 @@ export function SiteHeader() {
</div> </div>
</div> </div>
</header> </header>
<SiteMenu mobileExpanded={expanded} setMobileExpanded={setExpanded} />
</>
); );
} }

View File

@@ -175,11 +175,7 @@ const getMenuDropown = (item: MenuItem, onClick?: () => void) => {
); );
}; };
interface Props { export function SiteMenu() {
mobileExpanded?: boolean;
setMobileExpanded?: (expanded: boolean) => void;
}
export function SiteMenu({ mobileExpanded = false, setMobileExpanded }: Props) {
// This is hacky AF. But that's the price of using a non-react UI kit. // This is hacky AF. But that's the price of using a non-react UI kit.
const closeMenus = () => { const closeMenus = () => {
const navMenus = document.querySelectorAll(".nav-item.dropdown"); const navMenus = document.querySelectorAll(".nav-item.dropdown");
@@ -189,13 +185,12 @@ export function SiteMenu({ mobileExpanded = false, setMobileExpanded }: Props) {
if (dropdown) { if (dropdown) {
dropdown.classList.remove("show"); dropdown.classList.remove("show");
} }
setMobileExpanded?.(false);
}); });
}; };
return ( return (
<header className="navbar-expand-md"> <header className="navbar-expand-md">
<div className={cn("collapse", "navbar-collapse", { show: mobileExpanded })} id="navbar-menu"> <div className="collapse navbar-collapse" id="navbar-menu">
<div className="navbar"> <div className="navbar">
<div className="container-xl"> <div className="container-xl">
<div className="row flex-column flex-md-row flex-fill align-items-center"> <div className="row flex-column flex-md-row flex-fill align-items-center">

View File

@@ -169,6 +169,7 @@
"public": "Public", "public": "Public",
"redirection-host": "Redirection Host", "redirection-host": "Redirection Host",
"redirection-host.forward-domain": "Forward Domain", "redirection-host.forward-domain": "Forward Domain",
"redirection-host.forward-http-code": "HTTP Code",
"redirection-hosts": "Redirection Hosts", "redirection-hosts": "Redirection Hosts",
"redirection-hosts.count": "{count} {count, plural, one {Redirection Host} other {Redirection Hosts}}", "redirection-hosts.count": "{count} {count, plural, one {Redirection Host} other {Redirection Hosts}}",
"role.admin": "Administrator", "role.admin": "Administrator",

View File

@@ -509,6 +509,9 @@
"redirection-host.forward-domain": { "redirection-host.forward-domain": {
"defaultMessage": "Forward Domain" "defaultMessage": "Forward Domain"
}, },
"redirection-host.forward-http-code": {
"defaultMessage": "HTTP Code"
},
"redirection-hosts": { "redirection-hosts": {
"defaultMessage": "Redirection Hosts" "defaultMessage": "Redirection Hosts"
}, },

View File

@@ -162,7 +162,7 @@ const RedirectionHostModal = EasyModal.create(({ id, visible, remove }: Props) =
required required
{...field} {...field}
> >
<option value="$scheme">Auto</option> <option value="auto">Auto</option>
<option value="http">http</option> <option value="http">http</option>
<option value="https">https</option> <option value="https">https</option>
</select> </select>
@@ -212,6 +212,36 @@ const RedirectionHostModal = EasyModal.create(({ id, visible, remove }: Props) =
</Field> </Field>
</div> </div>
</div> </div>
<Field name="forwardHttpCode">
{({ field, form }: any) => (
<div className="mb-3">
<label className="form-label" htmlFor="forwardHttpCode">
<T id="redirection-host.forward-http-code" />
</label>
<select
id="forwardHttpCode"
className={`form-control ${form.errors.forwardHttpCode && form.touched.forwardHttpCode ? "is-invalid" : ""}`}
required
{...field}
>
<option value="300">300 Multiple choices</option>
<option value="301">301 Moved permanently</option>
<option value="302">302 Moved temporarily</option>
<option value="303">303 See other</option>
<option value="307">307 Temporary redirect</option>
<option value="308">308 Permanent redirect</option>
</select>
{form.errors.forwardHttpCode ? (
<div className="invalid-feedback">
{form.errors.forwardHttpCode &&
form.touched.forwardHttpCode
? form.errors.forwardHttpCode
: null}
</div>
) : null}
</div>
)}
</Field>
<div className="my-3"> <div className="my-3">
<h4 className="py-2"> <h4 className="py-2">
<T id="options" /> <T id="options" />