import type { IRouteConfig } from '@push.rocks/smartproxy'; import type { IRouteChallengeConfig } from '@push.rocks/smartchallenge'; import type * as servezoneInterfaces from '@serve.zone/interfaces'; import type { IDcRouterRouteConfig, IRouteRemoteIngress } from './remoteingress.js'; type TSmartProxyRouteRateLimit = NonNullable['rateLimit']>; export type TRouteRateLimitExceededPolicy = NonNullable; export interface IRouteRateLimit extends TSmartProxyRouteRateLimit { onExceeded?: TRouteRateLimitExceededPolicy; } type TSmartProxyRouteSecurityBase = Omit, 'rateLimit' | 'challenge'>; export interface IRouteSecurity extends TSmartProxyRouteSecurityBase { rateLimit?: IRouteRateLimit | null; challenge?: IRouteChallengeConfig | null; } export declare const apiTokenScopes: readonly ["*", "routes:read", "routes:write", "config:read", "stats:read", "logs:read", "config-events:read", "config-events:write", "security:read", "security:write", "emails:read", "emails:write", "certificates:read", "certificates:write", "tokens:read", "tokens:manage", "users:read", "users:manage", "source-profiles:read", "source-profiles:write", "target-profiles:read", "target-profiles:write", "targets:read", "targets:write", "dns-providers:read", "dns-providers:write", "domains:read", "domains:write", "dns-authority:read", "dns-authority:write", "dns-records:read", "dns-records:write", "acme-config:read", "acme-config:write", "email-domains:read", "email-domains:write", "smtp-accounts:read", "smtp-accounts:write", "remote-ingress:read", "remote-ingress:write", "vpn:read", "vpn:write", "radius:read", "radius:write", "gateway-clients:read", "gateway-clients:write", "workhosters:read", "workhosters:write"]; export type TApiTokenScope = typeof apiTokenScopes[number]; export type TGatewayClientType = 'onebox' | 'cloudly' | 'custom'; export interface IApiTokenPolicy { role: 'admin' | 'gatewayClient' | 'operator'; scopes?: TApiTokenScope[]; gatewayClient?: { type: TGatewayClientType; id: string; policyGeneration: number; }; hostnamePatterns?: string[]; allowedRouteTargets?: Array<{ host: string; ports: number[]; allowAnyPort?: boolean; }>; capabilities?: { readDomains?: boolean; readDnsRecords?: boolean; readRoutes?: boolean; syncRoutes?: boolean; syncDnsRecords?: boolean; readMail?: boolean; manageMail?: boolean; readCertificates?: boolean; requestCertificates?: boolean; readWebPush?: boolean; manageWebPush?: boolean; }; } export interface IGatewayCredentialLifecycle { source: 'provisioned'; state: 'candidate' | 'active'; /** Strictly monotonic within one gateway client. */ sequence: number; /** Generation this credential was issued to activate. */ policyGeneration: number; /** Digest of the exact durable policy snapshot this credential may activate. */ policyDigest: string; /** Set once when a provisioned candidate first becomes active. */ finalizedAt: number | null; /** Set only after older provisioned credentials have been durably cleaned up. */ cleanupCompletedAt: number | null; /** Stable response value retained for idempotent finalization retries. */ revokedCredentialCount: number | null; } /** * A reusable, named source profile that can be referenced by routes. * Stores the full IRouteSecurity shape from SmartProxy. * * SourceProfile = source-side (who can access: ipAllowList, rateLimit, auth) * TargetProfile = target-side (what can be accessed: domains, IP:port targets, route refs) */ export interface ISourceProfile { id: string; name: string; description?: string; /** The security configuration — mirrors SmartProxy's IRouteSecurity. */ security: IRouteSecurity; /** IDs of profiles this one extends (resolved top-down, later overrides earlier). */ extendsProfiles?: string[]; createdAt: number; updatedAt: number; createdBy: string; } export interface IRouteSourcePolicyExceededAction { type: '429'; errorMessage?: string; } export declare const routePathClasses: readonly ["git-smart-http", "static", "normal-html", "expensive-html", "raw", "archive"]; export type TRoutePathClass = typeof routePathClasses[number]; export declare const giteaRoutePathClassLabels: Record; export declare const giteaRoutePathClassPatterns: Record; export interface IRoutePathPolicyBinding { id?: string; pathClass: TRoutePathClass; /** Optional custom patterns. When omitted, the Gitea defaults for the class are used. */ pathPatterns?: string[]; /** Optional path-class override for the source binding's rate limit. */ rateLimit?: IRouteSecurity['rateLimit']; /** Optional path-class override for the source binding's browser challenge. */ challenge?: IRouteSecurity['challenge']; /** Optional path-class override for the source binding's connection limit. */ maxConnections?: IRouteSecurity['maxConnections']; onExceeded?: IRouteSourcePolicyExceededAction; } export interface IRouteSourceBinding { id?: string; sourceProfileRef: string; /** Snapshot of the profile name at resolution time, for display. */ sourceProfileName?: string; /** Optional route-level override for the referenced profile's rate limit. */ rateLimit?: IRouteSecurity['rateLimit']; /** Optional route-level override for the referenced profile's browser challenge. */ challenge?: IRouteSecurity['challenge']; /** Optional route-level override for the referenced profile's connection limit. */ maxConnections?: IRouteSecurity['maxConnections']; /** Optional exceeded message for source-policy connection/rate responses; rate-limit challenge lives on rateLimit.onExceeded. */ onExceeded?: IRouteSourcePolicyExceededAction; /** Optional path-class variants inside this source binding. Path-specific variants win over fallback variants. */ pathPolicies?: IRoutePathPolicyBinding[]; } /** * A reusable, named network target (host + port) that can be referenced by routes. */ export interface INetworkTarget { id: string; name: string; description?: string; host: string | string[]; port: number; createdAt: number; updatedAt: number; createdBy: string; } export declare const managedRouteKinds: readonly ["letsencrypt-http01-forward"]; export type TManagedRouteKind = typeof managedRouteKinds[number]; /** * Operator input for a canonical Let's Encrypt HTTP-01 forward. * Match port, path, protocol, priority, and source policy are server-managed. */ export interface ILetsEncryptHttp01ForwardConfig { name: string; domains: string[]; target?: { host: string; port: number; }; networkTargetRef?: string; remoteIngress?: IRouteRemoteIngress; } /** * Metadata on a stored route tracking where its resolved values came from. */ export interface IRouteMetadata { /** Ordered source profile bindings. The first matching source profile wins. */ sourceBindings?: IRouteSourceBinding[]; /** ID of the NetworkTargetDoc used to resolve this route's targets. */ networkTargetRef?: string; /** Snapshot of the target name at resolution time, for display. */ networkTargetName?: string; /** Timestamp of last reference resolution. */ lastResolvedAt?: number; /** External route ownership, used by gateway client reconciliation. */ ownerType?: 'gatewayClient' | 'operator' | 'system'; gatewayClientType?: TGatewayClientType; gatewayClientId?: string; gatewayClientAppId?: string; externalKey?: string; /** Persisted DNS intent for gateway route reconciliation. */ gatewayDnsMode?: servezoneInterfaces.data.TGatewayRouteDnsMode; /** Persisted provider proxy intent for gateway-managed DNS records. */ gatewayDnsProxied?: boolean; /** Canonical server-managed route purpose. */ managedRouteKind?: TManagedRouteKind; } /** * A route entry returned by the route management API. */ export interface IMergedRoute { route: IDcRouterRouteConfig; id: string; enabled: boolean; origin: 'config' | 'email' | 'dns' | 'api'; systemKey?: string; createdAt?: number; updatedAt?: number; metadata?: IRouteMetadata; } /** * A warning generated during route startup/apply. */ export interface IRouteWarning { /** * - 'disabled-route' → the route exists but is switched off. * - 'unverified-domain-ownership' → the route requests an automatic * certificate for a domain whose ownership dcrouter cannot prove, so ACME * can never succeed for it. Surfaced rather than refused for already-stored * routes; new and updated routes are refused outright. */ type: 'disabled-route' | 'unverified-domain-ownership'; routeName: string; message: string; } export type THttpRedirectStatus = 'active' | 'covered' | 'skipped'; /** * Derived HTTP-to-HTTPS redirect shown in the Ops UI. * These entries are generated from configured HTTPS routes and are not stored as routes. */ export interface IHttpRedirectInfo { id: string; status: THttpRedirectStatus; domainPattern: string; pathPattern?: string; fromTemplate: string; toTemplate: string; statusCode: number; priority: number; sourceRouteNames: string[]; sourceRouteIds: string[]; coveredByRouteNames: string[]; remoteIngress: boolean; notes?: string; } /** Return the stored route ID behind a source-policy-compiled route variant. */ export declare function canonicalizeSourceRouteId(routeId: string): string; /** * Public info about an API token (never includes the hash). */ export interface IApiTokenInfo { id: string; name: string; scopes: TApiTokenScope[]; policy?: IApiTokenPolicy; createdAt: number; expiresAt: number | null; lastUsedAt: number | null; enabled: boolean; } /** * A route persisted in the database. */ export interface IRoute { id: string; route: IDcRouterRouteConfig; enabled: boolean; createdAt: number; updatedAt: number; createdBy: string; origin: 'config' | 'email' | 'dns' | 'api'; systemKey?: string; metadata?: IRouteMetadata; } /** * A stored API token, stored in /config-api/tokens/{id}.json */ export interface IStoredApiToken { id: string; name: string; tokenHash: string; scopes: TApiTokenScope[]; policy?: IApiTokenPolicy; /** Null/absent means an ordinary manually issued token. */ gatewayCredentialLifecycle?: IGatewayCredentialLifecycle | null; createdAt: number; expiresAt: number | null; lastUsedAt: number | null; createdBy: string; enabled: boolean; } export {};