diff --git a/kernel/mobile/kernel.go b/kernel/mobile/kernel.go index 7e2e01a79..769a061af 100644 --- a/kernel/mobile/kernel.go +++ b/kernel/mobile/kernel.go @@ -18,12 +18,16 @@ package mobile import ( "fmt" + "net/http" "os" "path/filepath" + "strconv" "strings" "time" + "github.com/88250/gulu" "github.com/siyuan-note/filelock" + "github.com/siyuan-note/httpclient" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/cache" "github.com/siyuan-note/siyuan/kernel/job" @@ -34,6 +38,124 @@ import ( _ "golang.org/x/mobile/bind" ) +// VerifyAppStoreTransaction 用于验证苹果 App Store 交易。 +// +// accountToken UUID: +// +// 6ba7b810-9dad-11d1-0001-377616491562 +// 6ba7b810-9dad-11d1-{Cloud Region}00{User ID},中间的 00 为保留位 +// +// 返回码: +// +// 0:验证通过 +// -1:云端区域无效 +// -2:服务器通讯失败,需要重试 +// -3:非 iOS 设备 +// -4:账号未登录 +// -5:账号状态异常 +// -6:参数错误 +// -7:校验 accountToken 失败 +// -8:校验 transaction 失败 +func VerifyAppStoreTransaction(accountToken, transactionID string) (retCode int, retMsg string) { + retCode = -2 + retMsg = "unknown error" + + if util.ContainerIOS != util.Container { + retCode = -3 + retMsg = fmt.Sprintf("invalid container [%s]", util.Container) + logging.LogErrorf(retMsg) + return + } + + cloudRegionArg := accountToken[19:20] + if "0" != cloudRegionArg && "1" != cloudRegionArg { + retCode = -1 + retMsg = fmt.Sprintf("invalid cloud region [%s]", cloudRegionArg) + logging.LogErrorf(retMsg) + return + } + + cloudRegion, _ := strconv.Atoi(cloudRegionArg) + if util.CurrentCloudRegion != cloudRegion { + retCode = -1 + retMsg = fmt.Sprintf("invalid cloud region [cloudRegionArg=%s, currentRegion=%d]", cloudRegionArg, util.CurrentCloudRegion) + logging.LogErrorf(retMsg) + return + } + + userID := strings.ReplaceAll(accountToken[22:], "-", "") + verifyURL := util.GetCloudServer() + "/apis/siyuan/verifyAppStoreTransaction" + result := gulu.Ret.NewResult() + request := httpclient.NewCloudRequest30s() + resp, reqErr := request.SetSuccessResult(result).SetCookies(&http.Cookie{Name: "symphony", Value: model.Conf.GetUser().UserToken}). + SetBody(map[string]string{"transactionId": transactionID, "accountToken": accountToken, "userId": userID}).Post(verifyURL) + if nil != reqErr { + retCode = -2 + retMsg = fmt.Sprintf("verify app store transaction failed: %s", reqErr) + logging.LogErrorf(retMsg) + return + } + if http.StatusUnauthorized == resp.StatusCode || http.StatusForbidden == resp.StatusCode { + retCode = -4 + retMsg = fmt.Sprintf("verify app store transaction failed [sc=%d]", resp.StatusCode) + logging.LogErrorf(retMsg) + return + } + if http.StatusOK != resp.StatusCode { + retCode = -2 + retMsg = fmt.Sprintf("verify app store transaction failed [sc=%d]", resp.StatusCode) + logging.LogErrorf(retMsg) + return + } + + if -1 == result.Code { + retCode = -5 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + if -3 == result.Code { + retCode = -6 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + if -2 == result.Code { + retCode = -8 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + if -4 == result.Code { + retCode = -8 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + if -5 == result.Code { + retCode = -7 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + if -64 == result.Code { + retCode = -2 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + if 0 != result.Code { + retCode = -2 + retMsg = fmt.Sprintf("verify app store transaction failed [code=%d]", result.Code) + logging.LogErrorf(retMsg) + return + } + + retCode = 0 + retMsg = "verify app store transaction success" + return +} + func StartKernelFast(container, appDir, workspaceBaseDir, localIPs string) { go server.Serve(true) }