Files
past-go/past-go/internal/handler/account.go
T
Blizzard 8be6d9b1ab feat: add account deletion, announcements and subscription renewal
Support personal records and persistent smoking visibility. Add upload quota preflight, file cleanup, privacy entry, image caching and revision-based page refresh across the backend, admin and mini program.
2026-11-03 22:06:47 +08:00

59 lines
1.8 KiB
Go

package handler
import (
"context"
"crypto/sha256"
"encoding/hex"
"errors"
"past/internal/httpapi"
"past/internal/store"
"time"
)
func deletionKey(c *httpapi.Ctx, token string) string {
h := sha256.Sum256([]byte(token))
return c.App.Wechat.KeyPrefix + "account-delete:" + c.UID() + ":" + hex.EncodeToString(h[:])
}
func accountDeletionPreview(c *httpapi.Ctx) error {
if err := c.RequirePOST(); err != nil {
return err
}
s, err := c.DB.AccountDeletionSummary(c.UID())
if errors.Is(err, store.ErrAccountBound) {
return c.Err(409, err.Error())
}
if err != nil {
return err
}
token := httpapi.NewToken()
ctx, cancel := context.WithTimeout(c.R.Context(), 3*time.Second)
defer cancel()
if err := c.App.Wechat.Redis.Set(ctx, deletionKey(c, token), s.Revision, 5*time.Minute).Err(); err != nil {
return err
}
return c.OK(M{"summary": s, "confirmation_token": token, "expires_in": 300})
}
func accountDelete(c *httpapi.Ctx) error {
if err := c.RequirePOST(); err != nil {
return err
}
if c.In("confirmed") != true || c.InStr("confirmation_text") != "注销并删除全部数据" || c.InStr("confirmation_token") == "" {
return c.Err(400, "请完成二次确认")
}
ctx, cancel := context.WithTimeout(c.R.Context(), 5*time.Second)
defer cancel()
revision, err := c.App.Wechat.Redis.Get(ctx, deletionKey(c, c.InStr("confirmation_token"))).Result()
if err != nil || revision == "" {
return c.Err(409, "确认已过期,请重新查看注销数据统计")
}
err = c.DB.DeleteAccount(c.UID(), revision)
if errors.Is(err, store.ErrAccountBound) || errors.Is(err, store.ErrAccountChanged) {
return c.Err(409, err.Error())
}
if err != nil {
return err
}
c.App.Wechat.Redis.Del(ctx, deletionKey(c, c.InStr("confirmation_token")))
return c.OK(M{"success": true, "message": "账号及内容已删除,独占的存储文件正在清理"})
}