feat: sync deployed v1.0.0-rc.38-custom.42
Sync production source including routing, billing, Astra detection and public uptime. Update custom build instructions and license packaging.
This commit is contained in:
1 parent
aa6c3f50f4
commit
ceddfd3d6b
828 files changed
+122253
-13702
No files matched your search
+89
-13
@@ -1,6 +1,7 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"slices"
|
||||
@@ -11,7 +12,6 @@ import (
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
"github.com/QuantumNous/new-api/i18n"
|
||||
"github.com/QuantumNous/new-api/model"
|
||||
"github.com/QuantumNous/new-api/pkg/jsplugin"
|
||||
"github.com/QuantumNous/new-api/service"
|
||||
"github.com/QuantumNous/new-api/setting"
|
||||
"github.com/QuantumNous/new-api/setting/billing_setting"
|
||||
@@ -136,6 +136,50 @@ type OptionUpdateRequest struct {
|
||||
Value any `json:"value"`
|
||||
}
|
||||
|
||||
func UpdatePasskeyDomains(c *gin.Context) {
|
||||
var request struct {
|
||||
RPID *string `json:"rp_id"`
|
||||
LegacyRPIDs *string `json:"legacy_rp_ids"`
|
||||
Origins *string `json:"origins"`
|
||||
Preview bool `json:"preview"`
|
||||
RemovalConfirmation string `json:"removal_confirmation"`
|
||||
}
|
||||
if err := common.DecodeJson(c.Request.Body, &request); err != nil || request.RPID == nil || request.LegacyRPIDs == nil || request.Origins == nil {
|
||||
common.ApiErrorI18n(c, i18n.MsgInvalidParams)
|
||||
return
|
||||
}
|
||||
change, err := model.UpdatePasskeyDomainOptions(map[string]string{
|
||||
"passkey.rp_id": *request.RPID, "passkey.legacy_rp_ids": *request.LegacyRPIDs, "passkey.origins": *request.Origins,
|
||||
}, request.Preview, request.RemovalConfirmation)
|
||||
if err != nil {
|
||||
writePasskeyDomainSettingsError(c, err)
|
||||
if !request.Preview {
|
||||
recordPasskeyDomainAudit(c, change, request.RemovalConfirmation != "", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if !request.Preview {
|
||||
recordPasskeyDomainAudit(c, change, request.RemovalConfirmation != "", nil)
|
||||
}
|
||||
common.ApiSuccess(c, change)
|
||||
}
|
||||
|
||||
func writePasskeyDomainSettingsError(c *gin.Context, err error) {
|
||||
var removal *model.PasskeyDomainRemovalError
|
||||
if errors.As(err, &removal) {
|
||||
c.JSON(http.StatusConflict, gin.H{
|
||||
"success": false, "code": "PASSKEY_RP_ID_REMOVAL_CONFIRMATION_REQUIRED",
|
||||
"message": i18n.T(c, i18n.MsgPasskeyRPIDRemovalConfirmation), "data": removal.Change,
|
||||
})
|
||||
return
|
||||
}
|
||||
if errors.Is(err, system_setting.ErrPasskeyRPIDInvalid) {
|
||||
writeSecurityOperationError(c, err)
|
||||
return
|
||||
}
|
||||
common.ApiError(c, err)
|
||||
}
|
||||
|
||||
func UpdateOption(c *gin.Context) {
|
||||
var option OptionUpdateRequest
|
||||
err := common.DecodeJson(c.Request.Body, &option)
|
||||
@@ -359,25 +403,42 @@ func UpdateOption(c *gin.Context) {
|
||||
models = append(models, modelName)
|
||||
}
|
||||
sort.Strings(models)
|
||||
generation := jsplugin.DefaultRegistry.Generation()
|
||||
storedVariants := billing_setting.GetPluginBillingExprCopy()
|
||||
for _, modelName := range models {
|
||||
expression := expressions[modelName]
|
||||
if plugin, ok := generation.GetByModel(modelName); ok {
|
||||
err = billing_setting.SmokeTestTaskExpr(expression, plugin.Meta.UsageSchema)
|
||||
} else if target, resolved := model.ResolveTaskModelAlias(generation, modelName); resolved {
|
||||
if plugin, ok := generation.Get(target.PluginKey); ok {
|
||||
err = billing_setting.SmokeTestTaskExpr(expression, plugin.Meta.UsageSchema)
|
||||
} else {
|
||||
err = billing_setting.SmokeTestExpr(expression)
|
||||
variants := make(map[string]any)
|
||||
for key, expression := range storedVariants {
|
||||
if plugin, name, ok := billing_setting.SplitPluginBillingExprKey(key); ok && name == modelName {
|
||||
variants[plugin] = expression
|
||||
}
|
||||
} else {
|
||||
err = billing_setting.SmokeTestExpr(expression)
|
||||
}
|
||||
err = model.ValidateModelPricing(modelName, model.PricingValues{
|
||||
"billing_setting.billing_expr": expressions[modelName],
|
||||
billing_setting.PluginBillingExprOption: variants,
|
||||
})
|
||||
if err != nil {
|
||||
common.ApiErrorMsg(c, fmt.Sprintf("模型 %s 的计费表达式无效: %v", modelName, err))
|
||||
return
|
||||
}
|
||||
}
|
||||
case billing_setting.PluginBillingExprOption:
|
||||
var expressions map[string]string
|
||||
if err = common.UnmarshalJsonStr(option.Value.(string), &expressions); err != nil || expressions == nil {
|
||||
common.ApiErrorMsg(c, "plugin billing expressions must be a JSON object")
|
||||
return
|
||||
}
|
||||
for key, expression := range expressions {
|
||||
plugin, name, valid := billing_setting.SplitPluginBillingExprKey(key)
|
||||
if !valid {
|
||||
common.ApiErrorMsg(c, "invalid plugin billing expression key: "+key)
|
||||
return
|
||||
}
|
||||
if err = model.ValidateModelPricing(name, model.PricingValues{
|
||||
billing_setting.PluginBillingExprOption: map[string]any{plugin: expression},
|
||||
}); err != nil {
|
||||
common.ApiErrorMsg(c, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
case "console_setting.api_info":
|
||||
err = console_setting.ValidateConsoleSettings(option.Value.(string), "ApiInfo")
|
||||
if err != nil {
|
||||
@@ -415,9 +476,24 @@ func UpdateOption(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if model.IsPasskeyDomainOption(option.Key) {
|
||||
change, updateErr := model.UpdatePasskeyDomainOptions(map[string]string{option.Key: option.Value.(string)}, false, "")
|
||||
if updateErr != nil {
|
||||
writePasskeyDomainSettingsError(c, updateErr)
|
||||
recordPasskeyDomainAudit(c, change, false, updateErr)
|
||||
return
|
||||
}
|
||||
recordPasskeyDomainAudit(c, change, false, nil)
|
||||
common.ApiSuccess(c, change)
|
||||
return
|
||||
}
|
||||
err = model.UpdateOption(option.Key, option.Value.(string))
|
||||
if err != nil {
|
||||
common.ApiError(c, err)
|
||||
if errors.Is(err, system_setting.ErrPasskeyRPIDInvalid) {
|
||||
writeSecurityOperationError(c, err)
|
||||
} else {
|
||||
common.ApiError(c, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
// 出于安全考虑只记录被修改的配置项名称,不记录配置值(可能含密钥等敏感信息)。
|
||||
|
||||
Reference in new issue
Block a user