feat(auth): allowlist private для LAN return_to
Build and Push Auth Portal Docker Image / build-and-push (push) Successful in 3m37s
Build and Push Auth Portal Docker Image / create-release (push) Skipped

Co-authored-by: Cursor <[email protected]>
This commit is contained in:
Denozordec
2026-07-18 13:49:37 +07:00
co-authored by Cursor
parent bac95bdb2e
commit 1cc58977fd
3 changed files with 20 additions and 3 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ ADMIN_PASSWORD=admin
ADMIN_NAME=Admin
# Allowed return_to hosts (comma-separated), e.g. .shnt.top or full origins
RETURN_TO_ALLOWLIST=.shnt.top,localhost,http://localhost:5173,http://localhost:5174
RETURN_TO_ALLOWLIST=.shnt.top,localhost,private,http://localhost:5173,http://localhost:5174
# ReUI PRO (apps/web/components.json → @reui Authorization)
# Ключ: https://reui.io/docs/license-setup — класть в apps/web/.env.local (gitignored)
+1 -1
View File
@@ -12,7 +12,7 @@ services:
ADMIN_EMAIL: ${ADMIN_EMAIL:[email protected]}
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-}
ADMIN_NAME: ${ADMIN_NAME:-Admin}
RETURN_TO_ALLOWLIST: ${RETURN_TO_ALLOWLIST:-.shnt.top,localhost}
RETURN_TO_ALLOWLIST: ${RETURN_TO_ALLOWLIST:-.shnt.top,localhost,private}
LOG_LEVEL: info
STATIC_DIR: /app/static
volumes:
+18 -1
View File
@@ -127,7 +127,8 @@ export function hasPermission(
}
/**
* Allowlist entries: `.shnt.top`, `localhost`, or full origins `http://localhost:5173`.
* Allowlist entries: `.shnt.top`, `localhost`, full origins `http://localhost:5173`,
* or token `private` for RFC1918 LAN hosts (192.168/10/172.16-31).
*/
export function isReturnToAllowed(
returnTo: string,
@@ -146,7 +147,11 @@ export function isReturnToAllowed(
.map((s) => s.trim())
.filter(Boolean)
const allowPrivate = entries.some((e) => e.toLowerCase() === 'private')
if (allowPrivate && isPrivateHostname(url.hostname)) return true
for (const entry of entries) {
if (entry.toLowerCase() === 'private') continue
if (entry.startsWith('.')) {
const suffix = entry.slice(1)
if (url.hostname === suffix || url.hostname.endsWith(entry)) return true
@@ -167,6 +172,18 @@ export function isReturnToAllowed(
return false
}
function isPrivateHostname(hostname: string): boolean {
if (hostname === 'localhost' || hostname.endsWith('.local')) return true
const m = /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(hostname)
if (!m) return false
const a = Number(m[1])
const b = Number(m[2])
if (a === 10) return true
if (a === 192 && b === 168) return true
if (a === 172 && b >= 16 && b <= 31) return true
return false
}
export function buildSsoRedirectUrl(
returnTo: string,
accessToken: string,