From 20531971cf46b35622e50c5cd7274a36baa30224 Mon Sep 17 00:00:00 2001 From: Jacky Date: Fri, 7 Feb 2025 21:10:11 +0800 Subject: [PATCH] feat: encrypt login and install request #852 --- api/crypto/crypto.go | 22 +++++ api/crypto/router.go | 10 +++ api/system/router.go | 3 +- api/user/router.go | 3 +- app/package.json | 1 + app/pnpm-lock.yaml | 8 ++ app/src/api/auth.ts | 2 +- app/src/api/install.ts | 2 +- app/src/lib/http/index.ts | 90 +++++++++++---------- app/src/version.json | 2 +- app/src/vite-env.d.ts | 7 ++ go.sum | 61 -------------- internal/middleware/encrypted_params.go | 46 +++++++++++ internal/sign/crypto.go | 102 ++++++++++++++++++++++++ internal/sign/errors.go | 12 +++ router/routers.go | 2 + 16 files changed, 265 insertions(+), 108 deletions(-) create mode 100644 api/crypto/crypto.go create mode 100644 api/crypto/router.go create mode 100644 internal/middleware/encrypted_params.go create mode 100644 internal/sign/crypto.go create mode 100644 internal/sign/errors.go diff --git a/api/crypto/crypto.go b/api/crypto/crypto.go new file mode 100644 index 00000000..8a6ad90f --- /dev/null +++ b/api/crypto/crypto.go @@ -0,0 +1,22 @@ +package crypto + +import ( + "net/http" + + "github.com/0xJacky/Nginx-UI/api" + "github.com/0xJacky/Nginx-UI/internal/sign" + "github.com/gin-gonic/gin" +) + +// GetPublicKey generates a new ED25519 key pair and registers it in the cache +func GetPublicKey(c *gin.Context) { + sign, err := sign.GetCryptoParams() + if err != nil { + api.ErrHandler(c, err) + return + } + + c.JSON(http.StatusOK, gin.H{ + "public_key": sign.PublicKey, + }) +} diff --git a/api/crypto/router.go b/api/crypto/router.go new file mode 100644 index 00000000..c9455fa6 --- /dev/null +++ b/api/crypto/router.go @@ -0,0 +1,10 @@ +package crypto + +import "github.com/gin-gonic/gin" + +func InitPublicRouter(r *gin.RouterGroup) { + g := r.Group("/crypto") + { + g.GET("public_key", GetPublicKey) + } +} diff --git a/api/system/router.go b/api/system/router.go index 8c3fa1f0..e0b019b7 100644 --- a/api/system/router.go +++ b/api/system/router.go @@ -1,12 +1,13 @@ package system import ( + "github.com/0xJacky/Nginx-UI/internal/middleware" "github.com/gin-gonic/gin" ) func InitPublicRouter(r *gin.RouterGroup) { r.GET("install", InstallLockCheck) - r.POST("install", InstallNginxUI) + r.POST("install", middleware.EncryptedParams(), InstallNginxUI) r.GET("translation/:code", GetTranslation) } diff --git a/api/user/router.go b/api/user/router.go index 0222697b..ee390dc3 100644 --- a/api/user/router.go +++ b/api/user/router.go @@ -1,11 +1,12 @@ package user import ( + "github.com/0xJacky/Nginx-UI/internal/middleware" "github.com/gin-gonic/gin" ) func InitAuthRouter(r *gin.RouterGroup) { - r.POST("/login", Login) + r.POST("/login", middleware.EncryptedParams(), Login) r.DELETE("/logout", Logout) r.GET("/begin_passkey_login", BeginPasskeyLogin) diff --git a/app/package.json b/app/package.json index 9cdf8c6c..2476a370 100644 --- a/app/package.json +++ b/app/package.json @@ -30,6 +30,7 @@ "axios": "^1.7.9", "dayjs": "^1.11.13", "highlight.js": "^11.11.1", + "jsencrypt": "^3.3.2", "lodash": "^4.17.21", "marked": "^15.0.6", "marked-highlight": "^2.2.1", diff --git a/app/pnpm-lock.yaml b/app/pnpm-lock.yaml index 90f306e7..575d6f22 100644 --- a/app/pnpm-lock.yaml +++ b/app/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: highlight.js: specifier: ^11.11.1 version: 11.11.1 + jsencrypt: + specifier: ^3.3.2 + version: 3.3.2 lodash: specifier: ^4.17.21 version: 4.17.21 @@ -3122,6 +3125,9 @@ packages: resolution: {integrity: sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==} engines: {node: '>=12.0.0'} + jsencrypt@3.3.2: + resolution: {integrity: sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==} + jsesc@0.5.0: resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} hasBin: true @@ -7904,6 +7910,8 @@ snapshots: jsdoc-type-pratt-parser@4.1.0: {} + jsencrypt@3.3.2: {} + jsesc@0.5.0: {} jsesc@3.0.2: {} diff --git a/app/src/api/auth.ts b/app/src/api/auth.ts index 3605f0c1..59891fa9 100644 --- a/app/src/api/auth.ts +++ b/app/src/api/auth.ts @@ -19,7 +19,7 @@ const auth = { password, otp, recovery_code: recoveryCode, - }) + }, { crypto: true }) }, async casdoor_login(code?: string, state?: string) { await http.post('/casdoor_callback', { diff --git a/app/src/api/install.ts b/app/src/api/install.ts index b2f11dd6..5b4abade 100644 --- a/app/src/api/install.ts +++ b/app/src/api/install.ts @@ -12,7 +12,7 @@ const install = { return http.get('/install') }, install_nginx_ui(data: InstallRequest) { - return http.post('/install', data) + return http.post('/install', data, { crypto: true }) }, } diff --git a/app/src/lib/http/index.ts b/app/src/lib/http/index.ts index bbbf5a46..e745b903 100644 --- a/app/src/lib/http/index.ts +++ b/app/src/lib/http/index.ts @@ -5,6 +5,7 @@ import { useSettingsStore, useUserStore } from '@/pinia' import router from '@/routes' import { message } from 'ant-design-vue' import axios from 'axios' +import JSEncrypt from 'jsencrypt' import { storeToRefs } from 'pinia' import 'nprogress/nprogress.css' @@ -33,16 +34,35 @@ const instance = axios.create({ baseURL: import.meta.env.VITE_API_ROOT, timeout: 50000, headers: { 'Content-Type': 'application/json' }, - transformRequest: [function (data, headers) { - if (!(headers) || headers['Content-Type'] === 'multipart/form-data;charset=UTF-8') - return data - else - headers['Content-Type'] = 'application/json' - - return JSON.stringify(data) - }], }) +const http = { + get(url: string, config: AxiosRequestConfig = {}) { + // eslint-disable-next-line ts/no-explicit-any + return instance.get(url, config) + }, + // eslint-disable-next-line ts/no-explicit-any + post(url: string, data: any = undefined, config: AxiosRequestConfig = {}) { + // eslint-disable-next-line ts/no-explicit-any + return instance.post(url, data, config) + }, + // eslint-disable-next-line ts/no-explicit-any + put(url: string, data: any = undefined, config: AxiosRequestConfig = {}) { + // eslint-disable-next-line ts/no-explicit-any + return instance.put(url, data, config) + }, + delete(url: string, config: AxiosRequestConfig = {}) { + // eslint-disable-next-line ts/no-explicit-any + return instance.delete(url, config) + }, + patch(url: string, config: AxiosRequestConfig = {}) { + // eslint-disable-next-line ts/no-explicit-any + return instance.patch(url, config) + }, +} + +export default http + const nprogress = useNProgress() // Add new dedupe utility at the top @@ -65,23 +85,36 @@ function useMessageDedupe(interval = 5000): MessageDedupe { } instance.interceptors.request.use( - config => { + async config => { nprogress.start() if (token.value) { - // eslint-disable-next-line ts/no-explicit-any - (config.headers as any).Authorization = token.value + config.headers.Authorization = token.value } if (settings.environment.id) { - // eslint-disable-next-line ts/no-explicit-any - (config.headers as any)['X-Node-ID'] = settings.environment.id + config.headers['X-Node-ID'] = settings.environment.id } if (secureSessionId.value) { - // eslint-disable-next-line ts/no-explicit-any - (config.headers as any)['X-Secure-Session-ID'] = secureSessionId.value + config.headers['X-Secure-Session-ID'] = secureSessionId.value } + if (config.headers?.['Content-Type'] !== 'multipart/form-data;charset=UTF-8') { + config.headers['Content-Type'] = 'application/json' + + if (config.crypto) { + const cryptoParams = await http.get('/crypto/public_key') + const { public_key } = await cryptoParams + + // Encrypt data with RSA public key + const encrypt = new JSEncrypt() + encrypt.setPublicKey(public_key) + + config.data = JSON.stringify({ + encrypted_params: encrypt.encrypt(JSON.stringify(config.data)), + }) + } + } return config }, err => { @@ -154,30 +187,3 @@ instance.interceptors.response.use( return Promise.reject(error.response.data) }, ) - -const http = { - get(url: string, config: AxiosRequestConfig = {}) { - // eslint-disable-next-line ts/no-explicit-any - return instance.get(url, config) - }, - // eslint-disable-next-line ts/no-explicit-any - post(url: string, data: any = undefined, config: AxiosRequestConfig = {}) { - // eslint-disable-next-line ts/no-explicit-any - return instance.post(url, data, config) - }, - // eslint-disable-next-line ts/no-explicit-any - put(url: string, data: any = undefined, config: AxiosRequestConfig = {}) { - // eslint-disable-next-line ts/no-explicit-any - return instance.put(url, data, config) - }, - delete(url: string, config: AxiosRequestConfig = {}) { - // eslint-disable-next-line ts/no-explicit-any - return instance.delete(url, config) - }, - patch(url: string, config: AxiosRequestConfig = {}) { - // eslint-disable-next-line ts/no-explicit-any - return instance.patch(url, config) - }, -} - -export default http diff --git a/app/src/version.json b/app/src/version.json index b30487a6..5aae41e6 100644 --- a/app/src/version.json +++ b/app/src/version.json @@ -1 +1 @@ -{"version":"2.0.0-rc.1","build_id":7,"total_build":381} \ No newline at end of file +{"version":"2.0.0-rc.1","build_id":8,"total_build":382} \ No newline at end of file diff --git a/app/src/vite-env.d.ts b/app/src/vite-env.d.ts index 9c236552..dfd82789 100644 --- a/app/src/vite-env.d.ts +++ b/app/src/vite-env.d.ts @@ -27,3 +27,10 @@ declare module '@vue/runtime-core' { }, disableHtmlEscaping?: boolean) => string } } + +declare module 'axios' { + interface AxiosRequestConfig { + crypto?: boolean + skipErrHandling?: boolean + } +} diff --git a/go.sum b/go.sum index df9ff26d..00c672ea 100644 --- a/go.sum +++ b/go.sum @@ -712,28 +712,16 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/aws/aws-sdk-go v1.40.45/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v1.9.1/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2 v1.35.0 h1:jTPxEJyzjSuuz0wB+302hr8Eu9KUI+Zv8zlujMGJpVI= -github.com/aws/aws-sdk-go-v2 v1.35.0/go.mod h1:JgstGg0JjWU1KpVJjD5H0y0yyAIpSdKEq556EI6yOOM= github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk= github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM= -github.com/aws/aws-sdk-go-v2/config v1.29.3 h1:a5Ucjxe6iV+LHEBmYA9w40rT5aGxWybx/4l/O/fvJlE= -github.com/aws/aws-sdk-go-v2/config v1.29.3/go.mod h1:pt9z1x12zDiDb4iFLrxoeAKLVCU/Gp9DL/5BnwlY77o= github.com/aws/aws-sdk-go-v2/config v1.29.5 h1:4lS2IB+wwkj5J43Tq/AwvnscBerBJtQQ6YS7puzCI1k= github.com/aws/aws-sdk-go-v2/config v1.29.5/go.mod h1:SNzldMlDVbN6nWxM7XsUiNXPSa1LWlqiXtvh/1PrJGg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.56 h1:JKMBreKudV+ozx6rZJLvEtiexv48aEdhdC7mXUw9MLs= -github.com/aws/aws-sdk-go-v2/credentials v1.17.56/go.mod h1:S3xRjIHD8HHFgMTz4L56q/7IldfNtGL9JjH/vP3U6DA= github.com/aws/aws-sdk-go-v2/credentials v1.17.58 h1:/d7FUpAPU8Lf2KUdjniQvfNdlMID0Sd9pS23FJ3SS9Y= github.com/aws/aws-sdk-go-v2/credentials v1.17.58/go.mod h1:aVYW33Ow10CyMQGFgC0ptMRIqJWvJ4nxZb0sUiuQT/A= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.26 h1:XMBqBEuZLf8yxtH+mU/uUDyQbN4iD/xv9h6he2+lzhw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.26/go.mod h1:d0+wQ/3CYGPuHEfBTPpQdfUX7gjk0/Lxs5Q6KzdEGY8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27 h1:7lOW8NUwE9UZekS1DYoiPdVAqZ6A+LheHWb+mHbNOq8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.27/go.mod h1:w1BASFIPOPUae7AgaH4SbjNbfdkxuggLyGfNFTn8ITY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.30 h1:+7AzSGNhHoY53di13lvztf9Dyd/9ofzoYGBllkWp3a0= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.30/go.mod h1:Jxd/FrCny99yURiQiMywgXvBhd7tmgdv6KdlUTNzMSo= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.30 h1:Ex06eY6I5rO7IX0HalGfa5nGjpBoOsS1Qm3xfjkuszs= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.30/go.mod h1:AvyEMA9QcX59kFhVizBpIBpEMThUTXssuJe+emBdcGM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2 h1:Pg9URiobXy85kgFev3og2CuOZ8JZUBENF+dcgWBaYNk= @@ -741,28 +729,16 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.2/go.mod h1:FbtygfRFze9usAadmnGJN github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.8.1/go.mod h1:CM+19rL1+4dFWnOQKwDc7H1KwXTz+h61oUSHyhV0b3o= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2 h1:D4oz8/CzT9bAEYtVhSBmFj2dNOtaHOtMKc2vHBwYizA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.2/go.mod h1:Za3IHqTQ+yNcRHxu1OFucBh0ACZT4j4VQFF0BqpZcLY= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.11 h1:5JKQ2J3BBW4ovy6A/5Lwx9SpA6IzgH8jB3bquGZ1NUw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.11/go.mod h1:VShCk7rfCzK/b9U1aSkzLwcOoaDlYna16482QqEavis= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12 h1:O+8vD2rGjfihBewr5bT+QUfYUHIxCVgG61LHoT59shM= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.12/go.mod h1:usVdWJaosa66NMvmCrr08NcWDBRv4E6+YFG2pUdw1Lk= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.13 h1:yukUijkcclShNo3QXry+udZDyDQOy8siCjqNfpRKuf8= -github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.13/go.mod h1:Ka+a4bm2nmtvk+Ql1K2Bmr7MrJCs8qz4UDmaLQs1daY= github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.14 h1:GH3vnPsdH2sTkZRBPnAeMqwkJXdwPNrEh9nI+DEdD0o= github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.14/go.mod h1:fHFrxpH3kA2iK2NBg/jj3jxgVVfNS7WaKYC5axxr/PY= -github.com/aws/aws-sdk-go-v2/service/route53 v1.48.4 h1:qajhoD/ElVskbXAJfgljClGj7DGME0uoDGUMVjFTkNs= -github.com/aws/aws-sdk-go-v2/service/route53 v1.48.4/go.mod h1:kDfNqSNtcqB8aNUJClykJ+xLILNoYAaUIo72A2uR73Y= github.com/aws/aws-sdk-go-v2/service/route53 v1.48.6 h1:O7L9iEodiF07vJoXShMrw2XyeAqZhLUIXqWEitCq6EE= github.com/aws/aws-sdk-go-v2/service/route53 v1.48.6/go.mod h1:E93uWfli9RToQzVA7+bYnynKOFcYOhNWqhY1hWSMZRc= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.13 h1:q4pOAKxypbFoUJzOpgo939bF50qb4DgYshiDfcsdN0M= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.13/go.mod h1:G/0PTg7+vQT42ictQGjJhixzTcVZtHFvrN/OeTXrRfQ= github.com/aws/aws-sdk-go-v2/service/sso v1.24.14 h1:c5WJ3iHz7rLIgArznb3JCSQT3uUMiz9DLZhIX+1G8ok= github.com/aws/aws-sdk-go-v2/service/sso v1.24.14/go.mod h1:+JJQTxB6N4niArC14YNtxcQtwEqzS3o9Z32n7q33Rfs= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12 h1:4sGSGshSSfO1vrcXruPick3ioSf8nhhD6nuB2ni37P4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.12/go.mod h1:NHpu/pLOelViA4qxkAFH10VLqh+XeLhZfXDaFyMVgSs= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13 h1:f1L/JtUkVODD+k1+IiSJUUv8A++2qVr+Xvb3xWXETMU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.13/go.mod h1:tvqlFoja8/s0o+UruA1Nrezo/df0PzdunMDDurUfg6U= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.11 h1:RIXOjp7Dp4siCYJRwBHUcBdVgOWflSJGlq4ZhMI5Ta0= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.11/go.mod h1:ZR17k9bPKPR8u0IkyA6xVsjr56doNQ4ZB1fs7abYBfE= github.com/aws/aws-sdk-go-v2/service/sts v1.33.13 h1:3LXNnmtH3TURctC23hnC0p/39Q5gre3FI7BNOiDcVWc= github.com/aws/aws-sdk-go-v2/service/sts v1.33.13/go.mod h1:7Yn+p66q/jt38qMoVfNvjbm3D89mGBnkwDcijgtih8w= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= @@ -806,7 +782,6 @@ github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -1558,8 +1533,6 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b h1:FfH+VrHHk6Lxt9HdVS0PXzSXFyS2NbZKXv33FYPol0A= github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b/go.mod h1:AC62GU6hc0BrNm+9RK9VSiwa/EUe1bkIeFORAMcHvJU= github.com/openzipkin/zipkin-go v0.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= -github.com/oracle/oci-go-sdk/v65 v65.82.0 h1:42fSqE847E95ICfVPcKhRmzkvM6tucwbPdUMQydfWGc= -github.com/oracle/oci-go-sdk/v65 v65.82.0/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0= github.com/oracle/oci-go-sdk/v65 v65.83.0 h1:KFI0oyyCTPmgevHF+QlN02Zdf23Jx1p1X+4KPyH14H8= github.com/oracle/oci-go-sdk/v65 v65.83.0/go.mod h1:IBEV9l1qBzUpo7zgGaRUhbB05BVfcDGYRFBCPlTcPp0= github.com/ovh/go-ovh v1.6.0 h1:ixLOwxQdzYDx296sXcgS35TOPEahJkpjMGtzPadCjQI= @@ -1678,8 +1651,6 @@ github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd github.com/sashabaranov/go-openai v1.36.1 h1:EVfRXwIlW2rUzpx6vR+aeIKCK/xylSrVYAx1TMTSX3g= github.com/sashabaranov/go-openai v1.36.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31 h1:Fj7jPyu9TQjqfXcLylINK5PANSzOWXIX4QtGmfp67AY= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.31/go.mod h1:kzh+BSAvpoyHHdHBCDhmSWtBc1NbLMZ2lWHqnBoxFks= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.32 h1:4+LP7qmsLSGbmc66m1s5dKRMBwztRppfxFKlYqYte/c= github.com/scaleway/scaleway-sdk-go v1.0.0-beta.32/go.mod h1:kzh+BSAvpoyHHdHBCDhmSWtBc1NbLMZ2lWHqnBoxFks= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= @@ -1687,8 +1658,6 @@ github.com/selectel/domains-go v1.1.0 h1:futG50J43ALLKQAnZk9H9yOtLGnSUh7c5hSvuC5 github.com/selectel/domains-go v1.1.0/go.mod h1:SugRKfq4sTpnOHquslCpzda72wV8u0cMBHx0C0l+bzA= github.com/selectel/go-selvpcclient/v3 v3.2.1 h1:ny6WIAMiHzKxOgOEnwcWE79wIQij1AHHylzPA41MXCw= github.com/selectel/go-selvpcclient/v3 v3.2.1/go.mod h1:3EfSf8aEWyhspOGbvZ6mvnFg7JN5uckxNyBFPGWsXNQ= -github.com/shirou/gopsutil/v4 v4.24.12 h1:qvePBOk20e0IKA1QXrIIU+jmk+zEiYVVx06WjBRlZo4= -github.com/shirou/gopsutil/v4 v4.24.12/go.mod h1:DCtMPAad2XceTeIAbGyVfycbYQNBGk2P8cvDi7/VN9o= github.com/shirou/gopsutil/v4 v4.25.1 h1:QSWkTc+fu9LTAWfkZwZ6j8MSUk4A2LV7rbH0ZqmLjXs= github.com/shirou/gopsutil/v4 v4.25.1/go.mod h1:RoUCUpndaJFtT+2zsZzzmhvbfGoDCJ7nFXKJf8GqJbI= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= @@ -1780,12 +1749,8 @@ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69 github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1090 h1:0fZ+FZE7ZvqxGdYbtQW8OyPXGD1qGPmg4wT+Tjkv+1s= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1090/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1091 h1:RxogX8ZCPBmZ6PY7DjnWnwGRkAkYEEinT5WNNxbLVeo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1091/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1090 h1:8AXFluT9RV4EeWC7kfJUWjnFQlIJ4pBVC/+Qtqgg0hM= -github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1090/go.mod h1:/XMAs17Sih+pqp/Pxy0WpmdZE/CychzXEnW/tTrCujk= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1091 h1:36WwNgrtoGKszQovUj3+0CjNsM1gMQ3a5lvZx2bkjng= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1091/go.mod h1:cWRGvOUnMQMky4oliMX1dXT6Z4CbsSGOIxaUcrD5Zvw= github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho= @@ -1816,8 +1781,6 @@ github.com/uozi-tech/cosy-driver-mysql v0.2.2 h1:22S/XNIvuaKGqxQPsYPXN8TZ8hHjCQd github.com/uozi-tech/cosy-driver-mysql v0.2.2/go.mod h1:EZnRIbSj1V5U0gEeTobrXai/d1SV11lkl4zP9NFEmyE= github.com/uozi-tech/cosy-driver-postgres v0.2.1 h1:OICakGuT+omva6QOJCxTJ5Lfr7CGXLmk/zD+aS51Z2o= github.com/uozi-tech/cosy-driver-postgres v0.2.1/go.mod h1:eAy1A89yHbAEfjkhNAifaJQk172NqrNoRyRtFcZc9Go= -github.com/uozi-tech/cosy-driver-sqlite v0.2.0 h1:eTpIMyGoFUK4JcaiKfJHD5AyiM6vtCwN98c7Bz5n25o= -github.com/uozi-tech/cosy-driver-sqlite v0.2.0/go.mod h1:87a6mzn5IuEtIR4z7U4Ey8eKLGfNEOSkv7kPQlbNQgM= github.com/uozi-tech/cosy-driver-sqlite v0.2.1 h1:W+Z4pY25PSJCeReqroG7LIBeffsqotbpHzgqSMqZDIM= github.com/uozi-tech/cosy-driver-sqlite v0.2.1/go.mod h1:2ya7Z5P3HzFi1ktfL8gvwaAGx0DDV0bmWxNSNpaLlwo= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= @@ -1840,12 +1803,8 @@ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2 github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yandex-cloud/go-genproto v0.0.0-20250127124313-5be1a2cc06d4 h1:3N8k0k2YikzqQUUAFqPhbhiLEodQrRKIvlsUuJ09DYo= -github.com/yandex-cloud/go-genproto v0.0.0-20250127124313-5be1a2cc06d4/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo= github.com/yandex-cloud/go-genproto v0.0.0-20250203115010-0bcba64c41f6 h1:CHYGew+KO1JaK5sx/N2ApgVCTGCKvfSl0sSPplTyCog= github.com/yandex-cloud/go-genproto v0.0.0-20250203115010-0bcba64c41f6/go.mod h1:0LDD/IZLIUIV4iPH+YcF+jysO3jkSvADFGm4dCAuwQo= -github.com/yandex-cloud/go-sdk v0.0.0-20250127132311-016f84adc072 h1:s2wfllm5Z32Sl1TktCxHXMKJ9yQXpdFUuN5CFA/8qJY= -github.com/yandex-cloud/go-sdk v0.0.0-20250127132311-016f84adc072/go.mod h1:/7UdvQNU5/ISIOPHcj0S4lUcp/KejW2LJQhZGt9tdMU= github.com/yandex-cloud/go-sdk v0.0.0-20250203123950-24786ecffd92 h1:UTcY1921ZXBABB5JpSWxccyZaCjMuSbniyifW6nmLZ4= github.com/yandex-cloud/go-sdk v0.0.0-20250203123950-24786ecffd92/go.mod h1:MQm5WxsYpQRdUklz2C8q3uDhuIaDzzV7seLErAILLBE= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= @@ -1931,8 +1890,6 @@ go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -golang.org/x/arch v0.13.0 h1:KCkqVVV1kGg0X87TFysjCJ8MxtZEIU4Ja/yXGeoECdA= -golang.org/x/arch v0.13.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/arch v0.14.0 h1:z9JUEZWr8x4rR0OU6c4/4t6E6jOZ8/QBS2bBYBm4tx4= golang.org/x/arch v0.14.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -2033,8 +1990,6 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= -golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2147,8 +2102,6 @@ golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2167,8 +2120,6 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2293,8 +2244,6 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -2335,8 +2284,6 @@ golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2347,8 +2294,6 @@ golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -2645,16 +2590,10 @@ google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOl google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak= google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= -google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287 h1:WoUI1G0DQ648FKvSl756SKxHQR/bI+y4HyyIQfxMWI8= -google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287/go.mod h1:wkQ2Aj/xvshAUDtO/JHvu9y+AaN9cqs28QuSVSHtZSY= google.golang.org/genproto v0.0.0-20250204164813-702378808489 h1:nQcbCCOg2h2CQ0yA8SY3AHqriNKDvsetuq9mE/HFjtc= google.golang.org/genproto v0.0.0-20250204164813-702378808489/go.mod h1:wkQ2Aj/xvshAUDtO/JHvu9y+AaN9cqs28QuSVSHtZSY= -google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 h1:A2ni10G3UlplFrWdCDJTl7D7mJ7GSRm37S+PDimaKRw= -google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o= google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489 h1:5bKytslY8ViY0Cj/ewmRtrWHW64bNF03cAatUUFCdFI= google.golang.org/genproto/googleapis/rpc v0.0.0-20250204164813-702378808489/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= diff --git a/internal/middleware/encrypted_params.go b/internal/middleware/encrypted_params.go new file mode 100644 index 00000000..d2a2b877 --- /dev/null +++ b/internal/middleware/encrypted_params.go @@ -0,0 +1,46 @@ +package middleware + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + + "github.com/0xJacky/Nginx-UI/internal/sign" + "github.com/gin-gonic/gin" + "github.com/uozi-tech/cosy" +) + +var ( + e = cosy.NewErrorScope("middleware") + ErrInvalidRequestFormat = e.New(40000, "invalid request format") + ErrDecryptionFailed = e.New(40001, "decryption failed") +) + +func EncryptedParams() gin.HandlerFunc { + return func(c *gin.Context) { + // 1. Read the encrypted payload + var encryptedReq struct { + EncryptedParams string `json:"encrypted_params"` + } + + if err := c.ShouldBindJSON(&encryptedReq); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, ErrInvalidRequestFormat) + return + } + + // 2. Decrypt the parameters (implement your decryption logic) + decryptedData, err := sign.Decrypt(encryptedReq.EncryptedParams) + if err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, ErrDecryptionFailed) + return + } + + // 3. Replace request body with decrypted data + newBody, _ := json.Marshal(decryptedData) + c.Request.Body = io.NopCloser(bytes.NewReader(newBody)) + c.Request.ContentLength = int64(len(newBody)) + + c.Next() + } +} diff --git a/internal/sign/crypto.go b/internal/sign/crypto.go new file mode 100644 index 00000000..0ca117a3 --- /dev/null +++ b/internal/sign/crypto.go @@ -0,0 +1,102 @@ +package sign + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/json" + "encoding/pem" + "fmt" + "time" + + "github.com/0xJacky/Nginx-UI/internal/cache" + "github.com/uozi-tech/cosy/logger" +) + +const ( + CacheKey = "sign" + timeout = 10 * time.Minute +) + +type Sign struct { + PrivateKey string `json:"-"` + PublicKey string `json:"public_key"` +} + +// GenerateRSAKeyPair generates a new RSA key pair +func GenerateRSAKeyPair() (privateKeyPEM, publicKeyPEM []byte, err error) { + privateKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + return nil, nil, err + } + privateKeyPEM = pem.EncodeToMemory(&pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: x509.MarshalPKCS1PrivateKey(privateKey), + }) + publicKeyPEM = pem.EncodeToMemory(&pem.Block{ + Type: "RSA PUBLIC KEY", + Bytes: x509.MarshalPKCS1PublicKey(&privateKey.PublicKey), + }) + return +} + +// GetCryptoParams registers a new key pair in the cache if it doesn't exist +// otherwise, it returns the existing nonce and public key +func GetCryptoParams() (sign *Sign, err error) { + // Check if key pair exists in cache + if sign, ok := cache.Get(CacheKey); ok { + return sign.(*Sign), nil + } + // Generate a nonce = hash(publicKey) + privateKeyPEM, publicKeyPEM, err := GenerateRSAKeyPair() + if err != nil { + return nil, err + } + sign = &Sign{ + PrivateKey: string(privateKeyPEM), + PublicKey: string(publicKeyPEM), + } + cache.Set(CacheKey, sign, timeout) + return +} + +// Decrypt decrypts the data with the private key (nonce, paramEncrypted) +func Decrypt(paramEncrypted string) (data map[string]interface{}, err error) { + // Get sign params from cache + sign, ok := cache.Get(CacheKey) + if !ok { + return nil, ErrTimeout + } + + signParams := sign.(*Sign) + block, _ := pem.Decode([]byte(signParams.PrivateKey)) + if block == nil { + return nil, fmt.Errorf("failed to decode PEM block containing private key") + } + + privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes) + if err != nil { + logger.Errorf("failed to parse private key: %v", err) + return nil, err + } + + paramEncryptedDecoded, err := base64.StdEncoding.DecodeString(paramEncrypted) + if err != nil { + logger.Errorf("base64 decode error: %v", err) + return nil, err + } + + decrypted, err := rsa.DecryptPKCS1v15(rand.Reader, privateKey, paramEncryptedDecoded) + if err != nil { + logger.Errorf("decryption failed: %v", err) + return nil, err + } + + err = json.Unmarshal(decrypted, &data) + if err != nil { + return nil, err + } + + return +} diff --git a/internal/sign/errors.go b/internal/sign/errors.go new file mode 100644 index 00000000..25e77969 --- /dev/null +++ b/internal/sign/errors.go @@ -0,0 +1,12 @@ +package sign + +import "github.com/uozi-tech/cosy" + +var ( + e = cosy.NewErrorScope("sign") + ErrTimeout = e.New(40401, "request timeout") + ErrInvalidNonce = e.New(50000, "invalid nonce") + ErrDecodePrivateKey = e.New(50001, "failed to decode private key") + ErrInvalidSign = e.New(50002, "invalid signature") + ErrEncryptedDataTooShort = e.New(50003, "encrypted data too short") +) diff --git a/router/routers.go b/router/routers.go index bf30752e..3bc43634 100644 --- a/router/routers.go +++ b/router/routers.go @@ -15,6 +15,7 @@ import ( "github.com/0xJacky/Nginx-UI/api/openai" "github.com/0xJacky/Nginx-UI/api/public" "github.com/0xJacky/Nginx-UI/api/settings" + "github.com/0xJacky/Nginx-UI/api/crypto" "github.com/0xJacky/Nginx-UI/api/sites" "github.com/0xJacky/Nginx-UI/api/streams" "github.com/0xJacky/Nginx-UI/api/system" @@ -42,6 +43,7 @@ func InitRouter() { root := r.Group("/api") { public.InitRouter(root) + crypto.InitPublicRouter(root) system.InitPublicRouter(root) user.InitAuthRouter(root)