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.
59 lines
1.8 KiB
Go
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": "账号及内容已删除,独占的存储文件正在清理"})
|
|
}
|