feat: add telescope
This commit is contained in:
@@ -95,16 +95,22 @@ func (t *TapsellAdVerifier) Verify(ctx context.Context, userID int64, token stri
|
||||
return out.Valid && out.Completed, nil
|
||||
}
|
||||
|
||||
// --- مایکت: تأیید سمتسرور با X-Access-Token ---
|
||||
// --- مایکت: تأیید امضای RSA آفلاین (اولویت) یا سمتسرور با X-Access-Token ---
|
||||
//
|
||||
// افزونهی myket_iap مثلِ کافهبازار، purchaseData (JSONِ خام) و signature (base64)
|
||||
// برمیگرداند که با کلیدِ عمومیِ RSA و SHA1withRSA بهصورتِ آفلاین تأیید میشوند —
|
||||
// بدونِ رفتوبرگشتِ شبکه بهازای هر خرید. اگر کلیدِ عمومی تنظیم نشده باشد یا امضا
|
||||
// ارسال نشده باشد، به تأییدِ سمتسرور برمیگردیم:
|
||||
// GET https://developer.myket.ir/api/applications/{pkg}/purchases/products/{sku}/tokens/{token}
|
||||
// هدر: X-Access-Token: <accessToken> . پاسخ purchaseState=0 یعنی معتبر (غیرِ صفر=مسترد).
|
||||
type MyketVerifier struct {
|
||||
PackageName string
|
||||
AccessToken string
|
||||
pub *rsa.PublicKey // کلیدِ عمومیِ RSA برای تأییدِ آفلاین (اختیاری)
|
||||
client *http.Client
|
||||
}
|
||||
|
||||
// NewMyketVerifier یک تأییدکننده با access token (سمتسرور) میسازد.
|
||||
func NewMyketVerifier(pkg, accessToken string) *MyketVerifier {
|
||||
return &MyketVerifier{
|
||||
PackageName: pkg,
|
||||
@@ -113,7 +119,33 @@ func NewMyketVerifier(pkg, accessToken string) *MyketVerifier {
|
||||
}
|
||||
}
|
||||
|
||||
// WithRSAKey کلیدِ عمومیِ RSA را برای تأییدِ آفلاین ضمیمه میکند (اگر خالی نباشد).
|
||||
func (v *MyketVerifier) WithRSAKey(publicKey string) (*MyketVerifier, error) {
|
||||
if strings.TrimSpace(publicKey) == "" {
|
||||
return v, nil
|
||||
}
|
||||
pub, err := parseRSAPublicKey(publicKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("myket rsa: %w", err)
|
||||
}
|
||||
v.pub = pub
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func (v *MyketVerifier) Verify(ctx context.Context, p IAPProof) (bool, error) {
|
||||
// مسیرِ ترجیحی: تأییدِ امضای آفلاین (اگر کلید و امضا موجود باشند).
|
||||
if v.pub != nil && p.PurchaseData != "" && p.Signature != "" {
|
||||
sig, err := base64.StdEncoding.DecodeString(p.Signature)
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("myket: bad signature encoding: %w", err)
|
||||
}
|
||||
h := sha1.Sum([]byte(p.PurchaseData))
|
||||
if err := rsa.VerifyPKCS1v15(v.pub, crypto.SHA1, h[:], sig); err != nil {
|
||||
return false, nil // امضای نامعتبر ⇒ خریدِ نامعتبر
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
// مسیرِ جایگزین: تأییدِ سمتسرور با access token.
|
||||
if v.AccessToken == "" || p.Token == "" {
|
||||
return false, fmt.Errorf("myket: missing access token or purchase token")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user