mirror of
https://github.com/wu736139669/hapi.git
synced 2026-08-05 06:24:37 +00:00
feat: add wireguard relay integration for public server access with End-to-End Encryption
Integrates tunwg (WireGuard tunnel) to enable optional public access to the hapi server. Tunnel is disabled by default and enabled via --relay flag or HAPI_TUNNEL=true environment variable. Users can now run 'hapi server --relay' and get a direct link like: https://app.hapi.run/?server=https://xxx.relay.hapi.run&token=xxx
This commit is contained in:
@@ -125,6 +125,17 @@ function AppInner() {
|
||||
queryClient.clear()
|
||||
}, [baseUrl, queryClient])
|
||||
|
||||
// Clean up URL params after successful auth (for direct access links)
|
||||
useEffect(() => {
|
||||
if (!token || !api) return
|
||||
const url = new URL(window.location.href)
|
||||
if (url.searchParams.has('server') || url.searchParams.has('token')) {
|
||||
url.searchParams.delete('server')
|
||||
url.searchParams.delete('token')
|
||||
window.history.replaceState({}, '', url.toString())
|
||||
}
|
||||
}, [token, api])
|
||||
|
||||
useEffect(() => {
|
||||
if (!api || !token) {
|
||||
pushPromptedRef.current = false
|
||||
|
||||
@@ -21,6 +21,12 @@ function getTelegramInitData(): string | null {
|
||||
return initData || null
|
||||
}
|
||||
|
||||
function getTokenFromUrlParams(): string | null {
|
||||
if (typeof window === 'undefined') return null
|
||||
const query = new URLSearchParams(window.location.search)
|
||||
return query.get('token')
|
||||
}
|
||||
|
||||
function getAccessTokenKey(baseUrl: string): string {
|
||||
return `${ACCESS_TOKEN_PREFIX}${baseUrl}`
|
||||
}
|
||||
@@ -79,6 +85,15 @@ export function useAuthSource(baseUrl: string): {
|
||||
return
|
||||
}
|
||||
|
||||
// Check for URL token parameter (for direct access links)
|
||||
const urlToken = getTokenFromUrlParams()
|
||||
if (urlToken) {
|
||||
storeAccessToken(accessTokenKey, urlToken) // Save to localStorage for refresh
|
||||
setAuthSource({ type: 'accessToken', token: urlToken })
|
||||
setIsLoading(false)
|
||||
return
|
||||
}
|
||||
|
||||
// Check for stored access token as fallback
|
||||
const storedToken = getStoredAccessToken(accessTokenKey)
|
||||
if (storedToken) {
|
||||
|
||||
@@ -26,6 +26,17 @@ export function normalizeServerUrl(input: string): ServerUrlResult {
|
||||
return { ok: true, value: parsed.origin }
|
||||
}
|
||||
|
||||
function getServerFromUrlParams(): string | null {
|
||||
if (typeof window === 'undefined') return null
|
||||
const query = new URLSearchParams(window.location.search)
|
||||
const server = query.get('server')
|
||||
if (server) {
|
||||
const normalized = normalizeServerUrl(server)
|
||||
return normalized.ok ? normalized.value : null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
function readStoredServerUrl(): string | null {
|
||||
try {
|
||||
const stored = localStorage.getItem(SERVER_URL_KEY)
|
||||
@@ -65,7 +76,15 @@ export function useServerUrl(): {
|
||||
setServerUrl: (input: string) => ServerUrlResult
|
||||
clearServerUrl: () => void
|
||||
} {
|
||||
const [serverUrl, setServerUrlState] = useState<string | null>(() => readStoredServerUrl())
|
||||
const [serverUrl, setServerUrlState] = useState<string | null>(() => {
|
||||
// Priority: URL params > localStorage
|
||||
const fromUrl = getServerFromUrlParams()
|
||||
if (fromUrl) {
|
||||
writeStoredServerUrl(fromUrl) // Save to localStorage for refresh
|
||||
return fromUrl
|
||||
}
|
||||
return readStoredServerUrl()
|
||||
})
|
||||
|
||||
const fallbackOrigin = typeof window !== 'undefined' ? window.location.origin : ''
|
||||
const baseUrl = useMemo(() => serverUrl ?? fallbackOrigin, [serverUrl, fallbackOrigin])
|
||||
|
||||
Reference in New Issue
Block a user