mirror of
https://github.com/shuaiplus/nodewarden.git
synced 2026-06-20 13:00:39 +00:00
fix: remove unused change password handling functions from public route
This commit is contained in:
@@ -77,82 +77,6 @@ function handleMissingWebsiteIcon(): Response {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPrivateIpv4(hostname: string): boolean {
|
|
||||||
const parts = hostname.split('.').map((part) => Number(part));
|
|
||||||
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) return false;
|
|
||||||
const [a, b] = parts;
|
|
||||||
return (
|
|
||||||
a === 10 ||
|
|
||||||
a === 127 ||
|
|
||||||
(a === 169 && b === 254) ||
|
|
||||||
(a === 172 && b >= 16 && b <= 31) ||
|
|
||||||
(a === 192 && b === 168) ||
|
|
||||||
a === 0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function isBlockedChangePasswordHost(hostname: string): boolean {
|
|
||||||
const normalized = hostname.toLowerCase().replace(/\.+$/, '');
|
|
||||||
return (
|
|
||||||
normalized === 'localhost' ||
|
|
||||||
normalized.endsWith('.localhost') ||
|
|
||||||
normalized.endsWith('.local') ||
|
|
||||||
normalized === '::1' ||
|
|
||||||
normalized.startsWith('[') ||
|
|
||||||
isPrivateIpv4(normalized)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function parsePublicHttpUrl(rawUri: string | null): URL | null {
|
|
||||||
if (!rawUri) return null;
|
|
||||||
try {
|
|
||||||
const url = new URL(rawUri);
|
|
||||||
if (url.protocol !== 'http:' && url.protocol !== 'https:') return null;
|
|
||||||
if (isBlockedChangePasswordHost(url.hostname)) return null;
|
|
||||||
return url;
|
|
||||||
} catch {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function handleChangePasswordUri(request: Request): Promise<Response> {
|
|
||||||
const sourceUrl = parsePublicHttpUrl(new URL(request.url).searchParams.get('uri'));
|
|
||||||
if (!sourceUrl) {
|
|
||||||
return jsonResponse({ uri: null });
|
|
||||||
}
|
|
||||||
|
|
||||||
const wellKnownUrl = new URL('/.well-known/change-password', sourceUrl.origin);
|
|
||||||
const controller = new AbortController();
|
|
||||||
const timeout = setTimeout(() => controller.abort(), ICON_UPSTREAM_TIMEOUT_MS);
|
|
||||||
try {
|
|
||||||
const response = await fetch(wellKnownUrl.toString(), {
|
|
||||||
method: 'GET',
|
|
||||||
redirect: 'manual',
|
|
||||||
signal: controller.signal,
|
|
||||||
cf: {
|
|
||||||
cacheEverything: true,
|
|
||||||
cacheTtl: LIMITS.cache.iconTtlSeconds,
|
|
||||||
},
|
|
||||||
} as RequestInit & { cf: { cacheEverything: boolean; cacheTtl: number } });
|
|
||||||
|
|
||||||
if (response.status < 300 || response.status >= 400) {
|
|
||||||
return jsonResponse({ uri: null });
|
|
||||||
}
|
|
||||||
|
|
||||||
const location = response.headers.get('Location');
|
|
||||||
if (!location) return jsonResponse({ uri: null });
|
|
||||||
|
|
||||||
const targetUrl = parsePublicHttpUrl(new URL(location, wellKnownUrl).toString());
|
|
||||||
if (!targetUrl) return jsonResponse({ uri: null });
|
|
||||||
|
|
||||||
return jsonResponse({ uri: targetUrl.toString() });
|
|
||||||
} catch {
|
|
||||||
return jsonResponse({ uri: null });
|
|
||||||
} finally {
|
|
||||||
clearTimeout(timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function buildIconServiceBase(origin: string): string {
|
function buildIconServiceBase(origin: string): string {
|
||||||
return `${origin}/icons`;
|
return `${origin}/icons`;
|
||||||
}
|
}
|
||||||
@@ -360,12 +284,6 @@ export async function handlePublicRoute(
|
|||||||
return jsonResponse(await buildWebBootstrapResponse(env));
|
return jsonResponse(await buildWebBootstrapResponse(env));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (path === '/icons/change-password-uri' && method === 'GET') {
|
|
||||||
const blocked = await enforcePublicRateLimit('public-read', LIMITS.rateLimit.publicReadRequestsPerMinute);
|
|
||||||
if (blocked) return blocked;
|
|
||||||
return handleChangePasswordUri(request);
|
|
||||||
}
|
|
||||||
|
|
||||||
const iconMatch = path.match(/^\/icons\/([^/]+)\/icon\.png$/i);
|
const iconMatch = path.match(/^\/icons\/([^/]+)\/icon\.png$/i);
|
||||||
if (iconMatch && method === 'GET') {
|
if (iconMatch && method === 'GET') {
|
||||||
const fallbackMode = new URL(request.url).searchParams.get('fallback') === '404' ? 'not-found' : 'default';
|
const fallbackMode = new URL(request.url).searchParams.get('fallback') === '404' ? 'not-found' : 'default';
|
||||||
|
|||||||
Reference in New Issue
Block a user