Files
ComfyUI_frontend/src/utils/hostWhitelist.ts
sno 653cf64e01 [chore] Upgrade Prettier from 3.3.2 to 3.6.2 (#6089)
## Summary
- Updated Prettier from 3.3.2 to 3.6.2 in pnpm-workspace.yaml
- Ran `pnpm install` to update dependencies
- Ran `pnpm format` to apply new formatting rules
- Verified typecheck passes

## Test plan
- [x] TypeScript typecheck passes
- [x] Prettier formatting applied successfully

🤖 Generated with [Claude Code](https://claude.com/claude-code)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6089-chore-Upgrade-Prettier-from-3-3-2-to-3-6-2-28e6d73d3650816a888ff1129b14e0bc)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Christian Byrne <cbyrne@comfy.org>
2025-10-16 20:46:59 -07:00

99 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* Whitelisting helper for enabling SSO on safe, local-only hosts.
*
* Built-ins (always allowed):
* • 'localhost' and any subdomain of '.localhost' (e.g., app.localhost)
* • IPv4 loopback 127.0.0.0/8 (e.g., 127.0.0.1, 127.1.2.3)
* • IPv6 loopback ::1 (supports compressed/expanded textual forms)
*
* No environment variables are used. To add more exact hostnames,
* edit HOST_WHITELIST below.
*/
const HOST_WHITELIST: string[] = ['localhost']
/** Normalize for comparison: lowercase, strip port/brackets, trim trailing dot. */
export function normalizeHost(input: string): string {
let h = (input || '').trim().toLowerCase()
// Trim a trailing dot: 'localhost.' -> 'localhost'
h = h.replace(/\.$/, '')
// Remove ':port' safely.
// Case 1: [IPv6]:port
const mBracket = h.match(/^\[([^\]]+)\]:(\d+)$/)
if (mBracket) {
h = mBracket[1] // keep only the host inside the brackets
} else {
// Case 2: hostname/IPv4:port (exactly one ':')
const mPort = h.match(/^([^:]+):(\d+)$/)
if (mPort) h = mPort[1]
}
// Strip any remaining brackets (e.g., '[::1]' -> '::1')
h = h.replace(/^\[|\]$/g, '')
return h
}
/** Public check used by the UI. */
export function isHostWhitelisted(rawHost: string): boolean {
const host = normalizeHost(rawHost)
if (isLocalhostLabel(host)) return true
if (isIPv4Loopback(host)) return true
if (isIPv6Loopback(host)) return true
if (isComfyOrgHost(host)) return true
const normalizedList = HOST_WHITELIST.map(normalizeHost)
return normalizedList.includes(host)
}
/* -------------------- Helpers -------------------- */
function isLocalhostLabel(h: string): boolean {
// 'localhost' and any subdomain (e.g., 'app.localhost')
return h === 'localhost' || h.endsWith('.localhost')
}
const IPV4_OCTET = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|0?\\d?\\d)'
const V4_LOOPBACK_RE = new RegExp(
'^127\\.' + IPV4_OCTET + '\\.' + IPV4_OCTET + '\\.' + IPV4_OCTET + '$'
)
function isIPv4Loopback(h: string): boolean {
// 127/8 with strict 0255 octets (leading zeros allowed, e.g., 127.000.000.001)
return V4_LOOPBACK_RE.test(h)
}
// Fully expanded IPv6 loopback: 0:0:0:0:0:0:0:1 (allow leading zeros up to 4 chars)
const V6_FULL_LOOPBACK_RE = /^(?:0{1,4}:){7}0{0,3}1$/i
// Compressed IPv6 loopback forms around '::' with only zero groups before the final :1
// - Left side: zero groups separated by ':' (no trailing colon required)
// - Right side: zero groups each followed by ':' (so the final ':1' is provided by the pattern)
// The final group is exactly value 1, with up to 3 leading zeros (e.g., '0001').
const V6_COMPRESSED_LOOPBACK_RE =
/^((?:0{1,4}(?::0{1,4}){0,6})?)::((?:0{1,4}:){0,6})0{0,3}1$/i
function isIPv6Loopback(h: string): boolean {
// Exact full form: 0:0:0:0:0:0:0:1 (with up to 3 leading zeros on the final "1" group)
if (V6_FULL_LOOPBACK_RE.test(h)) return true
// Compressed forms that still equal ::1 (e.g., ::1, ::0001, 0:0::1, ::0:1, etc.)
const m = h.match(V6_COMPRESSED_LOOPBACK_RE)
if (!m) return false
// Count explicit zero groups on each side of '::' to ensure at least one group is compressed.
// (leftCount + rightCount) must be ≤ 6 so that the total expanded groups = 8.
const leftCount = m[1] ? (m[1].match(/0{1,4}:/gi)?.length ?? 0) : 0
const rightCount = m[2] ? (m[2].match(/0{1,4}:/gi)?.length ?? 0) : 0
// Require that at least one group was actually compressed: i.e., leftCount + rightCount ≤ 6.
return leftCount + rightCount <= 6
}
const COMFY_ORG_HOST = /\.comfy\.org$/
function isComfyOrgHost(h: string): boolean {
return COMFY_ORG_HOST.test(h)
}