refactor(api): unify routes under /api/v1/d, agent, relay, tunnel

Remove the /openflare prefix from management APIs (/api/v1/d/*) and move
Agent, Relay, and Tunnel protocol endpoints under /api/v1. Update Wavelet
frontend services and node client binaries to match.
This commit is contained in:
ryan
2026-06-19 11:08:06 +08:00
parent 6bd7dc91fc
commit 71ebfa555f
48 changed files with 18463 additions and 21924 deletions
+7022 -8336
View File
File diff suppressed because it is too large Load Diff
+7022 -8336
View File
File diff suppressed because it is too large Load Diff
+4254 -5085
View File
File diff suppressed because it is too large Load Diff
@@ -26,7 +26,7 @@ function buildSearchParams(filters: object): Record<string, unknown> {
}
export class AccessLogService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/access-logs';
protected static override readonly basePath: string = '/api/v1/d/access-logs';
static list(filters: AccessLogFilters = {}): Promise<AccessLogList> {
return this.get<AccessLogList>('/', buildSearchParams(filters));
@@ -7,7 +7,7 @@ import type {
} from './types';
export class ApplyLogService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/apply-logs';
protected static override readonly basePath: string = '/api/v1/d/apply-logs';
static list(query: ApplyLogListQuery = {}): Promise<ApplyLogList> {
const params: Record<string, unknown> = {};
@@ -1,5 +1,5 @@
import {BaseService} from '@/lib/services/core';
export class OpenFlareBaseService extends BaseService {
protected static override readonly basePath: string = '/api/v1/openflare';
protected static override readonly basePath: string = '/api/v1/d';
}
@@ -11,7 +11,7 @@ import type {
} from './types';
export class ConfigVersionService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/config-versions';
protected static override readonly basePath: string = '/api/v1/d/config-versions';
static list(): Promise<ConfigVersionSummary[]> {
return this.get<ConfigVersionSummary[]>('/');
@@ -231,7 +231,7 @@ function normalizeDashboardOverview(
}
export class DashboardService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/dashboard';
protected static override readonly basePath: string = '/api/v1/d/dashboard';
static async getOverview(): Promise<DashboardOverview | null> {
const overview = await this.get<
@@ -2,7 +2,7 @@ import {OpenFlareBaseService} from './base.service';
import type {DnsAccountItem, DnsAccountMutationPayload} from './types';
export class DnsAccountService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/dns-accounts';
protected static override readonly basePath: string = '/api/v1/d/dns-accounts';
static async list(): Promise<DnsAccountItem[]> {
return this.get<DnsAccountItem[]>('/');
@@ -10,7 +10,7 @@ import type {
} from './types';
export class NodeService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/nodes';
protected static override readonly basePath: string = '/api/v1/d/nodes';
static async listNodes(): Promise<NodeItem[]> {
return this.get<NodeItem[]>('/');
@@ -8,7 +8,7 @@ import type {
} from './types';
export class OptionService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/option';
protected static override readonly basePath: string = '/api/v1/d/option';
static list(): Promise<OptionItem[]> {
return this.get<OptionItem[]>('/');
@@ -2,7 +2,7 @@ import {OpenFlareBaseService} from './base.service';
import type {OriginDetail, OriginItem, OriginMutationPayload} from './types';
export class OriginService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/origins';
protected static override readonly basePath: string = '/api/v1/d/origins';
static list(): Promise<OriginItem[]> {
return this.get<OriginItem[]>('/');
@@ -13,7 +13,7 @@ import type {
} from './types';
export class PagesService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/pages';
protected static override readonly basePath: string = '/api/v1/d/pages';
static listProjects(): Promise<PagesProject[]> {
return this.get<PagesProject[]>('/');
@@ -2,7 +2,7 @@ import {OpenFlareBaseService} from './base.service';
import type {ProxyRouteItem, ProxyRouteMutationPayload} from './types';
export class ProxyRouteService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/proxy-routes';
protected static override readonly basePath: string = '/api/v1/d/proxy-routes';
static async list(): Promise<ProxyRouteItem[]> {
return this.get<ProxyRouteItem[]>('/');
@@ -10,7 +10,7 @@ import type {
} from './types';
class AcmeAccountApi extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/acme-accounts';
protected static override readonly basePath: string = '/api/v1/d/acme-accounts';
static getDefault(): Promise<AcmeAccountItem> {
return this.get<AcmeAccountItem>('/default');
@@ -18,7 +18,7 @@ class AcmeAccountApi extends OpenFlareBaseService {
}
export class TlsCertificateService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/tls-certificates';
protected static override readonly basePath: string = '/api/v1/d/tls-certificates';
static async list(): Promise<TlsCertificateItem[]> {
return this.get<TlsCertificateItem[]>('/');
@@ -8,10 +8,10 @@ import {OpenFlareBaseService} from './base.service';
import type {LatestReleaseInfo, ReleaseChannel, UpgradeStreamSnapshot, UploadedServerBinaryInfo} from './types';
/**
* OpenFlare 服务端升级 API(`/api/v1/openflare/update/*`)。
* OpenFlare 服务端升级 API(`/api/v1/d/update/*`)。
*/
export class UpdateService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/update';
protected static override readonly basePath: string = '/api/v1/d/update';
private static getApiUrl(path: string): string {
const baseURL = getApiBaseUrl();
@@ -1,7 +1,7 @@
import {OpenFlareBaseService} from './base.service';
export class UptimeKumaService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/uptimekuma';
protected static override readonly basePath: string = '/api/v1/d/uptimekuma';
static sync(): Promise<void> {
return this.post<void>('/sync');
@@ -11,7 +11,7 @@ import type {
} from './types';
export class WafService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/waf';
protected static override readonly basePath: string = '/api/v1/d/waf';
static async listRuleGroups(): Promise<WAFRuleGroup[]> {
return this.get<WAFRuleGroup[]>('/rule-groups');
@@ -6,7 +6,7 @@ import type {
} from './types';
export class WebsiteService extends OpenFlareBaseService {
protected static override readonly basePath: string = '/api/v1/openflare/managed-domains';
protected static override readonly basePath: string = '/api/v1/d/managed-domains';
static async list(): Promise<ManagedDomainItem[]> {
return this.get<ManagedDomainItem[]>('/');
@@ -28,7 +28,7 @@ import (
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/apply-logs [get]
// @Router /api/v1/d/apply-logs [get]
func GetApplyLogs(c *gin.Context) {
result, err := ListPage(c.Request.Context(), ListQuery{
NodeID: c.Query("node_id"),
@@ -53,7 +53,7 @@ func GetApplyLogs(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/apply-logs/cleanup [post]
// @Router /api/v1/d/apply-logs/cleanup [post]
func CleanupApplyLogs(c *gin.Context) {
var input CleanupInput
if !apiutil.BindJSON(c, &input) {
@@ -29,7 +29,7 @@ func handleLogicError(c *gin.Context, err error) bool {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/config-versions [get]
// @Router /api/v1/d/config-versions [get]
func ListConfigVersionsHandler(c *gin.Context) {
versions, err := ListConfigVersions(c.Request.Context())
if handleLogicError(c, err) {
@@ -49,7 +49,7 @@ func ListConfigVersionsHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或版本不存在"
// @Router /api/v1/openflare/config-versions/{id} [get]
// @Router /api/v1/d/config-versions/{id} [get]
func GetConfigVersionHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -71,7 +71,7 @@ func GetConfigVersionHandler(c *gin.Context) {
// @Success 200 {object} response.Any{data=model.ConfigVersion} "活跃配置版本"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限、不存在或无活跃版本"
// @Router /api/v1/openflare/config-versions/active [get]
// @Router /api/v1/d/config-versions/active [get]
func GetActiveConfigVersionHandler(c *gin.Context) {
version, err := GetActiveConfigVersion(c.Request.Context())
if apiutil.AbortNotFoundIfMissing(c, err, errNoActiveVersion) {
@@ -90,7 +90,7 @@ func GetActiveConfigVersionHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/config-versions/preview [get]
// @Router /api/v1/d/config-versions/preview [get]
func PreviewConfigVersionHandler(c *gin.Context) {
preview, err := PreviewConfigVersion(c.Request.Context())
if handleLogicError(c, err) {
@@ -109,7 +109,7 @@ func PreviewConfigVersionHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/config-versions/diff [get]
// @Router /api/v1/d/config-versions/diff [get]
func DiffConfigVersionHandler(c *gin.Context) {
diff, err := DiffConfigVersion(c.Request.Context())
if handleLogicError(c, err) {
@@ -129,7 +129,7 @@ func DiffConfigVersionHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/config-versions/publish [post]
// @Router /api/v1/d/config-versions/publish [post]
func PublishConfigVersionHandler(c *gin.Context) {
username := c.GetString("username")
force := c.Query("force") == "true"
@@ -151,7 +151,7 @@ func PublishConfigVersionHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或版本不存在"
// @Router /api/v1/openflare/config-versions/{id}/activate [post]
// @Router /api/v1/d/config-versions/{id}/activate [post]
func ActivateConfigVersionHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -176,7 +176,7 @@ func ActivateConfigVersionHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/config-versions/cleanup [post]
// @Router /api/v1/d/config-versions/cleanup [post]
func CleanupConfigVersionsHandler(c *gin.Context) {
var input CleanupInput
if !apiutil.BindJSON(c, &input) {
@@ -22,7 +22,7 @@ import (
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/dashboard/overview [get]
// @Router /api/v1/d/dashboard/overview [get]
func GetOverviewHandler(c *gin.Context) {
overview, err := GetOverview(c.Request.Context())
if apiutil.AbortBadRequestOnError(c, err) {
@@ -84,7 +84,7 @@ func TestAgentRelayFlaredProtocol(t *testing.T) {
require.NotEmpty(t, edge.AccessToken)
assert.Equal(t, "edge_node", edge.NodeType)
rec := performJSONRequest(t, engine, http.MethodPost, "/api/agent/nodes/heartbeat", map[string]any{
rec := performJSONRequest(t, engine, http.MethodPost, "/api/v1/agent/nodes/heartbeat", map[string]any{
"name": "edge-1",
"ip": "203.0.113.10",
"version": "0.1.0",
@@ -119,7 +119,7 @@ func TestAgentRelayFlaredProtocol(t *testing.T) {
require.NoError(t, err)
require.NotEmpty(t, relayNode.AccessToken)
rec := performJSONRequest(t, engine, http.MethodPost, "/api/relay/heartbeat", map[string]any{
rec := performJSONRequest(t, engine, http.MethodPost, "/api/v1/relay/heartbeat", map[string]any{
"version": "v0.1.0",
"frp_version": "0.61.0",
"relay_status": "healthy",
@@ -155,7 +155,7 @@ func TestAgentRelayFlaredProtocol(t *testing.T) {
require.NoError(t, err)
require.NotEmpty(t, clientNode.AccessToken)
rec := performJSONRequest(t, engine, http.MethodPost, "/api/flared/heartbeat", map[string]any{
rec := performJSONRequest(t, engine, http.MethodPost, "/api/v1/tunnel/heartbeat", map[string]any{
"client_version": "v0.2.0",
"frp_version": "0.61.0",
"tunnel_status": "running",
@@ -178,7 +178,7 @@ func TestAgentRelayFlaredProtocol(t *testing.T) {
require.NoError(t, err)
require.NotEmpty(t, bootstrap.DiscoveryToken)
rec := performJSONRequest(t, engine, http.MethodPost, "/api/agent/nodes/register", map[string]any{
rec := performJSONRequest(t, engine, http.MethodPost, "/api/v1/agent/nodes/register", map[string]any{
"name": "discovered-edge",
"ip": "203.0.113.30",
"version": "0.2.0",
@@ -209,7 +209,7 @@ func TestAgentRelayFlaredProtocol(t *testing.T) {
})
require.NoError(t, err)
rec := performJSONRequest(t, engine, http.MethodPost, "/api/agent/apply-logs", map[string]any{
rec := performJSONRequest(t, engine, http.MethodPost, "/api/v1/agent/apply-logs", map[string]any{
"version": "20260618-001",
"result": "success",
"message": "apply ok",
@@ -209,7 +209,7 @@ func TestCoreChainMigrationFlow(t *testing.T) {
})
t.Run("create apply log for node", func(t *testing.T) {
rec := performJSONRequest(t, engine, http.MethodPost, "/api/agent/apply-logs", map[string]any{
rec := performJSONRequest(t, engine, http.MethodPost, "/api/v1/agent/apply-logs", map[string]any{
"version": configVersion,
"result": "success",
"message": "config applied",
@@ -83,8 +83,6 @@ func unmarshalEnvelopeSlice(t *testing.T, data any) []any {
func mountOpenFlareTestRoutes(engine *gin.Engine) {
api := engine.Group("/api")
ofrouter.RegisterRoutes(api)
apiV1 := api.Group("/v1")
v1.RegisterV1Routes(apiV1, api)
}
+12 -12
View File
@@ -32,7 +32,7 @@ func handleLogicError(c *gin.Context, err error) bool {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/nodes [get]
// @Router /api/v1/d/nodes [get]
func ListNodesHandler(c *gin.Context) {
nodes, err := ListNodes(c.Request.Context())
if handleLogicError(c, err) {
@@ -53,7 +53,7 @@ func ListNodesHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/nodes [post]
// @Router /api/v1/d/nodes [post]
func CreateNodeHandler(c *gin.Context) {
var input Input
if !apiutil.BindJSON(c, &input) {
@@ -79,7 +79,7 @@ func CreateNodeHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/update [post]
// @Router /api/v1/d/nodes/{id}/update [post]
func UpdateNodeHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -107,7 +107,7 @@ func UpdateNodeHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/delete [post]
// @Router /api/v1/d/nodes/{id}/delete [post]
func DeleteNodeHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -128,7 +128,7 @@ func DeleteNodeHandler(c *gin.Context) {
// @Success 200 {object} response.Any{data=node.BootstrapView} "引导令牌"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/nodes/bootstrap-token [get]
// @Router /api/v1/d/nodes/bootstrap-token [get]
func GetBootstrapTokenHandler(c *gin.Context) {
view, err := GetBootstrapToken(c.Request.Context())
if handleLogicError(c, err) {
@@ -146,7 +146,7 @@ func GetBootstrapTokenHandler(c *gin.Context) {
// @Success 200 {object} response.Any{data=node.BootstrapView} "新引导令牌"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/nodes/bootstrap-token/rotate [post]
// @Router /api/v1/d/nodes/bootstrap-token/rotate [post]
func RotateBootstrapTokenHandler(c *gin.Context) {
view, err := RotateBootstrapToken(c.Request.Context())
if handleLogicError(c, err) {
@@ -167,7 +167,7 @@ func RotateBootstrapTokenHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/agent-release [get]
// @Router /api/v1/d/nodes/{id}/agent-release [get]
func GetAgentReleaseHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -193,7 +193,7 @@ func GetAgentReleaseHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/agent-update [post]
// @Router /api/v1/d/nodes/{id}/agent-update [post]
func RequestAgentUpdateHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -224,7 +224,7 @@ func RequestAgentUpdateHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/openresty-restart [post]
// @Router /api/v1/d/nodes/{id}/openresty-restart [post]
func RequestOpenrestyRestartHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -248,7 +248,7 @@ func RequestOpenrestyRestartHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/force-sync [post]
// @Router /api/v1/d/nodes/{id}/force-sync [post]
func RequestForceSyncHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -274,7 +274,7 @@ func RequestForceSyncHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/observability [get]
// @Router /api/v1/d/nodes/{id}/observability [get]
func GetObservabilityHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -303,7 +303,7 @@ func GetObservabilityHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或节点不存在"
// @Router /api/v1/openflare/nodes/{id}/observability/cleanup [post]
// @Router /api/v1/d/nodes/{id}/observability/cleanup [post]
func CleanupHealthEventsHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -31,7 +31,7 @@ import (
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/access-logs [get]
// @Router /api/v1/d/access-logs [get]
func GetAccessLogsHandler(c *gin.Context) {
logs, err := ListAccessLogs(c.Request.Context(), readAccessLogQuery(c))
if apiutil.AbortBadRequestOnError(c, err) {
@@ -60,7 +60,7 @@ func GetAccessLogsHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/access-logs/folds [get]
// @Router /api/v1/d/access-logs/folds [get]
func GetFoldedAccessLogsHandler(c *gin.Context) {
query := readAccessLogQuery(c)
query.FoldMinutes = readQueryInt(c, "fold_minutes")
@@ -92,7 +92,7 @@ func GetFoldedAccessLogsHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/access-logs/folds/ip-summary [get]
// @Router /api/v1/d/access-logs/folds/ip-summary [get]
func GetFoldedAccessLogIPsHandler(c *gin.Context) {
result, err := ListFoldedAccessLogIPs(c.Request.Context(), FoldedAccessLogIPQuery{
NodeID: c.Query("node_id"),
@@ -130,7 +130,7 @@ func GetFoldedAccessLogIPsHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/access-logs/ip-summary [get]
// @Router /api/v1/d/access-logs/ip-summary [get]
func GetAccessLogIPSummariesHandler(c *gin.Context) {
result, err := ListAccessLogIPSummaries(c.Request.Context(), AccessLogIPSummaryQuery{
NodeID: c.Query("node_id"),
@@ -163,7 +163,7 @@ func GetAccessLogIPSummariesHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/access-logs/ip-summary/trend [get]
// @Router /api/v1/d/access-logs/ip-summary/trend [get]
func GetAccessLogIPTrendHandler(c *gin.Context) {
result, err := GetAccessLogIPTrend(c.Request.Context(), AccessLogIPTrendQuery{
NodeID: c.Query("node_id"),
@@ -191,7 +191,7 @@ func GetAccessLogIPTrendHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/access-logs/cleanup [post]
// @Router /api/v1/d/access-logs/cleanup [post]
func CleanupAccessLogsHandler(c *gin.Context) {
var input AccessLogCleanupInput
if !apiutil.BindJSON(c, &input) {
@@ -23,9 +23,9 @@ import (
// @Success 200 {object} response.Any{data=option.statusView} "公开状态"
// @Failure 400 {object} response.Any "参数错误"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/status [get]
// @Router /api/v1/d/status [get]
func GetStatusHandler(c *gin.Context) {
view, err := getStatus(c.Request.Context(), "/api/v1/openflare")
view, err := getStatus(c.Request.Context(), "/api/v1/d")
if apiutil.AbortBadRequestOnError(c, err) {
return
}
@@ -40,7 +40,7 @@ func GetStatusHandler(c *gin.Context) {
// @Success 200 {object} response.Any{data=string} "系统公告"
// @Failure 400 {object} response.Any "参数错误"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/notice [get]
// @Router /api/v1/d/notice [get]
// GetNoticeHandler returns the notice content.
func GetNoticeHandler(c *gin.Context) {
notice, err := getNotice(c.Request.Context())
@@ -58,7 +58,7 @@ func GetNoticeHandler(c *gin.Context) {
// @Success 200 {object} response.Any{data=string} "关于信息"
// @Failure 400 {object} response.Any "参数错误"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/about [get]
// @Router /api/v1/d/about [get]
// GetAboutHandler returns the about content.
func GetAboutHandler(c *gin.Context) {
about, err := getAbout(c.Request.Context())
@@ -79,7 +79,7 @@ func GetAboutHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/option [get]
// @Router /api/v1/d/option [get]
// ListOptionsHandler lists OpenFlare options.
func ListOptionsHandler(c *gin.Context) {
options, err := listOptions(c.Request.Context())
@@ -102,7 +102,7 @@ func ListOptionsHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/option/update [post]
// @Router /api/v1/d/option/update [post]
// UpdateOptionHandler updates a single option.
func UpdateOptionHandler(c *gin.Context) {
var option model.OpenFlareOption
@@ -128,7 +128,7 @@ func UpdateOptionHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/option/update-batch [post]
// @Router /api/v1/d/option/update-batch [post]
// UpdateOptionsBatchHandler updates options in batch.
func UpdateOptionsBatchHandler(c *gin.Context) {
var payload optionBatchPayload
@@ -154,7 +154,7 @@ func UpdateOptionsBatchHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/option/geoip/lookup [post]
// @Router /api/v1/d/option/geoip/lookup [post]
// LookupGeoIPHandler performs a GeoIP lookup.
func LookupGeoIPHandler(c *gin.Context) {
var request geoIPLookupRequest
@@ -181,7 +181,7 @@ func LookupGeoIPHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/option/database/cleanup [post]
// @Router /api/v1/d/option/database/cleanup [post]
// CleanupDatabaseHandler cleans up observability data.
func CleanupDatabaseHandler(c *gin.Context) {
var input databaseCleanupInput
@@ -208,7 +208,7 @@ func CleanupDatabaseHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/uptimekuma/sync [post]
// @Router /api/v1/d/uptimekuma/sync [post]
// SyncUptimeKumaHandler triggers UptimeKuma sync.
func SyncUptimeKumaHandler(c *gin.Context) {
if apiutil.AbortBadRequestOnError(c, syncUptimeKuma(c.Request.Context())) {
@@ -29,7 +29,7 @@ func handleLogicError(c *gin.Context, err error) bool {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/origins [get]
// @Router /api/v1/d/origins [get]
func GetOrigins(c *gin.Context) {
origins, err := ListOrigins(c.Request.Context())
if handleLogicError(c, err) {
@@ -49,7 +49,7 @@ func GetOrigins(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或源站不存在"
// @Router /api/v1/openflare/origins/{id} [get]
// @Router /api/v1/d/origins/{id} [get]
func GetOrigin(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -74,7 +74,7 @@ func GetOrigin(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/origins [post]
// @Router /api/v1/d/origins [post]
func CreateOriginHandler(c *gin.Context) {
var input Input
if !apiutil.BindJSON(c, &input) {
@@ -100,7 +100,7 @@ func CreateOriginHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或源站不存在"
// @Router /api/v1/openflare/origins/{id}/update [post]
// @Router /api/v1/d/origins/{id}/update [post]
func UpdateOriginHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -128,7 +128,7 @@ func UpdateOriginHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或源站不存在"
// @Router /api/v1/openflare/origins/{id}/delete [post]
// @Router /api/v1/d/origins/{id}/delete [post]
func DeleteOriginHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -45,7 +45,7 @@ func deploymentIDParam(c *gin.Context) (uint, bool) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages [get]
// @Router /api/v1/d/pages [get]
func ListProjectsHandler(c *gin.Context) {
projects, err := ListProjects(c.Request.Context())
if handleLogicError(c, err) {
@@ -67,7 +67,7 @@ func ListProjectsHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id} [get]
// @Router /api/v1/d/pages/{id} [get]
func GetProjectHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -93,7 +93,7 @@ func GetProjectHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages [post]
// @Router /api/v1/d/pages [post]
func CreateProjectHandler(c *gin.Context) {
var input Input
if !apiutil.BindJSON(c, &input) {
@@ -121,7 +121,7 @@ func CreateProjectHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id}/update [post]
// @Router /api/v1/d/pages/{id}/update [post]
func UpdateProjectHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -151,7 +151,7 @@ func UpdateProjectHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id}/delete [post]
// @Router /api/v1/d/pages/{id}/delete [post]
func DeleteProjectHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -176,7 +176,7 @@ func DeleteProjectHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id}/deployments [get]
// @Router /api/v1/d/pages/{id}/deployments [get]
func ListDeploymentsHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -204,7 +204,7 @@ func ListDeploymentsHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id}/deployments/upload [post]
// @Router /api/v1/d/pages/{id}/deployments/upload [post]
func UploadDeploymentHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -236,7 +236,7 @@ func UploadDeploymentHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目或部署不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id}/deployments/{deployment_id}/activate [post]
// @Router /api/v1/d/pages/{id}/deployments/{deployment_id}/activate [post]
func ActivateDeploymentHandler(c *gin.Context) {
projectID, ok := apiutil.IDParam(c)
if !ok {
@@ -267,7 +267,7 @@ func ActivateDeploymentHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "项目或部署不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/{id}/deployments/{deployment_id}/delete [post]
// @Router /api/v1/d/pages/{id}/deployments/{deployment_id}/delete [post]
func DeleteDeploymentHandler(c *gin.Context) {
projectID, ok := apiutil.IDParam(c)
if !ok {
@@ -296,7 +296,7 @@ func DeleteDeploymentHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "部署不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/pages/deployments/{deployment_id}/files [get]
// @Router /api/v1/d/pages/deployments/{deployment_id}/files [get]
func ListDeploymentFilesHandler(c *gin.Context) {
deploymentID, ok := deploymentIDParam(c)
if !ok {
@@ -29,7 +29,7 @@ func handleLogicError(c *gin.Context, err error) bool {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/proxy-routes [get]
// @Router /api/v1/d/proxy-routes [get]
func GetProxyRoutes(c *gin.Context) {
routes, err := ListProxyRoutes(c.Request.Context())
if handleLogicError(c, err) {
@@ -49,7 +49,7 @@ func GetProxyRoutes(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或规则不存在"
// @Router /api/v1/openflare/proxy-routes/{id} [get]
// @Router /api/v1/d/proxy-routes/{id} [get]
func GetProxyRouteHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -74,7 +74,7 @@ func GetProxyRouteHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或不存在"
// @Router /api/v1/openflare/proxy-routes [post]
// @Router /api/v1/d/proxy-routes [post]
func CreateProxyRouteHandler(c *gin.Context) {
var input Input
if !apiutil.BindJSON(c, &input) {
@@ -100,7 +100,7 @@ func CreateProxyRouteHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或规则不存在"
// @Router /api/v1/openflare/proxy-routes/{id}/update [post]
// @Router /api/v1/d/proxy-routes/{id}/update [post]
func UpdateProxyRouteHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -128,7 +128,7 @@ func UpdateProxyRouteHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 404 {object} response.Any "无权限或规则不存在"
// @Router /api/v1/openflare/proxy-routes/{id}/delete [post]
// @Router /api/v1/d/proxy-routes/{id}/delete [post]
func DeleteProxyRouteHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
+21 -21
View File
@@ -31,7 +31,7 @@ func handleLogicError(c *gin.Context, err error) bool {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates [get]
// @Router /api/v1/d/tls-certificates [get]
func GetCertificates(c *gin.Context) {
certificates, err := ListCertificates(c.Request.Context())
if handleLogicError(c, err) {
@@ -53,7 +53,7 @@ func GetCertificates(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id} [get]
// @Router /api/v1/d/tls-certificates/{id} [get]
func GetCertificateDetail(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -79,7 +79,7 @@ func GetCertificateDetail(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id}/content [get]
// @Router /api/v1/d/tls-certificates/{id}/content [get]
func GetCertificateContentHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -105,7 +105,7 @@ func GetCertificateContentHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates [post]
// @Router /api/v1/d/tls-certificates [post]
func CreateCertificateHandler(c *gin.Context) {
var input CertificateInput
if !apiutil.BindJSON(c, &input) {
@@ -133,7 +133,7 @@ func CreateCertificateHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id}/update [post]
// @Router /api/v1/d/tls-certificates/{id}/update [post]
func UpdateCertificateHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -166,7 +166,7 @@ func UpdateCertificateHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/import-file [post]
// @Router /api/v1/d/tls-certificates/import-file [post]
func ImportCertificateFile(c *gin.Context) {
name := c.PostForm("name")
remark := c.PostForm("remark")
@@ -200,7 +200,7 @@ func ImportCertificateFile(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id}/delete [post]
// @Router /api/v1/d/tls-certificates/{id}/delete [post]
func DeleteCertificateHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -225,7 +225,7 @@ func DeleteCertificateHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/apply [post]
// @Router /api/v1/d/tls-certificates/apply [post]
func ApplyCertificateHandler(c *gin.Context) {
var input ApplyInput
if !apiutil.BindJSON(c, &input) {
@@ -253,7 +253,7 @@ func ApplyCertificateHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id}/update-acme [post]
// @Router /api/v1/d/tls-certificates/{id}/update-acme [post]
func UpdateACMECertificateHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -285,7 +285,7 @@ func UpdateACMECertificateHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id}/convert-acme [post]
// @Router /api/v1/d/tls-certificates/{id}/convert-acme [post]
func ConvertCertificateToACMEHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -315,7 +315,7 @@ func ConvertCertificateToACMEHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/tls-certificates/{id}/renew [post]
// @Router /api/v1/d/tls-certificates/{id}/renew [post]
func RenewCertificateHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -339,7 +339,7 @@ func RenewCertificateHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/managed-domains [get]
// @Router /api/v1/d/managed-domains [get]
func GetManagedDomains(c *gin.Context) {
domains, err := ListManagedDomains(c.Request.Context())
if handleLogicError(c, err) {
@@ -361,7 +361,7 @@ func GetManagedDomains(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/managed-domains [post]
// @Router /api/v1/d/managed-domains [post]
func CreateManagedDomainHandler(c *gin.Context) {
var input ManagedDomainInput
if !apiutil.BindJSON(c, &input) {
@@ -389,7 +389,7 @@ func CreateManagedDomainHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/managed-domains/{id}/update [post]
// @Router /api/v1/d/managed-domains/{id}/update [post]
func UpdateManagedDomainHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -419,7 +419,7 @@ func UpdateManagedDomainHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/managed-domains/{id}/delete [post]
// @Router /api/v1/d/managed-domains/{id}/delete [post]
func DeleteManagedDomainHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -443,7 +443,7 @@ func DeleteManagedDomainHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/managed-domains/match [get]
// @Router /api/v1/d/managed-domains/match [get]
func MatchManagedDomainCertificateHandler(c *gin.Context) {
domain := strings.TrimSpace(c.Query("domain"))
result, err := MatchManagedDomainCertificate(c.Request.Context(), domain)
@@ -464,7 +464,7 @@ func MatchManagedDomainCertificateHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/dns-accounts [get]
// @Router /api/v1/d/dns-accounts [get]
func GetDNSAccounts(c *gin.Context) {
accounts, err := ListDNSAccounts(c.Request.Context())
if handleLogicError(c, err) {
@@ -486,7 +486,7 @@ func GetDNSAccounts(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/dns-accounts [post]
// @Router /api/v1/d/dns-accounts [post]
func CreateDNSAccountHandler(c *gin.Context) {
var input DNSAccountInput
if !apiutil.BindJSON(c, &input) {
@@ -514,7 +514,7 @@ func CreateDNSAccountHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/dns-accounts/{id}/update [post]
// @Router /api/v1/d/dns-accounts/{id}/update [post]
func UpdateDNSAccountHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -544,7 +544,7 @@ func UpdateDNSAccountHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/dns-accounts/{id}/delete [post]
// @Router /api/v1/d/dns-accounts/{id}/delete [post]
func DeleteDNSAccountHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -568,7 +568,7 @@ func DeleteDNSAccountHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/acme-accounts/default [get]
// @Router /api/v1/d/acme-accounts/default [get]
func GetDefaultAcmeAccountHandler(c *gin.Context) {
account, err := GetDefaultAcmeAccount(c.Request.Context())
if handleLogicError(c, err) {
@@ -33,7 +33,7 @@ var upgradeLogsUpgrader = websocket.Upgrader{
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/update/latest-release [get]
// @Router /api/v1/d/update/latest-release [get]
func GetLatestReleaseHandler(c *gin.Context) {
release, err := GetLatestRelease(c.Request.Context(), c.Query("channel"))
if apiutil.AbortBadRequestOnError(c, err) {
@@ -55,7 +55,7 @@ func GetLatestReleaseHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/update/upgrade [post]
// @Router /api/v1/d/update/upgrade [post]
func UpgradeServerHandler(c *gin.Context) {
var request upgradeRequest
if err := bindOptionalJSON(c.Request.Body, &request); err != nil {
@@ -82,7 +82,7 @@ func UpgradeServerHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "功能已禁用或参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Router /api/v1/openflare/update/manual-upload [post]
// @Router /api/v1/d/update/manual-upload [post]
func UploadManualServerBinaryHandler(c *gin.Context) {
if apiutil.AbortBadRequestOnError(c, UploadManualBinary()) {
return
@@ -99,7 +99,7 @@ func UploadManualServerBinaryHandler(c *gin.Context) {
// @Failure 400 {object} response.Any "功能已禁用或参数错误"
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Router /api/v1/openflare/update/manual-upgrade [post]
// @Router /api/v1/d/update/manual-upgrade [post]
func ConfirmManualServerUpgradeHandler(c *gin.Context) {
if apiutil.AbortBadRequestOnError(c, ConfirmManualUpgrade()) {
return
@@ -114,7 +114,7 @@ func ConfirmManualServerUpgradeHandler(c *gin.Context) {
// @Success 101 {object} update.StreamSnapshot "WebSocket 升级日志流"
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Router /api/v1/openflare/update/logs/ws [get]
// @Router /api/v1/d/update/logs/ws [get]
func StreamServerUpgradeLogsHandler(c *gin.Context) {
conn, err := upgradeLogsUpgrader.Upgrade(c.Writer, c.Request, nil)
if err != nil {
+15 -15
View File
@@ -45,7 +45,7 @@ func routeIDParam(c *gin.Context) (uint, bool) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/rule-groups [get]
// @Router /api/v1/d/waf/rule-groups [get]
func ListRuleGroupsHandler(c *gin.Context) {
groups, err := ListRuleGroups(c.Request.Context())
if handleLogicError(c, err) {
@@ -67,7 +67,7 @@ func ListRuleGroupsHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/rule-groups/{id} [get]
// @Router /api/v1/d/waf/rule-groups/{id} [get]
func GetRuleGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -93,7 +93,7 @@ func GetRuleGroupHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/rule-groups [post]
// @Router /api/v1/d/waf/rule-groups [post]
func CreateRuleGroupHandler(c *gin.Context) {
var input RuleGroupInput
if !apiutil.BindJSON(c, &input) {
@@ -121,7 +121,7 @@ func CreateRuleGroupHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/rule-groups/{id}/update [post]
// @Router /api/v1/d/waf/rule-groups/{id}/update [post]
func UpdateRuleGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -151,7 +151,7 @@ func UpdateRuleGroupHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/rule-groups/{id}/delete [post]
// @Router /api/v1/d/waf/rule-groups/{id}/delete [post]
func DeleteRuleGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -178,7 +178,7 @@ func DeleteRuleGroupHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/rule-groups/{id}/sites [post]
// @Router /api/v1/d/waf/rule-groups/{id}/sites [post]
func ReplaceRuleGroupSitesHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -208,7 +208,7 @@ func ReplaceRuleGroupSitesHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/sites/{route_id}/rule-groups [get]
// @Router /api/v1/d/waf/sites/{route_id}/rule-groups [get]
func GetSiteRuleGroupsHandler(c *gin.Context) {
routeID, ok := routeIDParam(c)
if !ok {
@@ -236,7 +236,7 @@ func GetSiteRuleGroupsHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/sites/{route_id}/rule-groups [post]
// @Router /api/v1/d/waf/sites/{route_id}/rule-groups [post]
func ReplaceSiteRuleGroupsHandler(c *gin.Context) {
routeID, ok := routeIDParam(c)
if !ok {
@@ -264,7 +264,7 @@ func ReplaceSiteRuleGroupsHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups [get]
// @Router /api/v1/d/waf/ip-groups [get]
func ListIPGroupsHandler(c *gin.Context) {
groups, err := ListIPGroups(c.Request.Context())
if handleLogicError(c, err) {
@@ -286,7 +286,7 @@ func ListIPGroupsHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups/{id} [get]
// @Router /api/v1/d/waf/ip-groups/{id} [get]
func GetIPGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -312,7 +312,7 @@ func GetIPGroupHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups [post]
// @Router /api/v1/d/waf/ip-groups [post]
func CreateIPGroupHandler(c *gin.Context) {
var input IPGroupInput
if !apiutil.BindJSON(c, &input) {
@@ -340,7 +340,7 @@ func CreateIPGroupHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups/{id}/update [post]
// @Router /api/v1/d/waf/ip-groups/{id}/update [post]
func UpdateIPGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -370,7 +370,7 @@ func UpdateIPGroupHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups/{id}/delete [post]
// @Router /api/v1/d/waf/ip-groups/{id}/delete [post]
func DeleteIPGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -395,7 +395,7 @@ func DeleteIPGroupHandler(c *gin.Context) {
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 404 {object} response.Any "记录不存在"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups/{id}/sync [post]
// @Router /api/v1/d/waf/ip-groups/{id}/sync [post]
func SyncIPGroupHandler(c *gin.Context) {
id, ok := apiutil.IDParam(c)
if !ok {
@@ -421,7 +421,7 @@ func SyncIPGroupHandler(c *gin.Context) {
// @Failure 401 {object} response.Any "未登录"
// @Failure 403 {object} response.Any "无管理员权限"
// @Failure 500 {object} response.Any "内部错误"
// @Router /api/v1/openflare/waf/ip-groups/test [post]
// @Router /api/v1/d/waf/ip-groups/test [post]
func TestIPGroupAutoConfigHandler(c *gin.Context) {
var input IPGroupAutoTestInput
if !apiutil.BindJSON(c, &input) {
-5
View File
@@ -18,7 +18,6 @@ import (
"github.com/Rain-kl/Wavelet/internal/apps/risk_control"
router_root "github.com/Rain-kl/Wavelet/internal/router/root"
v1 "github.com/Rain-kl/Wavelet/internal/router/v1"
ofrouter "github.com/Rain-kl/Wavelet/internal/router/v1/openflare"
"github.com/Rain-kl/Wavelet/internal/apps/oauth"
"github.com/Rain-kl/Wavelet/internal/config"
@@ -116,10 +115,6 @@ func registerRoutes(r *gin.Engine) {
apiGroup := r.Group(config.Config.App.APIPrefix)
{
// OpenFlare Agent/Relay/Flared protocol routes under /api/*
ofrouter.RegisterRoutes(apiGroup)
// API V1
apiV1Router := apiGroup.Group("/v1")
{
v1.RegisterV1Routes(apiV1Router, apiGroup)
@@ -2,15 +2,15 @@
// SPDX-License-Identifier: Apache-2.0
// Package openflare registers OpenFlare HTTP routes.
// Management console APIs are mounted via RegisterV1Routes under /api/v1/openflare.
// Agent/Relay/Flared protocol routes are mounted via RegisterRoutes under /api.
// Management console APIs are mounted via RegisterV1Routes under /api/v1/d.
// Agent/Relay/Tunnel protocol routes are mounted via RegisterRoutes under /api/v1.
package openflare
import "github.com/gin-gonic/gin"
// RegisterRoutes mounts Agent/Relay/Flared protocol routes under the /api group.
func RegisterRoutes(apiGroup *gin.RouterGroup) {
registerAgentRoutes(apiGroup)
registerRelayRoutes(apiGroup)
registerFlaredRoutes(apiGroup)
// RegisterRoutes mounts Agent/Relay/Tunnel protocol routes under the /api/v1 group.
func RegisterRoutes(apiV1Router *gin.RouterGroup) {
registerAgentRoutes(apiV1Router)
registerRelayRoutes(apiV1Router)
registerTunnelRoutes(apiV1Router)
}
@@ -8,8 +8,8 @@ import (
"github.com/gin-gonic/gin"
)
func registerAgentRoutes(apiGroup *gin.RouterGroup) {
agentRoute := apiGroup.Group("/agent")
func registerAgentRoutes(apiV1Router *gin.RouterGroup) {
agentRoute := apiV1Router.Group("/agent")
{
discoveryRoute := agentRoute.Group("/")
discoveryRoute.Use(agent.AgentRegisterAuth())
@@ -9,8 +9,8 @@ import (
"github.com/gin-gonic/gin"
)
func registerRelayRoutes(apiGroup *gin.RouterGroup) {
relayRoute := apiGroup.Group("/relay")
func registerRelayRoutes(apiV1Router *gin.RouterGroup) {
relayRoute := apiV1Router.Group("/relay")
relayRoute.Use(relay.RelayAuth())
{
relayRoute.POST("/heartbeat", relay.PostHeartbeat)
@@ -18,13 +18,13 @@ func registerRelayRoutes(apiGroup *gin.RouterGroup) {
}
}
func registerFlaredRoutes(apiGroup *gin.RouterGroup) {
flaredRoute := apiGroup.Group("/flared")
flaredRoute.Use(flared.TunnelAuth())
func registerTunnelRoutes(apiV1Router *gin.RouterGroup) {
tunnelRoute := apiV1Router.Group("/tunnel")
tunnelRoute.Use(flared.TunnelAuth())
{
flaredRoute.POST("/heartbeat", flared.PostHeartbeat)
flaredRoute.GET("/config/active", flared.GetActiveConfig)
flaredRoute.POST("/apply-log", flared.PostApplyLog)
flaredRoute.GET("/ws", flared.GetWebSocket)
tunnelRoute.POST("/heartbeat", flared.PostHeartbeat)
tunnelRoute.GET("/config/active", flared.GetActiveConfig)
tunnelRoute.POST("/apply-log", flared.PostApplyLog)
tunnelRoute.GET("/ws", flared.GetWebSocket)
}
}
+3 -3
View File
@@ -6,11 +6,11 @@ package openflare
import "github.com/gin-gonic/gin"
// V1BasePath is the OpenFlare console API prefix under /api/v1.
const V1BasePath = "/api/v1/openflare"
const V1BasePath = "/api/v1/d"
// RegisterV1Routes mounts OpenFlare management console APIs under /api/v1/openflare.
// RegisterV1Routes mounts OpenFlare management console APIs under /api/v1/d.
func RegisterV1Routes(apiV1Router *gin.RouterGroup) {
group := apiV1Router.Group("/openflare")
group := apiV1Router.Group("/d")
registerOptionRoutes(group)
registerOriginRoutes(group)
registerApplyLogRoutes(group)
+2 -1
View File
@@ -17,8 +17,9 @@ func RegisterV1Routes(apiV1Router *gin.RouterGroup, apiGroup *gin.RouterGroup) {
// 2. Admin routes
RegisterAdminRoutes(apiV1Router)
// 3. OpenFlare management console APIs
// 3. OpenFlare management console APIs and Agent/Relay/Tunnel protocol routes
ofrouter.RegisterV1Routes(apiV1Router)
ofrouter.RegisterRoutes(apiV1Router)
// 4. Custom business routes (example only)
RegisterCustomRoutes(apiV1Router)
+4
View File
@@ -16,6 +16,10 @@ sidebar: false
## [Unreleased]
### 变更
- Wavelet API 路径统一:管理端由 `/api/v1/openflare/*` 调整为 `/api/v1/d/*`;Agent/Relay/Tunnel 协议路由分别迁移至 `/api/v1/agent/*`、`/api/v1/relay/*`、`/api/v1/tunnel/*`(原 `/api/flared/*`)。同步更新 Wavelet 前端服务层与 `openflare-agent`、`openflare-relay`、`openflared` 客户端连接端点。
### 新增
- Wavelet 总览仪表盘图表对齐旧前端 ECharts 样式:24 小时请求/容量趋势补充请求量与错误量展示,新增网络与磁盘趋势、Top 节点榜单、来源分布、状态码分布与 Top Domain 板块。
@@ -156,7 +156,7 @@ type fakeWebSocketConnection struct {
}
func (f *fakeWebSocketConnection) URL() string {
return "ws://127.0.0.1/api/agent/ws"
return "ws://127.0.0.1/api/v1/agent/ws"
}
func (f *fakeWebSocketConnection) SendStatus(payload protocol.NodePayload) error {
@@ -34,7 +34,7 @@ func New(baseURL string, token string, timeout time.Duration) *Client {
func (c *Client) RegisterNode(ctx context.Context, payload protocol.NodePayload) (*protocol.RegisterNodeResponse, error) {
slog.Debug("http register node request", "node_id", payload.NodeID, "current_version", payload.CurrentVersion)
resp := protocol.APIResponse[protocol.RegisterNodeResponse]{}
if err := c.postJSON(ctx, "/api/agent/nodes/register", payload, &resp); err != nil {
if err := c.postJSON(ctx, "/api/v1/agent/nodes/register", payload, &resp); err != nil {
return nil, err
}
if !resp.Success {
@@ -46,7 +46,7 @@ func (c *Client) RegisterNode(ctx context.Context, payload protocol.NodePayload)
func (c *Client) Heartbeat(ctx context.Context, payload protocol.NodePayload) (*protocol.HeartbeatResult, error) {
resp := protocol.HeartbeatAPIResponse{}
if err := c.postJSON(ctx, "/api/agent/nodes/heartbeat", payload, &resp); err != nil {
if err := c.postJSON(ctx, "/api/v1/agent/nodes/heartbeat", payload, &resp); err != nil {
return nil, err
}
if !resp.Success {
@@ -61,7 +61,7 @@ func (c *Client) Heartbeat(ctx context.Context, payload protocol.NodePayload) (*
func (c *Client) GetActiveConfig(ctx context.Context) (*protocol.ActiveConfigResponse, error) {
resp := protocol.APIResponse[protocol.ActiveConfigResponse]{}
if err := c.getJSON(ctx, "/api/agent/config-versions/active", &resp); err != nil {
if err := c.getJSON(ctx, "/api/v1/agent/config-versions/active", &resp); err != nil {
return nil, err
}
if !resp.Success {
@@ -73,12 +73,12 @@ func (c *Client) GetActiveConfig(ctx context.Context) (*protocol.ActiveConfigRes
func (c *Client) ReportApplyLog(ctx context.Context, payload protocol.ApplyLogPayload) error {
slog.Debug("http report apply log request", "node_id", payload.NodeID, "version", payload.Version, "result", payload.Result)
return c.postJSON(ctx, "/api/agent/apply-logs", payload, nil)
return c.postJSON(ctx, "/api/v1/agent/apply-logs", payload, nil)
}
func (c *Client) SyncWAFIPGroups(ctx context.Context, payload protocol.WAFIPGroupSyncRequest) (*protocol.WAFIPGroupSyncResponse, error) {
resp := protocol.APIResponse[protocol.WAFIPGroupSyncResponse]{}
if err := c.postJSON(ctx, "/api/agent/waf/ip-groups/sync", payload, &resp); err != nil {
if err := c.postJSON(ctx, "/api/v1/agent/waf/ip-groups/sync", payload, &resp); err != nil {
return nil, err
}
if !resp.Success {
@@ -88,7 +88,7 @@ func (c *Client) SyncWAFIPGroups(ctx context.Context, payload protocol.WAFIPGrou
}
func (c *Client) DownloadPagesDeploymentPackage(ctx context.Context, deploymentID uint) ([]byte, error) {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+fmt.Sprintf("/api/agent/pages/deployments/%d/package", deploymentID), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL+fmt.Sprintf("/api/v1/agent/pages/deployments/%d/package", deploymentID), nil)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -26,7 +26,7 @@ func New(baseURL string, token string, timeout time.Duration) *Client {
Token: token,
Timeout: timeout,
HeaderKey: "X-Agent-Token",
WSPath: "/api/agent/ws",
WSPath: "/api/v1/agent/ws",
}),
}
}
@@ -38,7 +38,7 @@ func New(baseURL string, token string, timeout time.Duration) *Client {
func (c *Client) Heartbeat(ctx context.Context, payload service.RelayHeartbeatPayload) (*service.RelayHeartbeatResponse, error) {
resp := APIResponse[service.RelayHeartbeatResponse]{}
if err := c.postJSON(ctx, "/api/relay/heartbeat", payload, &resp); err != nil {
if err := c.postJSON(ctx, "/api/v1/relay/heartbeat", payload, &resp); err != nil {
return nil, err
}
if !resp.Success {
+1 -1
View File
@@ -27,7 +27,7 @@ func New(baseURL string, token string, timeout time.Duration) *Client {
Token: token,
Timeout: timeout,
HeaderKey: "X-Agent-Token",
WSPath: "/api/relay/ws",
WSPath: "/api/v1/relay/ws",
}),
}
}
+3 -3
View File
@@ -38,7 +38,7 @@ func New(baseURL string, token string, timeout time.Duration) *Client {
func (c *Client) Heartbeat(ctx context.Context, payload service.FlaredHeartbeatPayload) (*service.FlaredHeartbeatResponse, error) {
resp := APIResponse[service.FlaredHeartbeatResponse]{}
if err := c.postJSON(ctx, "/api/flared/heartbeat", payload, &resp); err != nil {
if err := c.postJSON(ctx, "/api/v1/tunnel/heartbeat", payload, &resp); err != nil {
return nil, err
}
if !resp.Success {
@@ -49,7 +49,7 @@ func (c *Client) Heartbeat(ctx context.Context, payload service.FlaredHeartbeatP
func (c *Client) GetActiveConfig(ctx context.Context) (*service.FlaredTunnelConfigResponse, error) {
resp := APIResponse[service.FlaredTunnelConfigResponse]{}
if err := c.getJSON(ctx, "/api/flared/config/active", &resp); err != nil {
if err := c.getJSON(ctx, "/api/v1/tunnel/config/active", &resp); err != nil {
return nil, err
}
if !resp.Success {
@@ -60,7 +60,7 @@ func (c *Client) GetActiveConfig(ctx context.Context) (*service.FlaredTunnelConf
func (c *Client) ReportApplyLog(ctx context.Context, payload service.ApplyLogPayload) error {
resp := APIResponse[any]{}
if err := c.postJSON(ctx, "/api/flared/apply-log", payload, &resp); err != nil {
if err := c.postJSON(ctx, "/api/v1/tunnel/apply-log", payload, &resp); err != nil {
return err
}
if !resp.Success {
+1 -1
View File
@@ -27,7 +27,7 @@ func New(baseURL string, token string, timeout time.Duration) *Client {
Token: token,
Timeout: timeout,
HeaderKey: "X-Tunnel-Token",
WSPath: "/api/flared/ws",
WSPath: "/api/v1/tunnel/ws",
}),
}
}