diff --git a/server/handlers/vendors/bilibili/login.go b/server/handlers/vendors/bilibili/login.go index 8ac13544..3cdb9b53 100644 --- a/server/handlers/vendors/bilibili/login.go +++ b/server/handlers/vendors/bilibili/login.go @@ -48,7 +48,20 @@ func LoginWithQR(ctx *gin.Context) { cookie, err := bilibili.LoginWithQRCode(ctx, req.Key) if err != nil { - ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) + switch err { + case bilibili.ErrQRCodeExpired: + ctx.AbortWithStatusJSON(http.StatusBadRequest, model.NewApiErrorResp(err)) + case bilibili.ErrQRCodeScanned: + ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ + "status": "scanned", + })) + case bilibili.ErrQRCodeNotScanned: + ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ + "status": "notScanned", + })) + default: + ctx.AbortWithStatusJSON(http.StatusInternalServerError, model.NewApiErrorResp(err)) + } return } @@ -58,7 +71,9 @@ func LoginWithQR(ctx *gin.Context) { return } - ctx.Status(http.StatusNoContent) + ctx.JSON(http.StatusOK, model.NewApiDataResp(gin.H{ + "status": "success", + })) } func NewCaptcha(ctx *gin.Context) { diff --git a/vendors/bilibili/login.go b/vendors/bilibili/login.go index 748291ec..f2be9c97 100644 --- a/vendors/bilibili/login.go +++ b/vendors/bilibili/login.go @@ -2,6 +2,7 @@ package bilibili import ( "context" + "errors" "fmt" "net/http" "net/url" @@ -33,14 +34,41 @@ func NewQRCode(ctx context.Context) (*RQCode, error) { if err != nil { return nil, err } - // TODO: error message + if qr.Code != 0 { + return nil, errors.New(qr.Message) + } return &RQCode{ URL: qr.Data.URL, Key: qr.Data.QrcodeKey, }, nil } -// return SESSDATA cookie +type loginQRResp struct { + Code int `json:"code"` + Message string `json:"message"` + TTL int `json:"ttl"` + Data struct { + URL string `json:"url"` + RefreshToken string `json:"refresh_token"` + Timestamp int `json:"timestamp"` + Code uint `json:"code"` + Message string `json:"message"` + } `json:"data"` +} + +const ( + qrStatusSuccess uint = 0 + qrStatusExpired uint = 86038 + qrStatusScanned uint = 86090 + qrStatusNotScanned uint = 86101 +) + +var ( + ErrQRCodeExpired = errors.New("qr code expired") + ErrQRCodeScanned = errors.New("qr code scanned") + ErrQRCodeNotScanned = errors.New("qr code not scanned") +) + func LoginWithQRCode(ctx context.Context, key string) (*http.Cookie, error) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, fmt.Sprintf("https://passport.bilibili.com/x/passport-login/web/qrcode/poll?qrcode_key=%s", key), nil) if err != nil { @@ -53,12 +81,31 @@ func LoginWithQRCode(ctx context.Context, key string) (*http.Cookie, error) { return nil, err } defer resp.Body.Close() - for _, cookie := range resp.Cookies() { - if cookie.Name == "SESSDATA" { - return cookie, nil + var loginQRResp loginQRResp + err = json.NewDecoder(resp.Body).Decode(&loginQRResp) + if err != nil { + return nil, err + } + if loginQRResp.Code != 0 { + return nil, errors.New(loginQRResp.Message) + } + switch loginQRResp.Data.Code { + case qrStatusSuccess: + for _, cookie := range resp.Cookies() { + if cookie.Name == "SESSDATA" { + return cookie, nil + } } + return nil, fmt.Errorf("no cookie") + case qrStatusExpired: + return nil, ErrQRCodeExpired + case qrStatusScanned: + return nil, ErrQRCodeScanned + case qrStatusNotScanned: + return nil, ErrQRCodeNotScanned + default: + return nil, fmt.Errorf("unknown qr code status: %d", loginQRResp.Data.Code) } - return nil, fmt.Errorf("no SESSDATA cookie") } type CaptchaResp struct { @@ -83,6 +130,9 @@ func NewCaptcha(ctx context.Context) (*CaptchaResp, error) { if err != nil { return nil, err } + if captcha.Code != 0 { + return nil, errors.New(captcha.Message) + } return &CaptchaResp{ Token: captcha.Data.Token, Gt: captcha.Data.Geetest.Gt, @@ -115,6 +165,17 @@ type sms struct { } `json:"data"` } +const ( + smsStatusSuccess int = 0 + smsStatusBadReq int = -400 + smsStatusTelFormatErr int = 1002 + smsStatusRateLimit int = 86203 + smsStatusSended int = 1003 + smsStatusBanned int = 1025 + smsStatusTokenErr int = 2400 + smsStatusGeetestErr int = 2406 +) + func NewSMS(ctx context.Context, tel, token, challenge, validate string) (captchaKey string, err error) { b, err := getBuvidCookies() if err != nil { @@ -149,9 +210,22 @@ func NewSMS(ctx context.Context, tel, token, challenge, validate string) (captch if err != nil { return "", err } + if sms.Code != smsStatusSuccess { + return "", errors.New(sms.Message) + } return sms.Data.CaptchaKey, nil } +type loginSMSResp struct { + Code int `json:"code"` + Message string `json:"message"` + Data struct { + IsNew bool `json:"is_new"` + Status int `json:"status"` + URL string `json:"url"` + } `json:"data"` +} + func LoginWithSMS(ctx context.Context, tel, code, captchaKey string) (*http.Cookie, error) { data := url.Values{} data.Set("cid", "86") @@ -171,10 +245,19 @@ func LoginWithSMS(ctx context.Context, tel, code, captchaKey string) (*http.Cook if err != nil { return nil, err } + var loginSMSResp loginSMSResp + err = json.NewDecoder(resp.Body).Decode(&loginSMSResp) + if err != nil { + return nil, err + } + if loginSMSResp.Code != 0 { + return nil, errors.New(loginSMSResp.Message) + } + for _, cookie := range resp.Cookies() { if cookie.Name == "SESSDATA" { return cookie, nil } } - return nil, fmt.Errorf("no SESSDATA cookie") + return nil, fmt.Errorf("no cookie") } diff --git a/vendors/bilibili/movie.go b/vendors/bilibili/movie.go index 07632793..2fc95cdf 100644 --- a/vendors/bilibili/movie.go +++ b/vendors/bilibili/movie.go @@ -1,6 +1,7 @@ package bilibili import ( + "errors" "fmt" "net/http" @@ -45,7 +46,9 @@ func (c *Client) ParseVideoPage(aid uint, bvid string) (*VideoPageInfo, error) { if err != nil { return nil, err } - // TODO: error message + if info.Code != 0 { + return nil, errors.New(info.Message) + } r := &VideoPageInfo{ Title: info.Data.Title, CoverImage: info.Data.Pic, @@ -126,6 +129,9 @@ func (c *Client) GetVideoURL(aid uint, bvid string, cid uint, conf ...GetVideoUR if err != nil { return nil, err } + if info.Code != 0 { + return nil, errors.New(info.Message) + } return &VideoURL{ AcceptDescription: info.Data.AcceptDescription, AcceptQuality: info.Data.AcceptQuality, @@ -162,6 +168,9 @@ func (c *Client) GetSubtitles(aid uint, bvid string, cid uint) ([]*Subtitle, err if err != nil { return nil, err } + if info.Code != 0 { + return nil, errors.New(info.Message) + } r := make([]*Subtitle, len(info.Data.Subtitle.Subtitles)) for i, s := range info.Data.Subtitle.Subtitles { r[i] = &Subtitle{ @@ -196,6 +205,9 @@ func (c *Client) ParsePGCPage(epId, season_id uint) (*VideoPageInfo, error) { if err != nil { return nil, err } + if info.Code != 0 { + return nil, errors.New(info.Message) + } r := &VideoPageInfo{ Title: info.Result.Title, @@ -246,6 +258,10 @@ func (c *Client) GetPGCURL(ep_id, cid uint, conf ...GetVideoURLConfig) (*VideoUR if err != nil { return nil, err } + if info.Code != 0 { + return nil, errors.New(info.Message) + } + return &VideoURL{ AcceptDescription: info.Result.AcceptDescription, AcceptQuality: info.Result.AcceptQuality, diff --git a/vendors/bilibili/user.go b/vendors/bilibili/user.go index 9dedae3f..bad4aeed 100644 --- a/vendors/bilibili/user.go +++ b/vendors/bilibili/user.go @@ -1,6 +1,7 @@ package bilibili import ( + "errors" "net/http" json "github.com/json-iterator/go" @@ -20,5 +21,8 @@ func (c *Client) UserInfo() (*Nav, error) { if err != nil { return nil, err } + if nav.Code != 0 { + return nil, errors.New(nav.Message) + } return &nav, nil } diff --git a/vendors/bilibili/wbi.go b/vendors/bilibili/wbi.go index 776f84cb..a1c4e689 100644 --- a/vendors/bilibili/wbi.go +++ b/vendors/bilibili/wbi.go @@ -3,6 +3,7 @@ package bilibili import ( "crypto/md5" "encoding/hex" + "errors" "net/http" "net/url" "sort" @@ -119,6 +120,9 @@ func getWbiKeys() (string, string, error) { if err != nil { return "", "", err } + if info.Data.WbiImg.ImgURL == "" || info.Data.WbiImg.SubURL == "" { + return "", "", errors.New(info.Message) + } imgKey := strings.Split(strings.Split(info.Data.WbiImg.ImgURL, "/")[len(strings.Split(info.Data.WbiImg.ImgURL, "/"))-1], ".")[0] subKey := strings.Split(strings.Split(info.Data.WbiImg.SubURL, "/")[len(strings.Split(info.Data.WbiImg.SubURL, "/"))-1], ".")[0]