diff --git a/README.md b/README.md index f6aeaa86..776b2d11 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,7 @@ docker compose -f docker-compose.yaml up -d ``` (또는 한번에 실행: `docker compose -f compose.infra.yaml -f compose.ory.yaml -f docker-compose.yaml up -d`) -- **userfront**: http://localhost:5000 접속 +- **gateway (UserFront 프록시)**: http://localhost:5000 접속 - **backend**: http://localhost:3000 (API) - **ClickHouse**: http://localhost:8123 - **Kratos Public**: http://localhost:4433 @@ -283,6 +283,7 @@ baron_sso/ ├── adminfront/ # React 기반 관리 │ ├── src/ # UI 및 로직 │ └── pubspec.yaml +├── gateway/ # Nginx 기반 Gateway (UserFront 프록시) ├── compose.ory-stack.yaml # DB 서비스 (Postgres, ClickHouse) ├── compose.infra.yaml # DB 서비스 (Postgres, ClickHouse) ├── docker-compose.yaml # 앱 서비스 (Front, Back) diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index 055a44bb..1a835f59 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -39,6 +39,45 @@ func getEnv(key, fallback string) string { return fallback } +func normalizeDocsPrefix(prefix string) string { + trimmed := strings.TrimSpace(prefix) + if trimmed == "" || trimmed == "/" { + return "" + } + if !strings.HasPrefix(trimmed, "/") { + trimmed = "/" + trimmed + } + return strings.TrimRight(trimmed, "/") +} + +func registerDocsRoutes(app *fiber.App, prefix string) { + base := normalizeDocsPrefix(prefix) + docsPath := base + "/docs" + redocPath := base + "/redoc" + openapiPath := base + "/openapi.yaml" + + app.Get(docsPath, func(c *fiber.Ctx) error { + return c.SendFile("./docs/swagger-ui/index.html") + }) + app.Get(docsPath+"/", func(c *fiber.Ctx) error { + return c.SendFile("./docs/swagger-ui/index.html") + }) + app.Static(docsPath, "./docs/swagger-ui") + + app.Get(redocPath, func(c *fiber.Ctx) error { + return c.SendFile("./docs/redoc/index.html") + }) + app.Get(redocPath+"/", func(c *fiber.Ctx) error { + return c.SendFile("./docs/redoc/index.html") + }) + app.Static(redocPath, "./docs/redoc") + + app.Get(openapiPath, func(c *fiber.Ctx) error { + c.Type("yaml") + return c.SendFile("./docs/openapi.yaml") + }) +} + func main() { // Load .env file from possible paths // 1. .env (Current Directory) @@ -304,25 +343,12 @@ func main() { // [Security] Disable Swagger/ReDoc in Production if appEnv != "production" { - app.Get("/docs", func(c *fiber.Ctx) error { - return c.SendFile("./docs/swagger-ui/index.html") - }) - app.Get("/docs/", func(c *fiber.Ctx) error { - return c.SendFile("./docs/swagger-ui/index.html") - }) - app.Static("/docs", "./docs/swagger-ui") - app.Get("/redoc", func(c *fiber.Ctx) error { - return c.SendFile("./docs/redoc/index.html") - }) - app.Get("/redoc/", func(c *fiber.Ctx) error { - return c.SendFile("./docs/redoc/index.html") - }) - app.Static("/redoc", "./docs/redoc") - app.Get("/openapi.yaml", func(c *fiber.Ctx) error { - c.Type("yaml") - return c.SendFile("./docs/openapi.yaml") - }) - slog.Info("📚 API Docs enabled", "swagger", "/docs", "redoc", "/redoc") + docsPrefix := getEnv("DOCS_BASE_PATH", "/api") + registerDocsRoutes(app, "") + if normalized := normalizeDocsPrefix(docsPrefix); normalized != "" { + registerDocsRoutes(app, normalized) + } + slog.Info("📚 API Docs enabled", "swagger", "/docs", "redoc", "/redoc", "docs_prefix", docsPrefix) } else { slog.Info("🔒 API Docs disabled in production") } diff --git a/backend/docs/openapi.yaml b/backend/docs/openapi.yaml index e227460d..c5e191a5 100644 --- a/backend/docs/openapi.yaml +++ b/backend/docs/openapi.yaml @@ -470,6 +470,24 @@ paths: schema: $ref: "#/components/schemas/MessageResponse" + /api/v1/user/rp/linked: + get: + tags: [User] + summary: 연동된 RP 목록 조회 + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/LinkedRpListResponse" + "401": + description: Unauthorized + content: + application/json: + schema: + $ref: "#/components/schemas/ErrorResponse" + /api/v1/sessions: get: tags: [Session] @@ -1117,6 +1135,32 @@ components: code: type: string + LinkedRpSummary: + type: object + properties: + id: + type: string + name: + type: string + logo: + type: string + lastAuthenticatedAt: + type: string + status: + type: string + scopes: + type: array + items: + type: string + + LinkedRpListResponse: + type: object + properties: + items: + type: array + items: + $ref: "#/components/schemas/LinkedRpSummary" + SessionSummary: type: object properties: diff --git a/backend/docs/redoc/index.html b/backend/docs/redoc/index.html index 5d08e07d..489906ae 100644 --- a/backend/docs/redoc/index.html +++ b/backend/docs/redoc/index.html @@ -12,7 +12,26 @@
-