diff --git a/auth/docs/docs.go b/auth/docs/docs.go index b220190e..8b6b4925 100644 --- a/auth/docs/docs.go +++ b/auth/docs/docs.go @@ -42,6 +42,26 @@ const docTemplate = `{ } } }, + "/info": { + "get": { + "description": "List keibi's settings (oidc providers, public url...)", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "Auth info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/main.ServerInfo" + } + } + } + } + }, "/jwt": { "get": { "security": [ @@ -199,7 +219,252 @@ const docTemplate = `{ } } }, + "/oidc/callback/{provider}": { + "get": { + "description": "Exchange an opaque OIDC token for a local session.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC callback", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Opaque token returned by /oidc/logged/:provider", + "name": "token", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Optional tenant passthrough for federated setups", + "name": "tenant", + "in": "query" + }, + { + "type": "string", + "description": "Bearer token to link provider to current account", + "name": "Authorization", + "in": "header" + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/main.SessionWToken" + } + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "410": { + "description": "Login token expired or already used", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, + "/oidc/logged/{provider}": { + "get": { + "description": "Callback endpoint called by OIDC providers after login.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC logged callback", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "State value returned by the provider", + "name": "state", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Authorization code", + "name": "code", + "in": "query" + }, + { + "type": "string", + "description": "Provider callback error", + "name": "error", + "in": "query" + } + ], + "responses": { + "302": { + "description": "Found" + }, + "400": { + "description": "Invalid state", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, + "/oidc/login/{provider}": { + "get": { + "description": "Start an OIDC login with a provider.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC login", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "URL to redirect the browser to after provider callback", + "name": "redirectUrl", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Optional tenant passthrough for federated setups", + "name": "tenant", + "in": "query" + } + ], + "responses": { + "302": { + "description": "Found" + }, + "400": { + "description": "Missing redirectUrl", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, + "delete": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Remove an OIDC provider from the current account.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC unlink provider", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, "/sessions": { + "get": { + "security": [ + { + "Jwt": [] + } + ], + "description": "List all active sessions for the currently connected user", + "produces": [ + "application/json" + ], + "tags": [ + "sessions" + ], + "summary": "List my sessions", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/main.SessionWCurrent" + } + } + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, "post": { "description": "Login to your account and open a session", "consumes": [ @@ -374,7 +639,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.Page-main_User" + "$ref": "#/definitions/main.Page-models_User" } }, "422": { @@ -410,7 +675,7 @@ const docTemplate = `{ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.RegisterDto" + "$ref": "#/definitions/models.RegisterDto" } } ], @@ -421,6 +686,12 @@ const docTemplate = `{ "$ref": "#/definitions/main.SessionWToken" } }, + "403": { + "description": "Registrations are disabled", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, "409": { "description": "Duplicated email or username", "schema": { @@ -455,7 +726,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "401": { @@ -493,7 +764,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } } } @@ -521,7 +792,7 @@ const docTemplate = `{ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.EditUserDto" + "$ref": "#/definitions/models.EditUserDto" } } ], @@ -529,7 +800,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "403": { @@ -547,6 +818,137 @@ const docTemplate = `{ } } }, + "/users/me/logo": { + "get": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Get the current user's logo (manual upload if available, gravatar otherwise)", + "produces": [ + "image/*" + ], + "tags": [ + "users" + ], + "summary": "Get my logo", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "No gravatar image found for this user", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, + "post": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Upload a manual profile picture for the current user", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "users" + ], + "summary": "Upload my logo", + "parameters": [ + { + "type": "file", + "description": "Profile picture image (jpeg/png/gif/webp, max 5MB)", + "name": "logo", + "in": "formData", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "413": { + "description": "File too large", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "422": { + "description": "Missing or invalid logo file", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, + "delete": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Delete the current user's manually uploaded profile picture", + "produces": [ + "application/json" + ], + "tags": [ + "users" + ], + "summary": "Delete my logo", + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, "/users/me/password": { "patch": { "security": [ @@ -578,7 +980,7 @@ const docTemplate = `{ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.EditPasswordDto" + "$ref": "#/definitions/models.EditPasswordDto" } } ], @@ -595,6 +997,49 @@ const docTemplate = `{ } } }, + "/users/me/{id}": { + "delete": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Delete the user's manually uploaded profile picture", + "produces": [ + "application/json" + ], + "tags": [ + "users" + ], + "summary": "Delete user logo", + "parameters": [ + { + "type": "string", + "description": "The id or username of the user", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, "/users/{id}": { "get": { "security": [ @@ -626,7 +1071,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "404": { @@ -675,7 +1120,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "404": { @@ -724,7 +1169,7 @@ const docTemplate = `{ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.EditUserDto" + "$ref": "#/definitions/models.EditUserDto" } } ], @@ -732,7 +1177,7 @@ const docTemplate = `{ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "403": { @@ -749,6 +1194,104 @@ const docTemplate = `{ } } } + }, + "/users/{id}/logo": { + "get": { + "security": [ + { + "Jwt": [ + "users.read" + ] + } + ], + "description": "Get a user's logo (manual upload if available, gravatar otherwise)", + "produces": [ + "image/*" + ], + "tags": [ + "users" + ], + "summary": "Get user logo", + "parameters": [ + { + "type": "string", + "description": "The id or username of the user", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "404": { + "description": "No gravatar image found for this user", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, + "/users/{id}/sessions": { + "get": { + "security": [ + { + "Jwt": [] + } + ], + "description": "List all active sessions for a user. Listing someone else's sessions requires users.read.", + "produces": [ + "application/json" + ], + "tags": [ + "sessions" + ], + "summary": "List user sessions", + "parameters": [ + { + "type": "string", + "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397", + "description": "The id or username of the user", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/main.Session" + } + } + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Missing permissions: users.read.", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "No user found with id or username", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } } }, "definitions": { @@ -834,40 +1377,6 @@ const docTemplate = `{ } } }, - "main.EditPasswordDto": { - "type": "object", - "required": [ - "password" - ], - "properties": { - "password": { - "type": "string", - "example": "password1234" - } - } - }, - "main.EditUserDto": { - "type": "object", - "properties": { - "claims": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "example": { - "preferOriginal": " true" - } - }, - "email": { - "type": "string", - "example": "kyoo@zoriya.dev" - }, - "username": { - "type": "string", - "example": "zoriya" - } - } - }, "main.JwkSet": { "type": "object", "properties": { @@ -949,24 +1458,14 @@ const docTemplate = `{ } } }, - "main.OidcHandle": { + "main.OidcInfo": { "type": "object", "properties": { - "id": { - "description": "Id of this oidc handle.", - "type": "string", - "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397" + "logo": { + "type": "string" }, - "profileUrl": { - "description": "Link to the profile of the user on the external service. Null if unknown or irrelevant.", - "type": "string", - "format": "url", - "example": "https://myanimelist.net/profile/zoriya" - }, - "username": { - "description": "Username of the user on the external service.", - "type": "string", - "example": "zoriya" + "name": { + "type": "string" } } }, @@ -989,13 +1488,13 @@ const docTemplate = `{ } } }, - "main.Page-main_User": { + "main.Page-models_User": { "type": "object", "properties": { "items": { "type": "array", "items": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "next": { @@ -1008,29 +1507,20 @@ const docTemplate = `{ } } }, - "main.RegisterDto": { + "main.ServerInfo": { "type": "object", - "required": [ - "email", - "password", - "username" - ], "properties": { - "email": { - "description": "Valid email that could be used for forgotten password requests. Can be used for login.", - "type": "string", - "format": "email", - "example": "kyoo@zoriya.dev" + "allowRegister": { + "type": "boolean" }, - "password": { - "description": "Password to use.", - "type": "string", - "example": "password1234" + "oidc": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/main.OidcInfo" + } }, - "username": { - "description": "Username of the new account, can't contain @ signs. Can be used for login.", - "type": "string", - "example": "zoriya" + "publicUrl": { + "type": "string" } } }, @@ -1059,6 +1549,34 @@ const docTemplate = `{ } } }, + "main.SessionWCurrent": { + "type": "object", + "properties": { + "createdDate": { + "description": "When was the session first opened", + "type": "string", + "example": "2025-03-29T18:20:05.267Z" + }, + "current": { + "type": "boolean" + }, + "device": { + "description": "Device that created the session.", + "type": "string", + "example": "Web - Firefox" + }, + "id": { + "description": "Unique id of this session. Can be used for calls to DELETE", + "type": "string", + "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397" + }, + "lastUsed": { + "description": "Last date this session was used to access a service.", + "type": "string", + "example": "2025-03-29T18:20:05.267Z" + } + } + }, "main.SessionWToken": { "type": "object", "properties": { @@ -1088,7 +1606,92 @@ const docTemplate = `{ } } }, - "main.User": { + "models.EditPasswordDto": { + "type": "object", + "required": [ + "newPassword" + ], + "properties": { + "newPassword": { + "type": "string", + "example": "password1234" + }, + "oldPassword": { + "type": "string", + "example": "password1234" + } + } + }, + "models.EditUserDto": { + "type": "object", + "properties": { + "claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "example": { + "preferOriginal": " true" + } + }, + "email": { + "type": "string", + "example": "kyoo@zoriya.dev" + }, + "username": { + "type": "string", + "example": "zoriya" + } + } + }, + "models.OidcHandle": { + "type": "object", + "properties": { + "id": { + "description": "Id of this oidc handle.", + "type": "string", + "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397" + }, + "profileUrl": { + "description": "Link to the profile of the user on the external service. Null if unknown or irrelevant.", + "type": "string", + "format": "url", + "example": "https://myanimelist.net/profile/zoriya" + }, + "username": { + "description": "Username of the user on the external service.", + "type": "string", + "example": "zoriya" + } + } + }, + "models.RegisterDto": { + "type": "object", + "required": [ + "email", + "password", + "username" + ], + "properties": { + "email": { + "description": "Valid email that could be used for forgotten password requests. Can be used for login.", + "type": "string", + "format": "email", + "example": "kyoo@zoriya.dev" + }, + "password": { + "description": "Password to use.", + "type": "string", + "example": "password1234" + }, + "username": { + "description": "Username of the new account, can't contain @ signs. Can be used for login.", + "type": "string", + "example": "zoriya" + } + } + }, + "models.User": { "type": "object", "properties": { "claims": { @@ -1112,6 +1715,10 @@ const docTemplate = `{ "format": "email", "example": "kyoo@zoriya.dev" }, + "hasPassword": { + "description": "False if the user has never setup a password and only used oidc.", + "type": "boolean" + }, "id": { "description": "Id of the user.", "type": "string", @@ -1126,7 +1733,7 @@ const docTemplate = `{ "description": "List of other login method available for this user. Access tokens wont be returned here.", "type": "object", "additionalProperties": { - "$ref": "#/definitions/main.OidcHandle" + "$ref": "#/definitions/models.OidcHandle" } }, "username": { diff --git a/auth/docs/swagger.json b/auth/docs/swagger.json index fb41edc9..6bb6c614 100644 --- a/auth/docs/swagger.json +++ b/auth/docs/swagger.json @@ -36,6 +36,26 @@ } } }, + "/info": { + "get": { + "description": "List keibi's settings (oidc providers, public url...)", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "Auth info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/main.ServerInfo" + } + } + } + } + }, "/jwt": { "get": { "security": [ @@ -193,7 +213,252 @@ } } }, + "/oidc/callback/{provider}": { + "get": { + "description": "Exchange an opaque OIDC token for a local session.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC callback", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Opaque token returned by /oidc/logged/:provider", + "name": "token", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Optional tenant passthrough for federated setups", + "name": "tenant", + "in": "query" + }, + { + "type": "string", + "description": "Bearer token to link provider to current account", + "name": "Authorization", + "in": "header" + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/main.SessionWToken" + } + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "410": { + "description": "Login token expired or already used", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, + "/oidc/logged/{provider}": { + "get": { + "description": "Callback endpoint called by OIDC providers after login.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC logged callback", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "State value returned by the provider", + "name": "state", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Authorization code", + "name": "code", + "in": "query" + }, + { + "type": "string", + "description": "Provider callback error", + "name": "error", + "in": "query" + } + ], + "responses": { + "302": { + "description": "Found" + }, + "400": { + "description": "Invalid state", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, + "/oidc/login/{provider}": { + "get": { + "description": "Start an OIDC login with a provider.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC login", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "URL to redirect the browser to after provider callback", + "name": "redirectUrl", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "Optional tenant passthrough for federated setups", + "name": "tenant", + "in": "query" + } + ], + "responses": { + "302": { + "description": "Found" + }, + "400": { + "description": "Missing redirectUrl", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, + "delete": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Remove an OIDC provider from the current account.", + "produces": [ + "application/json" + ], + "tags": [ + "oidc" + ], + "summary": "OIDC unlink provider", + "parameters": [ + { + "type": "string", + "example": "google", + "description": "OIDC provider id", + "name": "provider", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "404": { + "description": "Unknown OIDC provider", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, "/sessions": { + "get": { + "security": [ + { + "Jwt": [] + } + ], + "description": "List all active sessions for the currently connected user", + "produces": [ + "application/json" + ], + "tags": [ + "sessions" + ], + "summary": "List my sessions", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/main.SessionWCurrent" + } + } + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, "post": { "description": "Login to your account and open a session", "consumes": [ @@ -368,7 +633,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.Page-main_User" + "$ref": "#/definitions/main.Page-models_User" } }, "422": { @@ -404,7 +669,7 @@ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.RegisterDto" + "$ref": "#/definitions/models.RegisterDto" } } ], @@ -415,6 +680,12 @@ "$ref": "#/definitions/main.SessionWToken" } }, + "403": { + "description": "Registrations are disabled", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, "409": { "description": "Duplicated email or username", "schema": { @@ -449,7 +720,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "401": { @@ -487,7 +758,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } } } @@ -515,7 +786,7 @@ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.EditUserDto" + "$ref": "#/definitions/models.EditUserDto" } } ], @@ -523,7 +794,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "403": { @@ -541,6 +812,137 @@ } } }, + "/users/me/logo": { + "get": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Get the current user's logo (manual upload if available, gravatar otherwise)", + "produces": [ + "image/*" + ], + "tags": [ + "users" + ], + "summary": "Get my logo", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "No gravatar image found for this user", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, + "post": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Upload a manual profile picture for the current user", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json" + ], + "tags": [ + "users" + ], + "summary": "Upload my logo", + "parameters": [ + { + "type": "file", + "description": "Profile picture image (jpeg/png/gif/webp, max 5MB)", + "name": "logo", + "in": "formData", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "413": { + "description": "File too large", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "422": { + "description": "Missing or invalid logo file", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + }, + "delete": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Delete the current user's manually uploaded profile picture", + "produces": [ + "application/json" + ], + "tags": [ + "users" + ], + "summary": "Delete my logo", + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, "/users/me/password": { "patch": { "security": [ @@ -572,7 +974,7 @@ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.EditPasswordDto" + "$ref": "#/definitions/models.EditPasswordDto" } } ], @@ -589,6 +991,49 @@ } } }, + "/users/me/{id}": { + "delete": { + "security": [ + { + "Jwt": [] + } + ], + "description": "Delete the user's manually uploaded profile picture", + "produces": [ + "application/json" + ], + "tags": [ + "users" + ], + "summary": "Delete user logo", + "parameters": [ + { + "type": "string", + "description": "The id or username of the user", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Invalid jwt token (or expired)", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, "/users/{id}": { "get": { "security": [ @@ -620,7 +1065,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "404": { @@ -669,7 +1114,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "404": { @@ -718,7 +1163,7 @@ "name": "user", "in": "body", "schema": { - "$ref": "#/definitions/main.EditUserDto" + "$ref": "#/definitions/models.EditUserDto" } } ], @@ -726,7 +1171,7 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "403": { @@ -743,6 +1188,104 @@ } } } + }, + "/users/{id}/logo": { + "get": { + "security": [ + { + "Jwt": [ + "users.read" + ] + } + ], + "description": "Get a user's logo (manual upload if available, gravatar otherwise)", + "produces": [ + "image/*" + ], + "tags": [ + "users" + ], + "summary": "Get user logo", + "parameters": [ + { + "type": "string", + "description": "The id or username of the user", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "file" + } + }, + "404": { + "description": "No gravatar image found for this user", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } + }, + "/users/{id}/sessions": { + "get": { + "security": [ + { + "Jwt": [] + } + ], + "description": "List all active sessions for a user. Listing someone else's sessions requires users.read.", + "produces": [ + "application/json" + ], + "tags": [ + "sessions" + ], + "summary": "List user sessions", + "parameters": [ + { + "type": "string", + "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397", + "description": "The id or username of the user", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/main.Session" + } + } + }, + "401": { + "description": "Missing jwt token", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "403": { + "description": "Missing permissions: users.read.", + "schema": { + "$ref": "#/definitions/main.KError" + } + }, + "404": { + "description": "No user found with id or username", + "schema": { + "$ref": "#/definitions/main.KError" + } + } + } + } } }, "definitions": { @@ -828,40 +1371,6 @@ } } }, - "main.EditPasswordDto": { - "type": "object", - "required": [ - "password" - ], - "properties": { - "password": { - "type": "string", - "example": "password1234" - } - } - }, - "main.EditUserDto": { - "type": "object", - "properties": { - "claims": { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "example": { - "preferOriginal": " true" - } - }, - "email": { - "type": "string", - "example": "kyoo@zoriya.dev" - }, - "username": { - "type": "string", - "example": "zoriya" - } - } - }, "main.JwkSet": { "type": "object", "properties": { @@ -943,24 +1452,14 @@ } } }, - "main.OidcHandle": { + "main.OidcInfo": { "type": "object", "properties": { - "id": { - "description": "Id of this oidc handle.", - "type": "string", - "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397" + "logo": { + "type": "string" }, - "profileUrl": { - "description": "Link to the profile of the user on the external service. Null if unknown or irrelevant.", - "type": "string", - "format": "url", - "example": "https://myanimelist.net/profile/zoriya" - }, - "username": { - "description": "Username of the user on the external service.", - "type": "string", - "example": "zoriya" + "name": { + "type": "string" } } }, @@ -983,13 +1482,13 @@ } } }, - "main.Page-main_User": { + "main.Page-models_User": { "type": "object", "properties": { "items": { "type": "array", "items": { - "$ref": "#/definitions/main.User" + "$ref": "#/definitions/models.User" } }, "next": { @@ -1002,29 +1501,20 @@ } } }, - "main.RegisterDto": { + "main.ServerInfo": { "type": "object", - "required": [ - "email", - "password", - "username" - ], "properties": { - "email": { - "description": "Valid email that could be used for forgotten password requests. Can be used for login.", - "type": "string", - "format": "email", - "example": "kyoo@zoriya.dev" + "allowRegister": { + "type": "boolean" }, - "password": { - "description": "Password to use.", - "type": "string", - "example": "password1234" + "oidc": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/main.OidcInfo" + } }, - "username": { - "description": "Username of the new account, can't contain @ signs. Can be used for login.", - "type": "string", - "example": "zoriya" + "publicUrl": { + "type": "string" } } }, @@ -1053,6 +1543,34 @@ } } }, + "main.SessionWCurrent": { + "type": "object", + "properties": { + "createdDate": { + "description": "When was the session first opened", + "type": "string", + "example": "2025-03-29T18:20:05.267Z" + }, + "current": { + "type": "boolean" + }, + "device": { + "description": "Device that created the session.", + "type": "string", + "example": "Web - Firefox" + }, + "id": { + "description": "Unique id of this session. Can be used for calls to DELETE", + "type": "string", + "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397" + }, + "lastUsed": { + "description": "Last date this session was used to access a service.", + "type": "string", + "example": "2025-03-29T18:20:05.267Z" + } + } + }, "main.SessionWToken": { "type": "object", "properties": { @@ -1082,7 +1600,92 @@ } } }, - "main.User": { + "models.EditPasswordDto": { + "type": "object", + "required": [ + "newPassword" + ], + "properties": { + "newPassword": { + "type": "string", + "example": "password1234" + }, + "oldPassword": { + "type": "string", + "example": "password1234" + } + } + }, + "models.EditUserDto": { + "type": "object", + "properties": { + "claims": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "example": { + "preferOriginal": " true" + } + }, + "email": { + "type": "string", + "example": "kyoo@zoriya.dev" + }, + "username": { + "type": "string", + "example": "zoriya" + } + } + }, + "models.OidcHandle": { + "type": "object", + "properties": { + "id": { + "description": "Id of this oidc handle.", + "type": "string", + "example": "e05089d6-9179-4b5b-a63e-94dd5fc2a397" + }, + "profileUrl": { + "description": "Link to the profile of the user on the external service. Null if unknown or irrelevant.", + "type": "string", + "format": "url", + "example": "https://myanimelist.net/profile/zoriya" + }, + "username": { + "description": "Username of the user on the external service.", + "type": "string", + "example": "zoriya" + } + } + }, + "models.RegisterDto": { + "type": "object", + "required": [ + "email", + "password", + "username" + ], + "properties": { + "email": { + "description": "Valid email that could be used for forgotten password requests. Can be used for login.", + "type": "string", + "format": "email", + "example": "kyoo@zoriya.dev" + }, + "password": { + "description": "Password to use.", + "type": "string", + "example": "password1234" + }, + "username": { + "description": "Username of the new account, can't contain @ signs. Can be used for login.", + "type": "string", + "example": "zoriya" + } + } + }, + "models.User": { "type": "object", "properties": { "claims": { @@ -1106,6 +1709,10 @@ "format": "email", "example": "kyoo@zoriya.dev" }, + "hasPassword": { + "description": "False if the user has never setup a password and only used oidc.", + "type": "boolean" + }, "id": { "description": "Id of the user.", "type": "string", @@ -1120,7 +1727,7 @@ "description": "List of other login method available for this user. Access tokens wont be returned here.", "type": "object", "additionalProperties": { - "$ref": "#/definitions/main.OidcHandle" + "$ref": "#/definitions/models.OidcHandle" } }, "username": { diff --git a/auth/docs/swagger.yaml b/auth/docs/swagger.yaml new file mode 100644 index 00000000..62a29f31 --- /dev/null +++ b/auth/docs/swagger.yaml @@ -0,0 +1,1164 @@ +basePath: /auth +definitions: + main.ApiKey: + properties: + claims: + additionalProperties: + type: string + example: + isAdmin: ' true' + type: object + createAt: + example: "2025-03-29T18:20:05.267Z" + type: string + id: + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + lastUsed: + example: "2025-03-29T18:20:05.267Z" + type: string + name: + example: myapp + type: string + type: object + main.ApiKeyDto: + properties: + claims: + additionalProperties: + type: string + example: + isAdmin: ' true' + type: object + name: + example: myapp + type: string + type: object + main.ApiKeyWToken: + properties: + claims: + additionalProperties: + type: string + example: + isAdmin: ' true' + type: object + createAt: + example: "2025-03-29T18:20:05.267Z" + type: string + id: + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + lastUsed: + example: "2025-03-29T18:20:05.267Z" + type: string + name: + example: myapp + type: string + token: + example: myapp-lyHzTYm9yi+pkEv3m2tamAeeK7Dj7N3QRP7xv7dPU5q9MAe8tU4ySwYczE0RaMr4fijsA== + type: string + type: object + main.JwkSet: + properties: + keys: + items: + properties: + e: + example: AQAB + type: string + key_ops: + example: + - '[verify]' + items: + type: string + type: array + kty: + example: RSA + type: string + "n": + example: oBcXcJUR-Sb8_b4qIj28LRAPxdF_6odRr52K5-ymiEkR2DOlEuXBtM-biWxPESW-U-zhfHzdVLf6ioy5xL0bJTh8BMIorkrDliN3vb81jCvyOMgZ7ATMJpMAQMmSDN7sL3U45r22FaoQufCJMQHmUsZPecdQSgj2aFBiRXxsLleYlSezdBVT_gKH-coqeYXSC_hk-ezSq4aDZ10BlDnZ-FA7-ES3T7nBmJEAU7KDAGeSvbYAfYimOW0r-Vc0xQNuwGCfzZtSexKXDbYbNwOVo3SjfCabq-gMfap_owcHbKicGBZu1LDlh7CpkmLQf_kv6GihM2LWFFh6Vwg2cltiwF22EIPlUDtYTkUR0qRkdNJaNkwV5Vv_6r3pzSmu5ovRriKtlrvJMjlTnLb4_ltsge3fw5Z34cJrsp094FbUc2O6Or4FGEXUldieJCnVRhs2_h6SDcmeMXs1zfvE5GlDnq8tZV6WMJ5Sb4jNO7rs_hTkr23_E6mVg-DdtozGfqzRzhIjPym6D_jVfR6dZv5W0sKwOHRmT7nYq-C7b2sAwmNNII296M4Rq-jn0b5pgSeMDYbIpbIA4thU8LYU0lBZp_ZVwWKG1RFZDxz3k9O5UVth2kTpTWlwn0hB1aAvgXHo6in1CScITGA72p73RbDieNnLFaCK4xUVstkWAKLqPxs + type: string + use: + example: sig + type: string + type: object + type: array + type: object + main.Jwt: + properties: + token: + description: The jwt token you can use for all authorized call to either keibi + or other services. + example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.KMUFsIDTnFmyG3nMiGM6H9FNFUROf3wh7SmqJp-QV30 + type: string + type: object + main.KError: + properties: + details: {} + message: + example: No user found with this id + type: string + status: + example: 404 + type: integer + type: object + main.LoginDto: + properties: + login: + description: Either the email or the username. + example: zoriya + type: string + password: + description: Password of the account. + example: password1234 + type: string + required: + - login + - password + type: object + main.OidcInfo: + properties: + logo: + type: string + name: + type: string + type: object + main.Page-main_ApiKey: + properties: + items: + items: + $ref: '#/definitions/main.ApiKey' + type: array + next: + example: https://kyoo.zoriya.dev/auth/users?after=aoeusth + type: string + this: + example: https://kyoo.zoriya.dev/auth/users + type: string + type: object + main.Page-models_User: + properties: + items: + items: + $ref: '#/definitions/models.User' + type: array + next: + example: https://kyoo.zoriya.dev/auth/users?after=aoeusth + type: string + this: + example: https://kyoo.zoriya.dev/auth/users + type: string + type: object + main.ServerInfo: + properties: + allowRegister: + type: boolean + oidc: + additionalProperties: + $ref: '#/definitions/main.OidcInfo' + type: object + publicUrl: + type: string + type: object + main.Session: + properties: + createdDate: + description: When was the session first opened + example: "2025-03-29T18:20:05.267Z" + type: string + device: + description: Device that created the session. + example: Web - Firefox + type: string + id: + description: Unique id of this session. Can be used for calls to DELETE + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + lastUsed: + description: Last date this session was used to access a service. + example: "2025-03-29T18:20:05.267Z" + type: string + type: object + main.SessionWCurrent: + properties: + createdDate: + description: When was the session first opened + example: "2025-03-29T18:20:05.267Z" + type: string + current: + type: boolean + device: + description: Device that created the session. + example: Web - Firefox + type: string + id: + description: Unique id of this session. Can be used for calls to DELETE + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + lastUsed: + description: Last date this session was used to access a service. + example: "2025-03-29T18:20:05.267Z" + type: string + type: object + main.SessionWToken: + properties: + createdDate: + description: When was the session first opened + example: "2025-03-29T18:20:05.267Z" + type: string + device: + description: Device that created the session. + example: Web - Firefox + type: string + id: + description: Unique id of this session. Can be used for calls to DELETE + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + lastUsed: + description: Last date this session was used to access a service. + example: "2025-03-29T18:20:05.267Z" + type: string + token: + example: lyHzTYm9yi+pkEv3m2tamAeeK7Dj7N3QRP7xv7dPU5q9MAe8tU4ySwYczE0RaMr4fijsA== + type: string + type: object + models.EditPasswordDto: + properties: + newPassword: + example: password1234 + type: string + oldPassword: + example: password1234 + type: string + required: + - newPassword + type: object + models.EditUserDto: + properties: + claims: + additionalProperties: + type: string + example: + preferOriginal: ' true' + type: object + email: + example: kyoo@zoriya.dev + type: string + username: + example: zoriya + type: string + type: object + models.OidcHandle: + properties: + id: + description: Id of this oidc handle. + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + profileUrl: + description: Link to the profile of the user on the external service. Null + if unknown or irrelevant. + example: https://myanimelist.net/profile/zoriya + format: url + type: string + username: + description: Username of the user on the external service. + example: zoriya + type: string + type: object + models.RegisterDto: + properties: + email: + description: Valid email that could be used for forgotten password requests. + Can be used for login. + example: kyoo@zoriya.dev + format: email + type: string + password: + description: Password to use. + example: password1234 + type: string + username: + description: Username of the new account, can't contain @ signs. Can be used + for login. + example: zoriya + type: string + required: + - email + - password + - username + type: object + models.User: + properties: + claims: + additionalProperties: + type: string + description: List of custom claims JWT created via get /jwt will have + example: + isAdmin: ' true' + type: object + createdDate: + description: When was this account created? + example: "2025-03-29T18:20:05.267Z" + type: string + email: + description: Email of the user. Can be used as a login. + example: kyoo@zoriya.dev + format: email + type: string + hasPassword: + description: False if the user has never setup a password and only used oidc. + type: boolean + id: + description: Id of the user. + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + type: string + lastSeen: + description: When was the last time this account made any authorized request? + example: "2025-03-29T18:20:05.267Z" + type: string + oidc: + additionalProperties: + $ref: '#/definitions/models.OidcHandle' + description: List of other login method available for this user. Access tokens + wont be returned here. + type: object + username: + description: Username of the user. Can be used as a login. + example: zoriya + type: string + type: object +host: kyoo.zoriya.dev +info: + contact: + name: Repository + url: https://github.com/zoriya/kyoo + description: Auth system made for kyoo. + license: + name: GPL-3.0 + url: https://www.gnu.org/licenses/gpl-3.0.en.html + title: Keibi - Kyoo's auth + version: "1.0" +paths: + /.well-known/jwks.json: + get: + description: Get the jwks info, used to validate jwts. + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.JwkSet' + summary: Jwks + tags: + - jwt + /info: + get: + description: List keibi's settings (oidc providers, public url...) + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.ServerInfo' + summary: Auth info + tags: + - oidc + /jwt: + get: + description: Convert a session token or an API key to a short lived JWT. + produces: + - application/json + responses: + "200": + description: OK + headers: + Authorization: + description: Jwt (same value as the returned token) + type: string + schema: + $ref: '#/definitions/main.Jwt' + "403": + description: Invalid session token (or expired) + schema: + $ref: '#/definitions/main.KError' + security: + - Token: [] + summary: Get JWT + tags: + - jwt + /keys: + delete: + consumes: + - application/json + description: Delete an existing API key + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.ApiKey' + "404": + description: Invalid id + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid id format + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - apikeys.write + summary: Delete API key + tags: + - apikeys + get: + consumes: + - application/json + description: List all api keys + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.Page-main_ApiKey' + security: + - Jwt: + - apikeys.read + summary: List API keys + tags: + - apikeys + post: + consumes: + - application/json + description: Create a new API key + parameters: + - description: Api key info + in: body + name: key + schema: + $ref: '#/definitions/main.ApiKeyDto' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/main.ApiKeyWToken' + "409": + description: Duplicated api key + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid create body + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - apikeys.write + summary: Create API key + tags: + - apikeys + /oidc/callback/{provider}: + get: + description: Exchange an opaque OIDC token for a local session. + parameters: + - description: OIDC provider id + example: google + in: path + name: provider + required: true + type: string + - description: Opaque token returned by /oidc/logged/:provider + in: query + name: token + required: true + type: string + - description: Optional tenant passthrough for federated setups + in: query + name: tenant + type: string + - description: Bearer token to link provider to current account + in: header + name: Authorization + type: string + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/main.SessionWToken' + "404": + description: Unknown OIDC provider + schema: + $ref: '#/definitions/main.KError' + "410": + description: Login token expired or already used + schema: + $ref: '#/definitions/main.KError' + summary: OIDC callback + tags: + - oidc + /oidc/logged/{provider}: + get: + description: Callback endpoint called by OIDC providers after login. + parameters: + - description: OIDC provider id + example: google + in: path + name: provider + required: true + type: string + - description: State value returned by the provider + in: query + name: state + required: true + type: string + - description: Authorization code + in: query + name: code + type: string + - description: Provider callback error + in: query + name: error + type: string + produces: + - application/json + responses: + "302": + description: Found + "400": + description: Invalid state + schema: + $ref: '#/definitions/main.KError' + "404": + description: Unknown OIDC provider + schema: + $ref: '#/definitions/main.KError' + summary: OIDC logged callback + tags: + - oidc + /oidc/login/{provider}: + delete: + description: Remove an OIDC provider from the current account. + parameters: + - description: OIDC provider id + example: google + in: path + name: provider + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + "404": + description: Unknown OIDC provider + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: OIDC unlink provider + tags: + - oidc + get: + description: Start an OIDC login with a provider. + parameters: + - description: OIDC provider id + example: google + in: path + name: provider + required: true + type: string + - description: URL to redirect the browser to after provider callback + in: query + name: redirectUrl + required: true + type: string + - description: Optional tenant passthrough for federated setups + in: query + name: tenant + type: string + produces: + - application/json + responses: + "302": + description: Found + "400": + description: Missing redirectUrl + schema: + $ref: '#/definitions/main.KError' + "404": + description: Unknown OIDC provider + schema: + $ref: '#/definitions/main.KError' + summary: OIDC login + tags: + - oidc + /sessions: + get: + description: List all active sessions for the currently connected user + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/main.SessionWCurrent' + type: array + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: List my sessions + tags: + - sessions + post: + consumes: + - application/json + description: Login to your account and open a session + parameters: + - description: The device the created session will be used on + example: android tv + in: query + name: device + type: string + - description: Account informations + in: body + name: login + schema: + $ref: '#/definitions/main.LoginDto' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/main.SessionWToken' + "403": + description: Invalid password + schema: + $ref: '#/definitions/main.KError' + "404": + description: Account does not exists + schema: + $ref: '#/definitions/main.KError' + "422": + description: User does not have a password (registered via oidc, please + login via oidc) + schema: + $ref: '#/definitions/main.KError' + summary: Login + tags: + - sessions + /sessions/{id}: + delete: + description: Delete a session and logout + parameters: + - description: The id of the session to delete + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + format: uuid + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.Session' + "404": + description: Session not found with specified id (if not using the /current + route) + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid session id + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Delete other session + tags: + - sessions + /sessions/current: + delete: + description: Delete a session and logout + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.Session' + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Logout + tags: + - sessions + /users: + get: + consumes: + - application/json + description: List all users existing in this instance. + parameters: + - description: used for pagination. + in: query + name: after + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/main.Page-models_User' + "422": + description: Invalid after id + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - users.read + summary: List all users + tags: + - users + post: + consumes: + - application/json + description: Register as a new user and open a session for it + parameters: + - description: The device the created session will be used on + example: android + in: query + name: device + type: string + - description: Registration informations + in: body + name: user + schema: + $ref: '#/definitions/models.RegisterDto' + produces: + - application/json + responses: + "201": + description: Created + schema: + $ref: '#/definitions/main.SessionWToken' + "403": + description: Registrations are disabled + schema: + $ref: '#/definitions/main.KError' + "409": + description: Duplicated email or username + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid register body + schema: + $ref: '#/definitions/main.KError' + summary: Register + tags: + - users + /users/{id}: + delete: + consumes: + - application/json + description: Delete an account and all it's sessions. + parameters: + - description: User id of the user to delete + format: uuid + in: path + name: id + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "404": + description: Invalid user id + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid id format + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - users.delete + summary: Delete user + tags: + - users + get: + description: Get informations about a user from it's id + parameters: + - description: The id of the user + format: uuid + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "404": + description: No user with the given id found + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid id (not a uuid) + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - users.read + summary: Get user + tags: + - users + patch: + consumes: + - application/json + description: Edit an account info or permissions + parameters: + - description: User id of the user to edit + format: uuid + in: path + name: id + type: string + - description: Edited user info + in: body + name: user + schema: + $ref: '#/definitions/models.EditUserDto' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "403": + description: You don't have permissions to edit another account + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid body + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - users.write + summary: Edit user + tags: + - users + /users/{id}/logo: + get: + description: Get a user's logo (manual upload if available, gravatar otherwise) + parameters: + - description: The id or username of the user + in: path + name: id + required: true + type: string + produces: + - image/* + responses: + "200": + description: OK + schema: + type: file + "404": + description: No gravatar image found for this user + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: + - users.read + summary: Get user logo + tags: + - users + /users/{id}/sessions: + get: + description: List all active sessions for a user. Listing someone else's sessions + requires users.read. + parameters: + - description: The id or username of the user + example: e05089d6-9179-4b5b-a63e-94dd5fc2a397 + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: OK + schema: + items: + $ref: '#/definitions/main.Session' + type: array + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: 'Missing permissions: users.read.' + schema: + $ref: '#/definitions/main.KError' + "404": + description: No user found with id or username + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: List user sessions + tags: + - sessions + /users/me: + delete: + consumes: + - application/json + description: Delete your account and all your sessions + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + security: + - Jwt: [] + summary: Delete self + tags: + - users + get: + description: Get informations about the currently connected user + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Get me + tags: + - users + patch: + consumes: + - application/json + description: Edit your account's info + parameters: + - description: Edited user info + in: body + name: user + schema: + $ref: '#/definitions/models.EditUserDto' + produces: + - application/json + responses: + "200": + description: OK + schema: + $ref: '#/definitions/models.User' + "403": + description: You can't edit a protected claim + schema: + $ref: '#/definitions/main.KError' + "422": + description: Invalid body + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Edit self + tags: + - users + /users/me/{id}: + delete: + description: Delete the user's manually uploaded profile picture + parameters: + - description: The id or username of the user + in: path + name: id + required: true + type: string + produces: + - application/json + responses: + "204": + description: No Content + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Delete user logo + tags: + - users + /users/me/logo: + delete: + description: Delete the current user's manually uploaded profile picture + produces: + - application/json + responses: + "204": + description: No Content + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Delete my logo + tags: + - users + get: + description: Get the current user's logo (manual upload if available, gravatar + otherwise) + produces: + - image/* + responses: + "200": + description: OK + schema: + type: file + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + "404": + description: No gravatar image found for this user + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Get my logo + tags: + - users + post: + consumes: + - multipart/form-data + description: Upload a manual profile picture for the current user + parameters: + - description: Profile picture image (jpeg/png/gif/webp, max 5MB) + in: formData + name: logo + required: true + type: file + produces: + - application/json + responses: + "204": + description: No Content + "401": + description: Missing jwt token + schema: + $ref: '#/definitions/main.KError' + "403": + description: Invalid jwt token (or expired) + schema: + $ref: '#/definitions/main.KError' + "413": + description: File too large + schema: + $ref: '#/definitions/main.KError' + "422": + description: Missing or invalid logo file + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Upload my logo + tags: + - users + /users/me/password: + patch: + consumes: + - application/json + description: Edit your password + parameters: + - default: true + description: Invalidate other sessions + in: query + name: invalidate + type: boolean + - description: New password + in: body + name: user + schema: + $ref: '#/definitions/models.EditPasswordDto' + produces: + - application/json + responses: + "204": + description: No Content + "422": + description: Invalid body + schema: + $ref: '#/definitions/main.KError' + security: + - Jwt: [] + summary: Edit password + tags: + - users +securityDefinitions: + Jwt: + in: header + name: Authorization + type: apiKey + Token: + in: header + name: Authorization + type: apiKey +swagger: "2.0" diff --git a/auth/go.mod b/auth/go.mod index 8cb35e78..bfaa1f0e 100644 --- a/auth/go.mod +++ b/auth/go.mod @@ -7,15 +7,16 @@ require ( github.com/exaring/otelpgx v0.10.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/google/uuid v1.6.0 - github.com/jackc/pgx/v5 v5.8.0 + github.com/jackc/pgx/v5 v5.9.1 github.com/labstack/echo-jwt/v5 v5.0.1 github.com/labstack/echo-opentelemetry v0.0.2 github.com/labstack/echo/v5 v5.0.4 github.com/lestrrat-go/jwx/v3 v3.0.13 - github.com/swaggo/echo-swagger v1.5.0 + github.com/mileusna/useragent v1.3.5 + github.com/swaggo/echo-swagger/v2 v2.0.1 github.com/swaggo/swag v1.16.6 go.opentelemetry.io/contrib/bridges/otelslog v0.17.0 - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 go.opentelemetry.io/otel v1.42.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.18.0 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.18.0 @@ -31,47 +32,47 @@ require ( require ( github.com/cenkalti/backoff/v5 v5.0.3 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/swag/conv v0.25.4 // indirect - github.com/go-openapi/swag/jsonname v0.25.4 // indirect - github.com/go-openapi/swag/jsonutils v0.25.4 // indirect - github.com/go-openapi/swag/loading v0.25.4 // indirect - github.com/go-openapi/swag/stringutils v0.25.4 // indirect - github.com/go-openapi/swag/typeutils v0.25.4 // indirect - github.com/go-openapi/swag/yamlutils v0.25.4 // indirect - github.com/goccy/go-json v0.10.5 // indirect + github.com/go-openapi/swag/conv v0.25.5 // indirect + github.com/go-openapi/swag/jsonname v0.25.5 // indirect + github.com/go-openapi/swag/jsonutils v0.25.5 // indirect + github.com/go-openapi/swag/loading v0.25.5 // indirect + github.com/go-openapi/swag/stringutils v0.25.5 // indirect + github.com/go-openapi/swag/typeutils v0.25.5 // indirect + github.com/go-openapi/swag/yamlutils v0.25.5 // indirect + github.com/goccy/go-json v0.10.6 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect github.com/lestrrat-go/blackmagic v1.0.4 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect - github.com/lestrrat-go/httprc/v3 v3.0.3 // indirect + github.com/lestrrat-go/httprc/v3 v3.0.4 // indirect github.com/lestrrat-go/option/v2 v2.0.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/segmentio/asm v1.2.1 // indirect - github.com/sv-tools/openapi v0.2.1 // indirect - github.com/swaggo/swag/v2 v2.0.0-rc4 // indirect + github.com/sv-tools/openapi v0.4.0 // indirect + github.com/swaggo/swag/v2 v2.0.0-rc5 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.40.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.42.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/mod v0.32.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect + golang.org/x/mod v0.34.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 // indirect google.golang.org/grpc v1.79.3 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) require ( github.com/KyleBanks/depth v1.2.1 // indirect - github.com/gabriel-vasile/mimetype v1.4.12 // indirect - github.com/go-openapi/jsonpointer v0.22.4 // indirect - github.com/go-openapi/jsonreference v0.21.4 // indirect - github.com/go-openapi/spec v0.22.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.13 // indirect + github.com/go-openapi/jsonpointer v0.22.5 // indirect + github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/spec v0.22.4 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.30.1 @@ -81,17 +82,15 @@ require ( github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/leodido/go-urn v1.4.0 // indirect - github.com/mileusna/useragent v1.3.5 github.com/swaggo/files/v2 v2.0.2 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.42.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.42.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.42.0 - golang.org/x/crypto v0.48.0 // indirect - golang.org/x/net v0.51.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/sys v0.41.0 // indirect - golang.org/x/text v0.34.0 // indirect - golang.org/x/time v0.14.0 // indirect - golang.org/x/tools v0.41.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + golang.org/x/crypto v0.49.0 // indirect + golang.org/x/net v0.52.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/time v0.15.0 // indirect + golang.org/x/tools v0.43.0 // indirect ) diff --git a/auth/go.sum b/auth/go.sum index 063ed7f4..af6acff9 100644 --- a/auth/go.sum +++ b/auth/go.sum @@ -15,11 +15,10 @@ github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 h1:5RVFMOWjMyRy8cARdy79nAmgYw3hK/4HUq48LQ6Wwqo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/dhui/dktest v0.4.6 h1:+DPKyScKSEp3VLtbMDHcUq6V5Lm5zfZZVb0Sk7Ahom4= github.com/dhui/dktest v0.4.6/go.mod h1:JHTSYDtKkvFNFHJKqCzVzqXecyv+tKt8EzceOmQOgbU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -34,40 +33,40 @@ github.com/exaring/otelpgx v0.10.0 h1:NGGegdoBQM3jNZDKG8ENhigUcgBN7d7943L0YlcIpZ github.com/exaring/otelpgx v0.10.0/go.mod h1:R5/M5LWsPPBZc1SrRE5e0DiU48bI78C1/GPTWs6I66U= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw= -github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= +github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= -github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= -github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= -github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= -github.com/go-openapi/spec v0.22.3 h1:qRSmj6Smz2rEBxMnLRBMeBWxbbOvuOoElvSvObIgwQc= -github.com/go-openapi/spec v0.22.3/go.mod h1:iIImLODL2loCh3Vnox8TY2YWYJZjMAKYyLH2Mu8lOZs= +github.com/go-openapi/jsonpointer v0.22.5 h1:8on/0Yp4uTb9f4XvTrM2+1CPrV05QPZXu+rvu2o9jcA= +github.com/go-openapi/jsonpointer v0.22.5/go.mod h1:gyUR3sCvGSWchA2sUBJGluYMbe1zazrYWIkWPjjMUY0= +github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= +github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= +github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= -github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= -github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= -github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= -github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= -github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= -github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4 h1:IACsSvBhiNJwlDix7wq39SS2Fh7lUOCJRmx/4SN4sVo= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.4/go.mod h1:Mt0Ost9l3cUzVv4OEZG+WSeoHwjWLnarzMePNDAOBiM= -github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= -github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= -github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= -github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= -github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= -github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= -github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= -github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= -github.com/go-openapi/testify/enable/yaml/v2 v2.0.2 h1:0+Y41Pz1NkbTHz8NngxTuAXxEodtNSI1WG1c/m5Akw4= -github.com/go-openapi/testify/enable/yaml/v2 v2.0.2/go.mod h1:kme83333GCtJQHXQ8UKX3IBZu6z8T5Dvy5+CW3NLUUg= -github.com/go-openapi/testify/v2 v2.0.2 h1:X999g3jeLcoY8qctY/c/Z8iBHTbwLz7R2WXd6Ub6wls= -github.com/go-openapi/testify/v2 v2.0.2/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= +github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= +github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= +github.com/go-openapi/swag/jsonname v0.25.5 h1:8p150i44rv/Drip4vWI3kGi9+4W9TdI3US3uUYSFhSo= +github.com/go-openapi/swag/jsonname v0.25.5/go.mod h1:jNqqikyiAK56uS7n8sLkdaNY/uq6+D2m2LANat09pKU= +github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= +github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo= +github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= +github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= +github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= +github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= +github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= +github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= +github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= +github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0 h1:7SgOMTvJkM8yWrQlU8Jm18VeDPuAvB/xWrdxFJkoFag= +github.com/go-openapi/testify/enable/yaml/v2 v2.4.0/go.mod h1:14iV8jyyQlinc9StD7w1xVPW3CO3q1Gj04Jy//Kw4VM= +github.com/go-openapi/testify/v2 v2.4.0 h1:8nsPrHVCWkQ4p8h1EsRVymA2XABB4OT40gcvAu+voFM= +github.com/go-openapi/testify/v2 v2.4.0/go.mod h1:HCPmvFFnheKK2BuwSA0TbbdxJ3I16pjwMkYkP4Ywn54= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -76,8 +75,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= -github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= -github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU= +github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= @@ -98,8 +97,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= -github.com/jackc/pgx/v5 v5.8.0 h1:TYPDoleBBme0xGSAX3/+NujXXtpZn9HBONkQC7IEZSo= -github.com/jackc/pgx/v5 v5.8.0/go.mod h1:QVeDInX2m9VyzvNeiCJVjCkNFqzsNb43204HshNSZKw= +github.com/jackc/pgx/v5 v5.9.1 h1:uwrxJXBnx76nyISkhr33kQLlUqjv7et7b9FjCen/tdc= +github.com/jackc/pgx/v5 v5.9.1/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -122,8 +121,8 @@ github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7 github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU= github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE= github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E= -github.com/lestrrat-go/httprc/v3 v3.0.3 h1:WjLHWkDkgWXeIUrKi/7lS/sGq2DjkSAwdTbH5RHXAKs= -github.com/lestrrat-go/httprc/v3 v3.0.3/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= +github.com/lestrrat-go/httprc/v3 v3.0.4 h1:pXyH2ppK8GYYggygxJ3TvxpCZnbEUWc9qSwRTTApaLA= +github.com/lestrrat-go/httprc/v3 v3.0.4/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0= github.com/lestrrat-go/jwx/v3 v3.0.13 h1:AdHKiPIYeCSnOJtvdpipPg/0SuFh9rdkN+HF3O0VdSk= github.com/lestrrat-go/jwx/v3 v3.0.13/go.mod h1:2m0PV1A9tM4b/jVLMx8rh6rBl7F6WGb3EG2hufN9OQU= github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss= @@ -157,16 +156,16 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/sv-tools/openapi v0.2.1 h1:ES1tMQMJFGibWndMagvdoo34T1Vllxr1Nlm5wz6b1aA= -github.com/sv-tools/openapi v0.2.1/go.mod h1:k5VuZamTw1HuiS9p2Wl5YIDWzYnHG6/FgPOSFXLAhGg= -github.com/swaggo/echo-swagger v1.5.0 h1:nkHxOaBy0SkbJMtMeXZC64KHSa0mJdZFQhVqwEcMres= -github.com/swaggo/echo-swagger v1.5.0/go.mod h1:TzO363X1ZG/MSbjrG2IX6m65Yd3/zpqh5KM6lPctAhk= +github.com/sv-tools/openapi v0.4.0 h1:UhD9DVnGox1hfTePNclpUzUFgos57FvzT2jmcAuTOJ4= +github.com/sv-tools/openapi v0.4.0/go.mod h1:kD/dG+KP0+Fom1r6nvcj/ORtLus8d8enXT6dyRZDirE= +github.com/swaggo/echo-swagger/v2 v2.0.1 h1:jKR3QiK+ciGjxE0+7qZ/azjtlx/pTVls7pJFJqdJoJI= +github.com/swaggo/echo-swagger/v2 v2.0.1/go.mod h1:BbgiO9XKX6yYU5Rq4ejqVlQI0mVRv6ziFKd0XgdztnQ= github.com/swaggo/files/v2 v2.0.2 h1:Bq4tgS/yxLB/3nwOMcul5oLEUKa877Ykgz3CJMVbQKU= github.com/swaggo/files/v2 v2.0.2/go.mod h1:TVqetIzZsO9OhHX1Am9sRf9LdrFZqoK49N37KON/jr0= github.com/swaggo/swag v1.16.6 h1:qBNcx53ZaX+M5dxVyTrgQ0PJ/ACK+NzhwcbieTt+9yI= github.com/swaggo/swag v1.16.6/go.mod h1:ngP2etMK5a0P3QBizic5MEwpRmluJZPHjXcMoj4Xesg= -github.com/swaggo/swag/v2 v2.0.0-rc4 h1:SZ8cK68gcV6cslwrJMIOqPkJELRwq4gmjvk77MrvHvY= -github.com/swaggo/swag/v2 v2.0.0-rc4/go.mod h1:Ow7Y8gF16BTCDn8YxZbyKn8FkMLRUHekv1kROJZpbvE= +github.com/swaggo/swag/v2 v2.0.0-rc5 h1:fK7d6ET9rrEsdB8IyuwXREWMcyQN3N7gawGFbbrjgHk= +github.com/swaggo/swag/v2 v2.0.0-rc5/go.mod h1:kCL8Fu4Zl8d5tB2Bgj96b8wRowwrwk175bZHXfuGVFI= github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -174,8 +173,8 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/bridges/otelslog v0.17.0 h1:NFIS6x7wyObQ7cR84x7bt1sr8nYBx89s3x3GwRjw40k= go.opentelemetry.io/contrib/bridges/otelslog v0.17.0/go.mod h1:39SaByOyDMRMe872AE7uelMuQZidIw7LLFAnQi0FWTE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0 h1:OyrsyzuttWTSur2qN/Lm0m2a8yqyIjUVBZcxFPuXq2o= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.67.0/go.mod h1:C2NGBr+kAB4bk3xtMXfZ94gqFDtg/GkI7e9zqGh5Beg= go.opentelemetry.io/contrib/propagators/b3 v1.40.0 h1:xariChe8OOVF3rNlfzGFgQc61npQmXhzZj/i82mxMfg= go.opentelemetry.io/contrib/propagators/b3 v1.40.0/go.mod h1:72WvbdxbOfXaELEQfonFfOL6osvcVjI7uJEE8C2nkrs= go.opentelemetry.io/otel v1.42.0 h1:lSQGzTgVR3+sgJDAU/7/ZMjN9Z+vUip7leaqBKy4sho= @@ -208,33 +207,35 @@ go.opentelemetry.io/otel/sdk/metric v1.42.0 h1:D/1QR46Clz6ajyZ3G8SgNlTJKBdGp84q9 go.opentelemetry.io/otel/sdk/metric v1.42.0/go.mod h1:Ua6AAlDKdZ7tdvaQKfSmnFTdHx37+J4ba8MwVCYM5hc= go.opentelemetry.io/otel/trace v1.42.0 h1:OUCgIPt+mzOnaUTpOQcBiM/PLQ/Op7oq6g4LenLmOYY= go.opentelemetry.io/otel/trace v1.42.0/go.mod h1:f3K9S+IFqnumBkKhRJMeaZeNk9epyhnCmQh/EysQCdc= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= +go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c= -golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU= +golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= +golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -243,8 +244,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= @@ -256,23 +257,23 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc= -golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg= +golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= +golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= -google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= -google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= +google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7 h1:ndE4FoJqsIceKP2oYSnUZqhTdYufCYYkqwtFzfrhI7w= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= @@ -280,10 +281,8 @@ google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/auth/main.go b/auth/main.go index e346c9c6..e02ed133 100644 --- a/auth/main.go +++ b/auth/main.go @@ -25,7 +25,7 @@ import ( echojwt "github.com/labstack/echo-jwt/v5" "github.com/labstack/echo/v5" "github.com/labstack/echo/v5/middleware" - echoSwagger "github.com/swaggo/echo-swagger" + echoSwagger "github.com/swaggo/echo-swagger/v2" "github.com/exaring/otelpgx" ) diff --git a/auth/oidc.go b/auth/oidc.go index 619cb2b9..e0ebb4c9 100644 --- a/auth/oidc.go +++ b/auth/oidc.go @@ -544,7 +544,7 @@ type OidcInfo struct { // @Description List keibi's settings (oidc providers, public url...) // @Tags oidc // @Produce json -// @Success 200 ServerInfo +// @Success 200 {object} ServerInfo // @Router /info [get] func (h *Handler) Info(c *echo.Context) error { ret := ServerInfo{ diff --git a/front/src/ui/details/staff.tsx b/front/src/ui/details/staff.tsx index 57b520a0..e7109d33 100644 --- a/front/src/ui/details/staff.tsx +++ b/front/src/ui/details/staff.tsx @@ -1,7 +1,7 @@ import { useTranslation } from "react-i18next"; import { View } from "react-native"; import { Role } from "~/models"; -import { Container, H2, Image, P, Poster, Skeleton, SubP } from "~/primitives"; +import { Container, H2, P, Poster, Skeleton, SubP } from "~/primitives"; import { InfiniteGrid, type QueryIdentifier } from "~/query"; import { EmptyView } from "../empty-view"; diff --git a/front/src/ui/player/controls/tracks-menu.tsx b/front/src/ui/player/controls/tracks-menu.tsx index 9ed05a90..6f41181f 100644 --- a/front/src/ui/player/controls/tracks-menu.tsx +++ b/front/src/ui/player/controls/tracks-menu.tsx @@ -176,6 +176,7 @@ export const QualityMenu = ({ }} /> {lvls + .reverse() .map((x) => (