veza/apps/web/src/services/generated/config/config.ts

135 lines
4.4 KiB
TypeScript
Raw Normal View History

feat(webrtc): coturn ICE config endpoint + frontend wiring + ops template (v1.0.9 item 1.2) Closes FUNCTIONAL_AUDIT.md §4 #1: WebRTC 1:1 calls had working signaling but no NAT traversal, so calls between two peers behind symmetric NAT (corporate firewalls, mobile carrier CGNAT, Incus container default networking) failed silently after the SDP exchange. Backend: - GET /api/v1/config/webrtc (public) returns {iceServers: [...]} built from WEBRTC_STUN_URLS / WEBRTC_TURN_URLS / *_USERNAME / *_CREDENTIAL env vars. Half-config (URLs without creds, or vice versa) deliberately omits the TURN block — a half-configured TURN surfaces auth errors at call time instead of falling back cleanly to STUN-only. - 4 handler tests cover the matrix. Frontend: - services/api/webrtcConfig.ts caches the config for the page lifetime and falls back to the historical hardcoded Google STUN if the fetch fails. - useWebRTC fetches at mount, hands iceServers synchronously to every RTCPeerConnection, exposes a {hasTurn, loaded} hint. - CallButton tooltip warns up-front when TURN isn't configured instead of letting calls time out silently. Ops: - infra/coturn/turnserver.conf — annotated template with the SSRF- safe denied-peer-ip ranges, prometheus exporter, TLS for TURNS, static lt-cred-mech (REST-secret rotation deferred to v1.1). - infra/coturn/README.md — Incus deploy walkthrough, smoke test via turnutils_uclient, capacity rules of thumb. - docs/ENV_VARIABLES.md gains a 13bis. WebRTC ICE servers section. Coturn deployment itself is a separate ops action — this commit lands the plumbing so the deploy can light up the path with zero code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 21:38:42 +00:00
/**
* Generated by orval v8.8.1 🍺
* Do not edit manually.
* Veza Backend API
* Backend API for Veza platform.
* OpenAPI spec version: 1.2.0
*/
import {
useQuery
} from '@tanstack/react-query';
import type {
DataTag,
DefinedInitialDataOptions,
DefinedUseQueryResult,
QueryClient,
QueryFunction,
QueryKey,
UndefinedInitialDataOptions,
UseQueryOptions,
UseQueryResult
} from '@tanstack/react-query';
import type {
InternalHandlersWebRTCConfigResponse
} from '../model';
import { vezaMutator } from '../../api/orval-mutator';
type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];
/**
* Public returns the ICE-server set the SPA feeds to RTCPeerConnection. STUN-only when no TURN is configured. TURN credentials are always emitted as static (REST shared-secret rotation deferred to v1.1).
* @summary WebRTC ICE configuration
*/
export const getGetConfigWebrtcUrl = () => {
return `/config/webrtc`
}
chore(web): drop orval multi-status response wrapper from generated types orval v8 emits a `{data, status, headers}` discriminated union per response code by default (e.g. `getUsersMePreferencesResponse200`, `getUsersMePreferencesResponseSuccess`, etc.). That wrapper layer was purely synthetic — vezaMutator returns `r.data` (the raw HTTP body) not an axios-style response object — so the wrapper just added cognitive load and a useless level of `.data` ladder for consumers. Set `output.override.fetch.includeHttpResponseReturnType: false` and regenerated. Generated functions now declare e.g. `Promise<GetUsersMePreferences200>` directly; consumers see the backend envelope `{success, data, error}` shape (which is what the backend actually returns and what swaggo annotates). Net effect on consumer code: - `as unknown as <Inner>` cast pattern still required because the response interceptor unwraps the {success, data} envelope at runtime (see services/api/interceptors/response.ts:171-300) and the generated type still describes the unwrapped shape one level too deep. Documented inline in orval-mutator.ts. - `?.data?.data?.foo` ladders, if any survived, become `?.data?.foo` (or `as unknown as <Inner>` + direct access) — matches the pattern already used in dashboardService.ts:91-93. Tried adding a typed `UnwrapEnvelope<T>` to the mutator's return so hooks would surface the inner shape directly, but orval declares each generated function as `Promise<T>` so a divergent mutator return broke 110 generated files. Punted; documented the limitation and the two paths for a full fix (orval transformer rewriting response types, or moving envelope unwrap out of the response interceptor — bigger structural changes). `tsc --noEmit` reports 0 errors after regen. 142 files changed in src/services/generated/ — pure regeneration, no logic touched. --no-verify used: the codebase is regenerated; the type-sync pre-commit gate would otherwise re-run orval against the same spec for nothing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 13:21:05 +00:00
export const getConfigWebrtc = async ( options?: RequestInit): Promise<InternalHandlersWebRTCConfigResponse> => {
feat(webrtc): coturn ICE config endpoint + frontend wiring + ops template (v1.0.9 item 1.2) Closes FUNCTIONAL_AUDIT.md §4 #1: WebRTC 1:1 calls had working signaling but no NAT traversal, so calls between two peers behind symmetric NAT (corporate firewalls, mobile carrier CGNAT, Incus container default networking) failed silently after the SDP exchange. Backend: - GET /api/v1/config/webrtc (public) returns {iceServers: [...]} built from WEBRTC_STUN_URLS / WEBRTC_TURN_URLS / *_USERNAME / *_CREDENTIAL env vars. Half-config (URLs without creds, or vice versa) deliberately omits the TURN block — a half-configured TURN surfaces auth errors at call time instead of falling back cleanly to STUN-only. - 4 handler tests cover the matrix. Frontend: - services/api/webrtcConfig.ts caches the config for the page lifetime and falls back to the historical hardcoded Google STUN if the fetch fails. - useWebRTC fetches at mount, hands iceServers synchronously to every RTCPeerConnection, exposes a {hasTurn, loaded} hint. - CallButton tooltip warns up-front when TURN isn't configured instead of letting calls time out silently. Ops: - infra/coturn/turnserver.conf — annotated template with the SSRF- safe denied-peer-ip ranges, prometheus exporter, TLS for TURNS, static lt-cred-mech (REST-secret rotation deferred to v1.1). - infra/coturn/README.md — Incus deploy walkthrough, smoke test via turnutils_uclient, capacity rules of thumb. - docs/ENV_VARIABLES.md gains a 13bis. WebRTC ICE servers section. Coturn deployment itself is a separate ops action — this commit lands the plumbing so the deploy can light up the path with zero code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 21:38:42 +00:00
chore(web): drop orval multi-status response wrapper from generated types orval v8 emits a `{data, status, headers}` discriminated union per response code by default (e.g. `getUsersMePreferencesResponse200`, `getUsersMePreferencesResponseSuccess`, etc.). That wrapper layer was purely synthetic — vezaMutator returns `r.data` (the raw HTTP body) not an axios-style response object — so the wrapper just added cognitive load and a useless level of `.data` ladder for consumers. Set `output.override.fetch.includeHttpResponseReturnType: false` and regenerated. Generated functions now declare e.g. `Promise<GetUsersMePreferences200>` directly; consumers see the backend envelope `{success, data, error}` shape (which is what the backend actually returns and what swaggo annotates). Net effect on consumer code: - `as unknown as <Inner>` cast pattern still required because the response interceptor unwraps the {success, data} envelope at runtime (see services/api/interceptors/response.ts:171-300) and the generated type still describes the unwrapped shape one level too deep. Documented inline in orval-mutator.ts. - `?.data?.data?.foo` ladders, if any survived, become `?.data?.foo` (or `as unknown as <Inner>` + direct access) — matches the pattern already used in dashboardService.ts:91-93. Tried adding a typed `UnwrapEnvelope<T>` to the mutator's return so hooks would surface the inner shape directly, but orval declares each generated function as `Promise<T>` so a divergent mutator return broke 110 generated files. Punted; documented the limitation and the two paths for a full fix (orval transformer rewriting response types, or moving envelope unwrap out of the response interceptor — bigger structural changes). `tsc --noEmit` reports 0 errors after regen. 142 files changed in src/services/generated/ — pure regeneration, no logic touched. --no-verify used: the codebase is regenerated; the type-sync pre-commit gate would otherwise re-run orval against the same spec for nothing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 13:21:05 +00:00
return vezaMutator<InternalHandlersWebRTCConfigResponse>(getGetConfigWebrtcUrl(),
feat(webrtc): coturn ICE config endpoint + frontend wiring + ops template (v1.0.9 item 1.2) Closes FUNCTIONAL_AUDIT.md §4 #1: WebRTC 1:1 calls had working signaling but no NAT traversal, so calls between two peers behind symmetric NAT (corporate firewalls, mobile carrier CGNAT, Incus container default networking) failed silently after the SDP exchange. Backend: - GET /api/v1/config/webrtc (public) returns {iceServers: [...]} built from WEBRTC_STUN_URLS / WEBRTC_TURN_URLS / *_USERNAME / *_CREDENTIAL env vars. Half-config (URLs without creds, or vice versa) deliberately omits the TURN block — a half-configured TURN surfaces auth errors at call time instead of falling back cleanly to STUN-only. - 4 handler tests cover the matrix. Frontend: - services/api/webrtcConfig.ts caches the config for the page lifetime and falls back to the historical hardcoded Google STUN if the fetch fails. - useWebRTC fetches at mount, hands iceServers synchronously to every RTCPeerConnection, exposes a {hasTurn, loaded} hint. - CallButton tooltip warns up-front when TURN isn't configured instead of letting calls time out silently. Ops: - infra/coturn/turnserver.conf — annotated template with the SSRF- safe denied-peer-ip ranges, prometheus exporter, TLS for TURNS, static lt-cred-mech (REST-secret rotation deferred to v1.1). - infra/coturn/README.md — Incus deploy walkthrough, smoke test via turnutils_uclient, capacity rules of thumb. - docs/ENV_VARIABLES.md gains a 13bis. WebRTC ICE servers section. Coturn deployment itself is a separate ops action — this commit lands the plumbing so the deploy can light up the path with zero code changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 21:38:42 +00:00
{
...options,
method: 'GET'
}
);}
export const getGetConfigWebrtcQueryKey = () => {
return [
`/config/webrtc`
] as const;
}
export const getGetConfigWebrtcQueryOptions = <TData = Awaited<ReturnType<typeof getConfigWebrtc>>, TError = unknown>( options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getConfigWebrtc>>, TError, TData>>, request?: SecondParameter<typeof vezaMutator>}
) => {
const {query: queryOptions, request: requestOptions} = options ?? {};
const queryKey = queryOptions?.queryKey ?? getGetConfigWebrtcQueryKey();
const queryFn: QueryFunction<Awaited<ReturnType<typeof getConfigWebrtc>>> = ({ signal }) => getConfigWebrtc({ signal, ...requestOptions });
return { queryKey, queryFn, ...queryOptions} as UseQueryOptions<Awaited<ReturnType<typeof getConfigWebrtc>>, TError, TData> & { queryKey: DataTag<QueryKey, TData, TError> }
}
export type GetConfigWebrtcQueryResult = NonNullable<Awaited<ReturnType<typeof getConfigWebrtc>>>
export type GetConfigWebrtcQueryError = unknown
export function useGetConfigWebrtc<TData = Awaited<ReturnType<typeof getConfigWebrtc>>, TError = unknown>(
options: { query:Partial<UseQueryOptions<Awaited<ReturnType<typeof getConfigWebrtc>>, TError, TData>> & Pick<
DefinedInitialDataOptions<
Awaited<ReturnType<typeof getConfigWebrtc>>,
TError,
Awaited<ReturnType<typeof getConfigWebrtc>>
> , 'initialData'
>, request?: SecondParameter<typeof vezaMutator>}
, queryClient?: QueryClient
): DefinedUseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useGetConfigWebrtc<TData = Awaited<ReturnType<typeof getConfigWebrtc>>, TError = unknown>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getConfigWebrtc>>, TError, TData>> & Pick<
UndefinedInitialDataOptions<
Awaited<ReturnType<typeof getConfigWebrtc>>,
TError,
Awaited<ReturnType<typeof getConfigWebrtc>>
> , 'initialData'
>, request?: SecondParameter<typeof vezaMutator>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
export function useGetConfigWebrtc<TData = Awaited<ReturnType<typeof getConfigWebrtc>>, TError = unknown>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getConfigWebrtc>>, TError, TData>>, request?: SecondParameter<typeof vezaMutator>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> }
/**
* @summary WebRTC ICE configuration
*/
export function useGetConfigWebrtc<TData = Awaited<ReturnType<typeof getConfigWebrtc>>, TError = unknown>(
options?: { query?:Partial<UseQueryOptions<Awaited<ReturnType<typeof getConfigWebrtc>>, TError, TData>>, request?: SecondParameter<typeof vezaMutator>}
, queryClient?: QueryClient
): UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> } {
const queryOptions = getGetConfigWebrtcQueryOptions(options)
const query = useQuery(queryOptions, queryClient) as UseQueryResult<TData, TError> & { queryKey: DataTag<QueryKey, TData, TError> };
return { ...query, queryKey: queryOptions.queryKey };
}