// Package docs provides API documentation using Swagger/OpenAPI package docs import ( "encoding/json" "net/http" ) // SwaggerInfo holds the API information var SwaggerInfo = struct { Title string Description string Version string Host string BasePath string Schemes []string }{ Title: "OTPM API", Description: "API for One-Time Password Manager", Version: "1.0.0", Host: "localhost:8080", BasePath: "/", Schemes: []string{"http", "https"}, } // SwaggerJSON returns the Swagger JSON func SwaggerJSON() []byte { swagger := map[string]interface{}{ "swagger": "2.0", "info": map[string]interface{}{ "title": SwaggerInfo.Title, "description": SwaggerInfo.Description, "version": SwaggerInfo.Version, }, "host": SwaggerInfo.Host, "basePath": SwaggerInfo.BasePath, "schemes": SwaggerInfo.Schemes, "paths": getPaths(), "definitions": map[string]interface{}{ "LoginRequest": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "code": map[string]interface{}{ "type": "string", "description": "WeChat authorization code", }, }, "required": []string{"code"}, }, "LoginResponse": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "token": map[string]interface{}{ "type": "string", "description": "JWT token", }, "openid": map[string]interface{}{ "type": "string", "description": "WeChat OpenID", }, }, }, "CreateOTPRequest": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "name": map[string]interface{}{ "type": "string", "description": "OTP name", }, "issuer": map[string]interface{}{ "type": "string", "description": "OTP issuer", }, "secret": map[string]interface{}{ "type": "string", "description": "OTP secret", }, "algorithm": map[string]interface{}{ "type": "string", "description": "OTP algorithm", "enum": []string{"SHA1", "SHA256", "SHA512"}, }, "digits": map[string]interface{}{ "type": "integer", "description": "OTP digits", "enum": []int{6, 8}, }, "period": map[string]interface{}{ "type": "integer", "description": "OTP period in seconds", "enum": []int{30, 60}, }, }, "required": []string{"name", "issuer", "secret", "algorithm", "digits", "period"}, }, "OTP": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "id": map[string]interface{}{ "type": "string", "description": "OTP ID", }, "user_id": map[string]interface{}{ "type": "string", "description": "User ID", }, "name": map[string]interface{}{ "type": "string", "description": "OTP name", }, "issuer": map[string]interface{}{ "type": "string", "description": "OTP issuer", }, "algorithm": map[string]interface{}{ "type": "string", "description": "OTP algorithm", }, "digits": map[string]interface{}{ "type": "integer", "description": "OTP digits", }, "period": map[string]interface{}{ "type": "integer", "description": "OTP period in seconds", }, "created_at": map[string]interface{}{ "type": "string", "format": "date-time", "description": "Creation time", }, "updated_at": map[string]interface{}{ "type": "string", "format": "date-time", "description": "Last update time", }, }, }, "OTPCodeResponse": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "code": map[string]interface{}{ "type": "string", "description": "OTP code", }, "expires_in": map[string]interface{}{ "type": "integer", "description": "Seconds until expiration", }, }, }, "VerifyOTPRequest": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "code": map[string]interface{}{ "type": "string", "description": "OTP code to verify", }, }, "required": []string{"code"}, }, "VerifyOTPResponse": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "valid": map[string]interface{}{ "type": "boolean", "description": "Whether the code is valid", }, }, }, "UpdateOTPRequest": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "name": map[string]interface{}{ "type": "string", "description": "OTP name", }, "issuer": map[string]interface{}{ "type": "string", "description": "OTP issuer", }, "algorithm": map[string]interface{}{ "type": "string", "description": "OTP algorithm", "enum": []string{"SHA1", "SHA256", "SHA512"}, }, "digits": map[string]interface{}{ "type": "integer", "description": "OTP digits", "enum": []int{6, 8}, }, "period": map[string]interface{}{ "type": "integer", "description": "OTP period in seconds", "enum": []int{30, 60}, }, }, }, "ErrorResponse": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "code": map[string]interface{}{ "type": "integer", "description": "Error code", }, "message": map[string]interface{}{ "type": "string", "description": "Error message", }, }, }, }, "securityDefinitions": map[string]interface{}{ "Bearer": map[string]interface{}{ "type": "apiKey", "name": "Authorization", "in": "header", "description": "JWT token with Bearer prefix", }, }, } data, _ := json.MarshalIndent(swagger, "", " ") return data } // getPaths returns the API paths func getPaths() map[string]interface{} { return map[string]interface{}{ "/login": map[string]interface{}{ "post": map[string]interface{}{ "summary": "Login with WeChat", "description": "Login with WeChat authorization code", "tags": []string{"auth"}, "parameters": []map[string]interface{}{ { "name": "body", "in": "body", "description": "Login request", "required": true, "schema": map[string]interface{}{ "$ref": "#/definitions/LoginRequest", }, }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "Successful login", "schema": map[string]interface{}{ "$ref": "#/definitions/LoginResponse", }, }, "400": map[string]interface{}{ "description": "Invalid request", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, }, "/verify-token": map[string]interface{}{ "post": map[string]interface{}{ "summary": "Verify token", "description": "Verify JWT token", "tags": []string{"auth"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "Token is valid", "schema": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "valid": map[string]interface{}{ "type": "boolean", "description": "Whether the token is valid", }, }, }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, }, "/otp": map[string]interface{}{ "get": map[string]interface{}{ "summary": "List OTPs", "description": "List all OTPs for the authenticated user", "tags": []string{"otp"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "List of OTPs", "schema": map[string]interface{}{ "type": "array", "items": map[string]interface{}{ "$ref": "#/definitions/OTP", }, }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, "post": map[string]interface{}{ "summary": "Create OTP", "description": "Create a new OTP", "tags": []string{"otp"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "parameters": []map[string]interface{}{ { "name": "body", "in": "body", "description": "OTP creation request", "required": true, "schema": map[string]interface{}{ "$ref": "#/definitions/CreateOTPRequest", }, }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "OTP created", "schema": map[string]interface{}{ "$ref": "#/definitions/OTP", }, }, "400": map[string]interface{}{ "description": "Invalid request", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, }, "/otp/{id}": map[string]interface{}{ "put": map[string]interface{}{ "summary": "Update OTP", "description": "Update an existing OTP", "tags": []string{"otp"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "parameters": []map[string]interface{}{ { "name": "id", "in": "path", "description": "OTP ID", "required": true, "type": "string", }, { "name": "body", "in": "body", "description": "OTP update request", "required": true, "schema": map[string]interface{}{ "$ref": "#/definitions/UpdateOTPRequest", }, }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "OTP updated", "schema": map[string]interface{}{ "$ref": "#/definitions/OTP", }, }, "400": map[string]interface{}{ "description": "Invalid request", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "404": map[string]interface{}{ "description": "OTP not found", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, "delete": map[string]interface{}{ "summary": "Delete OTP", "description": "Delete an existing OTP", "tags": []string{"otp"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "parameters": []map[string]interface{}{ { "name": "id", "in": "path", "description": "OTP ID", "required": true, "type": "string", }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "OTP deleted", "schema": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "message": map[string]interface{}{ "type": "string", "description": "Success message", }, }, }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "404": map[string]interface{}{ "description": "OTP not found", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, }, "/otp/{id}/code": map[string]interface{}{ "get": map[string]interface{}{ "summary": "Get OTP code", "description": "Get the current OTP code", "tags": []string{"otp"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "parameters": []map[string]interface{}{ { "name": "id", "in": "path", "description": "OTP ID", "required": true, "type": "string", }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "OTP code", "schema": map[string]interface{}{ "$ref": "#/definitions/OTPCodeResponse", }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "404": map[string]interface{}{ "description": "OTP not found", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, }, "/otp/{id}/verify": map[string]interface{}{ "post": map[string]interface{}{ "summary": "Verify OTP code", "description": "Verify an OTP code", "tags": []string{"otp"}, "security": []map[string]interface{}{ { "Bearer": []string{}, }, }, "parameters": []map[string]interface{}{ { "name": "id", "in": "path", "description": "OTP ID", "required": true, "type": "string", }, { "name": "body", "in": "body", "description": "OTP verification request", "required": true, "schema": map[string]interface{}{ "$ref": "#/definitions/VerifyOTPRequest", }, }, }, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "OTP verification result", "schema": map[string]interface{}{ "$ref": "#/definitions/VerifyOTPResponse", }, }, "400": map[string]interface{}{ "description": "Invalid request", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "401": map[string]interface{}{ "description": "Unauthorized", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "404": map[string]interface{}{ "description": "OTP not found", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, "500": map[string]interface{}{ "description": "Internal server error", "schema": map[string]interface{}{ "$ref": "#/definitions/ErrorResponse", }, }, }, }, }, "/health": map[string]interface{}{ "get": map[string]interface{}{ "summary": "Health check", "description": "Check if the API is healthy", "tags": []string{"system"}, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "API is healthy", "schema": map[string]interface{}{ "type": "object", "properties": map[string]interface{}{ "status": map[string]interface{}{ "type": "string", "description": "Health status", }, "time": map[string]interface{}{ "type": "string", "format": "date-time", "description": "Current time", }, }, }, }, }, }, }, "/metrics": map[string]interface{}{ "get": map[string]interface{}{ "summary": "Metrics", "description": "Get application metrics", "tags": []string{"system"}, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "Application metrics", }, }, }, }, "/swagger.json": map[string]interface{}{ "get": map[string]interface{}{ "summary": "Swagger JSON", "description": "Get Swagger JSON", "tags": []string{"system"}, "responses": map[string]interface{}{ "200": map[string]interface{}{ "description": "Swagger JSON", }, }, }, }, } } // Handler returns an HTTP handler for Swagger JSON func Handler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json") w.Write(SwaggerJSON()) } }