feat(ECR-013B): AccountLifecycle Closed;启用 Loop 连续执行

UserStatus 迁移、DeviceAuth 拒绝非 active、admin-h5 CTA;
Reviewer Closed。Human 授权 LOOP_AUTHORIZATION(免逐闸确认)。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
jackyu66git
2026-08-07 17:47:18 +08:00
co-authored by Cursor
parent f75b42397f
commit e25cd94b0c
33 changed files with 799 additions and 56 deletions
+20
View File
@@ -38,6 +38,9 @@ func DeviceAuth(pool *pgxpool.Pool) gin.HandlerFunc {
WHERE token=$1 AND revoked_at IS NULL AND expires_at > now()`, tok,
).Scan(&uid)
if err == nil {
if !ensureActiveUser(c, pool, uid) {
return
}
_, _ = pool.Exec(c.Request.Context(), `
INSERT INTO device_identities(device_key, user_id)
VALUES ($1,$2)
@@ -56,12 +59,29 @@ func DeviceAuth(pool *pgxpool.Pool) gin.HandlerFunc {
c.Abort()
return
}
if !ensureActiveUser(c, pool, userID) {
return
}
c.Set(string(UserIDKey), userID.String())
c.Header(DeviceKeyHeader, key)
c.Next()
}
}
// ensureActiveUser aborts with 401 when UserStatus is not active.
func ensureActiveUser(c *gin.Context, pool *pgxpool.Pool, userID uuid.UUID) bool {
var status string
err := pool.QueryRow(c.Request.Context(), `
SELECT status FROM users WHERE id=$1 AND deleted_at IS NULL`, userID,
).Scan(&status)
if err != nil || status != "active" {
response.Fail(c, http.StatusUnauthorized, 40113, "账户已受限")
c.Abort()
return false
}
return true
}
func bearerFromHeader(h string) string {
if len(h) < 8 {
return ""