feat(api): 账号环境指纹更新端点——PUT /creator/accounts/:id/fingerprint 单独保存并按需重启
- Store.UpdateAccountFingerprint:更新账号绑定环境指纹,seed 保持账号派生值,携带代理直接拒绝(门禁对齐 CreateBoundEnv) - 运行中的环境先停后启以应用新指纹,未运行仅落库下次启动生效;账号资源锁防并发冲突 - accountEnvironmentView 内联 fingerprint 回显,编辑页预填数据源 - 覆盖:store 层 seed 保留/校验拒绝/JSON 往返、路由畸形入参、PG 端到端(保存/回显/持久化/400/404)
This commit is contained in:
@@ -194,6 +194,21 @@ func registerCreatorWithServices(app *fiber.App, store *creator.Store, phaseASto
|
||||
}
|
||||
return c.JSON(profile)
|
||||
})
|
||||
// 编辑页指纹浏览器环境:单独保存;运行中的环境停后以新指纹重启,未运行仅落库下次启动生效。
|
||||
app.Put("/api/creator/accounts/:id/fingerprint", func(c fiber.Ctx) error {
|
||||
var input hub.Fingerprint
|
||||
if err := decodeCreator(c, &input); err != nil {
|
||||
return creatorError(c, err)
|
||||
}
|
||||
if hubStore == nil {
|
||||
return c.Status(fiber.StatusServiceUnavailable).JSON(map[string]string{"error": "environment store unavailable"})
|
||||
}
|
||||
view, err := updateAccountEnvironmentFingerprint(c.Context(), hubStore, c.Params("id"), input)
|
||||
if err != nil {
|
||||
return creatorError(c, err)
|
||||
}
|
||||
return c.JSON(view)
|
||||
})
|
||||
app.Put("/api/creator/accounts/:id/tags", func(c fiber.Ctx) error {
|
||||
var input struct {
|
||||
Tags []string `json:"tags"`
|
||||
@@ -739,6 +754,51 @@ func startCreatorEnvironment(ctx context.Context, store HubStore, environment hu
|
||||
return startBrowserRuntime(ctx, store, defaultNetworkExitProbe(), environment, finish)
|
||||
}
|
||||
|
||||
// updateAccountEnvironmentFingerprint 编辑页指纹浏览器环境单独保存:
|
||||
// 运行中的环境先停后启以应用新指纹;未运行仅落库,下次启动自然生效。
|
||||
// seed 属账号派生、代理属出口管理,Store 层拒绝透传入参携带。
|
||||
func updateAccountEnvironmentFingerprint(ctx context.Context, hubStore HubStore, accountID string, input hub.Fingerprint) (map[string]any, error) {
|
||||
unlock, err := lockAccountResources(ctx, hubStore, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: lock account environment: %v", creator.ErrUnavailable, err)
|
||||
}
|
||||
defer unlock()
|
||||
|
||||
environment, err := hubStore.GetEnvironmentContextForAccount(ctx, accountID)
|
||||
if errors.Is(err, hub.ErrNotFound) {
|
||||
return nil, creator.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: load account environment: %v", creator.ErrUnavailable, err)
|
||||
}
|
||||
restart := environment.RuntimeID != ""
|
||||
if restart {
|
||||
if err := stopEnvironmentRuntime(ctx, hubStore, environment); err != nil {
|
||||
return nil, fmt.Errorf("%w: stop environment before fingerprint update: %v", creator.ErrUnavailable, err)
|
||||
}
|
||||
}
|
||||
environment, err = hubStore.UpdateAccountFingerprint(ctx, accountID, input)
|
||||
if errors.Is(err, hub.ErrInvalid) {
|
||||
return nil, creator.ErrInvalid
|
||||
}
|
||||
if errors.Is(err, hub.ErrNotFound) {
|
||||
return nil, creator.ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: persist fingerprint: %v", creator.ErrUnavailable, err)
|
||||
}
|
||||
if restart {
|
||||
if err := startCreatorEnvironment(ctx, hubStore, environment); err != nil {
|
||||
return nil, fmt.Errorf("%w: restart environment with updated fingerprint: %v", creator.ErrUnavailable, err)
|
||||
}
|
||||
environment, err = hubStore.GetEnvironmentContextForAccount(ctx, accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: reload environment after fingerprint restart: %v", creator.ErrUnavailable, err)
|
||||
}
|
||||
}
|
||||
return accountEnvironmentView(environment), nil
|
||||
}
|
||||
|
||||
func creatorLoginQRCode(ctx context.Context, store *creator.Store, phaseAStore *accountdomain.Store, hubStore HubStore, accountID string) (map[string]any, error) {
|
||||
if store == nil || phaseAStore == nil || hubStore == nil || strings.TrimSpace(accountID) == "" {
|
||||
return nil, creator.ErrUnavailable
|
||||
|
||||
Reference in New Issue
Block a user