From 1469917c24c8d01967cfef5937a21d5322588008 Mon Sep 17 00:00:00 2001 From: harold Date: Fri, 28 Feb 2025 10:05:23 +0500 Subject: [PATCH] add auth client service --- cmd/main.go | 6 +- internal/api/http/handlers/donat/donat.go | 15 +- internal/api/http/handlers/target/target.go | 8 +- internal/api/http/handlers/widget/widget.go | 452 ++++++++++---------- internal/app/http/app.go | 21 +- internal/model/api/auth.go | 4 +- internal/model/interfaces.go | 8 +- internal/model/models.go | 12 +- internal/model/sql/query.go | 4 + internal/model/types.go | 1 + internal/repository/donat/donat.go | 27 ++ internal/service/donat/donat.go | 45 +- internal/service/target/target.go | 30 ++ pkg/api/auth/auth.go | 33 +- pkg/custom_response/custom_response.go | 26 ++ 15 files changed, 422 insertions(+), 270 deletions(-) create mode 100644 pkg/custom_response/custom_response.go diff --git a/cmd/main.go b/cmd/main.go index 0c164ec..4f25a79 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -28,7 +28,7 @@ import ( // @title Donate Auth Documentation // @version 3.0 // @description Donate auth service docs. -// @BasePath /api/donat-wiget +// @BasePath /api/widget // @securityDefinitions.apikey BearerAuth // @in header // @name Authorization @@ -53,8 +53,8 @@ func main() { // SERVICES widgetService := WidgetService.New(widgetRepo) - donatService := DonatService.New(donatRepo, widgetRepo, paymentClient) - targetService := TargetService.New(targetRepo) + donatService := DonatService.New(donatRepo, widgetRepo, paymentClient, authClient) + targetService := TargetService.New(targetRepo, authClient) http.NewApp( db, diff --git a/internal/api/http/handlers/donat/donat.go b/internal/api/http/handlers/donat/donat.go index 0a14d31..f7ab674 100644 --- a/internal/api/http/handlers/donat/donat.go +++ b/internal/api/http/handlers/donat/donat.go @@ -131,7 +131,19 @@ func MarkDonatView(donatService model.DonatService) echo.HandlerFunc { // @Router /inner-donate-page [get] func GetInnerDonatePage(donatService model.DonatService) echo.HandlerFunc { return func(request echo.Context) error { - return nil + authData, err := donatService.CheckToken(request) + if err != nil { + slog.Error("Unauthorized") + return echo.NewHTTPError(http.StatusUnauthorized, err.Error()) + } + ctx := context.Background() + + var innerPage model.InnerDonatePageResponse + innerPage, err = donatService.GetInnerDonatPage(ctx, model.StreamerID(authData.AccountID)) + if err != nil { + return echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + return request.JSON(http.StatusOK, innerPage) } } @@ -148,6 +160,7 @@ func GetInnerDonatePage(donatService model.DonatService) echo.HandlerFunc { // @Router /outer-donate-page [get] func GetOuterDonatePage(donatService model.DonatService) echo.HandlerFunc { return func(request echo.Context) error { + return nil } } diff --git a/internal/api/http/handlers/target/target.go b/internal/api/http/handlers/target/target.go index 523631b..fdcac5e 100644 --- a/internal/api/http/handlers/target/target.go +++ b/internal/api/http/handlers/target/target.go @@ -28,13 +28,17 @@ func CreateTarget(targetService model.TargetService, authClient model.AuthClient return request.JSON(http.StatusInternalServerError, err.Error()) } - authData, err := authClient.CheckToken(request) + authData, err := targetService.CheckToken(request) if err != nil { slog.Error(err.Error()) return request.JSON(http.StatusInternalServerError, err.Error()) } - targetID, err := targetService.CreateTarget(ctx, model.StreamerID(authData.StreamerID), body.Amount, body.Text) + targetID, err := targetService.CreateTarget(ctx, model.StreamerID( + model.StreamerID(authData.AccountID)), + body.Amount, + body.Text, + ) if err != nil { slog.Error(err.Error()) return request.JSON(http.StatusInternalServerError, err.Error()) diff --git a/internal/api/http/handlers/widget/widget.go b/internal/api/http/handlers/widget/widget.go index 064a672..ac44e2d 100644 --- a/internal/api/http/handlers/widget/widget.go +++ b/internal/api/http/handlers/widget/widget.go @@ -1,226 +1,226 @@ -package widget - -import ( - "context" - "donat-widget/internal/model" - "github.com/labstack/echo/v4" - "log/slog" - "net/http" - "strconv" -) - -func CreateWidget(widgetService model.WidgetService, authClient model.AuthClient) echo.HandlerFunc { - type CreateWidgetBody struct { - TemplateID model.TemplateID `json:"templateID"` - MinAmount model.DonatAmount `json:"minAmount"` - Duration model.Duration `json:"duration"` - } - - type CreateWidgetResponse struct { - WidgetID model.WidgetID `json:"widgetID"` - } - return func(request echo.Context) error { - ctx := context.Background() - var body CreateWidgetBody - if err := request.Bind(&body); err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - if err := request.Validate(&body); err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - authData, err := authClient.CheckToken(request) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - if authData.StreamerID == 0 { - slog.Error("Unauthorized account") - return request.JSON(http.StatusUnauthorized, "Unauthorized") - } - if authData.StreamerID == -1 { - slog.Error("Expired token") - return request.JSON(http.StatusUnauthorized, "Expired token") - } - - widgetID, err := widgetService.CreateWidget( - ctx, - model.StreamerID(authData.StreamerID), - body.TemplateID, - body.Duration, - body.MinAmount, - ) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - response := CreateWidgetResponse{ - WidgetID: widgetID, - } - - return request.JSON(200, response) - } -} - -func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc { - return func(request echo.Context) error { - ctx := context.Background() - - streamerID, err := strconv.Atoi(request.Param("streamerID")) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - widgetHTML, err := widgetService.GetWidgetHTML( - ctx, - model.StreamerID(streamerID), - ) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - slog.Info("Get widget HTML successfully") - return request.HTML(200, string(widgetHTML)) - } -} - -func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc { - type Response struct { - AudioUrl model.MediaUrl `json:"audioUrl"` - ImageUrl model.MediaUrl `json:"imageUrl"` - Duration model.Duration `json:"duration"` - } - return func(request echo.Context) error { - ctx := context.Background() - - widgetID, err := strconv.Atoi(request.Param("widgetID")) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - widget, err := widgetService.GetWidgetByID(ctx, model.WidgetID(widgetID)) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - if len(widget) == 0 { - return request.JSON(http.StatusNotFound, "widget not found") - } - - return request.JSON(200, widget) - } -} - -func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { - return func(request echo.Context) error { - ctx := context.Background() - - widgetID, err := strconv.Atoi(request.FormValue("widgetID")) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - mediaType := request.Param("mediaType") - - file, err := request.FormFile("file") - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - src, err := file.Open() - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - err = widgetService.SetMediaFile( - ctx, - model.MediaType(mediaType), - model.WidgetID(widgetID), - &src, - file.Filename, - file.Size, - "", - ) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - slog.Info("set " + mediaType + " file successfully") - return request.String(200, "File successfully uploaded") - } -} - -func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { - return func(request echo.Context) error { - ctx := context.Background() - - mediaType := request.Param("mediaType") - if mediaType != "background" && mediaType != "image" && mediaType != "audio" { - slog.Error("Path parameter 'mediaType' is invalid") - return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid") - } - - widgetID, err := strconv.Atoi(request.Param("widgetID")) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - file, err := widgetService.GetMediaFile( - ctx, - model.WidgetID(widgetID), - model.MediaType(mediaType), - ) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - slog.Info("get " + mediaType + " file successfully") - return request.Blob(200, "application/octet-stream", file) - } -} - -func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc { - type Body struct { - WidgetID model.WidgetID `json:"widgetID" validate:"required"` - MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"` - } - return func(request echo.Context) error { - ctx := context.Background() - var body Body - if err := request.Bind(&body); err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - if err := request.Validate(&body); err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - mediaType := request.Param("mediaType") - - err := widgetService.SetMediaUrl( - ctx, - model.MediaType(mediaType), - body.WidgetID, - body.MediaUrl, - ) - if err != nil { - slog.Error(err.Error()) - return request.JSON(http.StatusInternalServerError, err.Error()) - } - - return request.String(200, "Media URL successfully set") - } -} +//package widget +// +//import ( +// "context" +// "donat-widget/internal/model" +// "github.com/labstack/echo/v4" +// "log/slog" +// "net/http" +// "strconv" +//) +// +//func CreateWidget(widgetService model.WidgetService, authClient model.AuthClient) echo.HandlerFunc { +// type CreateWidgetBody struct { +// TemplateID model.TemplateID `json:"templateID"` +// MinAmount model.DonatAmount `json:"minAmount"` +// Duration model.Duration `json:"duration"` +// } +// +// type CreateWidgetResponse struct { +// WidgetID model.WidgetID `json:"widgetID"` +// } +// return func(request echo.Context) error { +// ctx := context.Background() +// var body CreateWidgetBody +// if err := request.Bind(&body); err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// if err := request.Validate(&body); err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// authData, err := authClient.CheckToken(request) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// if authData.StreamerID == 0 { +// slog.Error("Unauthorized account") +// return request.JSON(http.StatusUnauthorized, "Unauthorized") +// } +// if authData.StreamerID == -1 { +// slog.Error("Expired token") +// return request.JSON(http.StatusUnauthorized, "Expired token") +// } +// +// widgetID, err := widgetService.CreateWidget( +// ctx, +// model.StreamerID(authData.StreamerID), +// body.TemplateID, +// body.Duration, +// body.MinAmount, +// ) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// response := CreateWidgetResponse{ +// WidgetID: widgetID, +// } +// +// return request.JSON(200, response) +// } +//} +// +//func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc { +// return func(request echo.Context) error { +// ctx := context.Background() +// +// streamerID, err := strconv.Atoi(request.Param("streamerID")) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// widgetHTML, err := widgetService.GetWidgetHTML( +// ctx, +// model.StreamerID(streamerID), +// ) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// slog.Info("Get widget HTML successfully") +// return request.HTML(200, string(widgetHTML)) +// } +//} +// +//func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc { +// type Response struct { +// AudioUrl model.MediaUrl `json:"audioUrl"` +// ImageUrl model.MediaUrl `json:"imageUrl"` +// Duration model.Duration `json:"duration"` +// } +// return func(request echo.Context) error { +// ctx := context.Background() +// +// widgetID, err := strconv.Atoi(request.Param("widgetID")) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// widget, err := widgetService.GetWidgetByID(ctx, model.WidgetID(widgetID)) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// if len(widget) == 0 { +// return request.JSON(http.StatusNotFound, "widget not found") +// } +// +// return request.JSON(200, widget) +// } +//} +// +//func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { +// return func(request echo.Context) error { +// ctx := context.Background() +// +// widgetID, err := strconv.Atoi(request.FormValue("widgetID")) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// mediaType := request.Param("mediaType") +// +// file, err := request.FormFile("file") +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// src, err := file.Open() +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// err = widgetService.SetMediaFile( +// ctx, +// model.MediaType(mediaType), +// model.WidgetID(widgetID), +// &src, +// file.Filename, +// file.Size, +// "", +// ) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// slog.Info("set " + mediaType + " file successfully") +// return request.String(200, "File successfully uploaded") +// } +//} +// +//func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { +// return func(request echo.Context) error { +// ctx := context.Background() +// +// mediaType := request.Param("mediaType") +// if mediaType != "background" && mediaType != "image" && mediaType != "audio" { +// slog.Error("Path parameter 'mediaType' is invalid") +// return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid") +// } +// +// widgetID, err := strconv.Atoi(request.Param("widgetID")) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// file, err := widgetService.GetMediaFile( +// ctx, +// model.WidgetID(widgetID), +// model.MediaType(mediaType), +// ) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// slog.Info("get " + mediaType + " file successfully") +// return request.Blob(200, "application/octet-stream", file) +// } +//} +// +//func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc { +// type Body struct { +// WidgetID model.WidgetID `json:"widgetID" validate:"required"` +// MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"` +// } +// return func(request echo.Context) error { +// ctx := context.Background() +// var body Body +// if err := request.Bind(&body); err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// if err := request.Validate(&body); err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// mediaType := request.Param("mediaType") +// +// err := widgetService.SetMediaUrl( +// ctx, +// model.MediaType(mediaType), +// body.WidgetID, +// body.MediaUrl, +// ) +// if err != nil { +// slog.Error(err.Error()) +// return request.JSON(http.StatusInternalServerError, err.Error()) +// } +// +// return request.String(200, "Media URL successfully set") +// } +//} diff --git a/internal/app/http/app.go b/internal/app/http/app.go index 6a45540..8c2b2a9 100644 --- a/internal/app/http/app.go +++ b/internal/app/http/app.go @@ -18,7 +18,6 @@ import ( import ( . "donat-widget/internal/api/http/handlers/donat" . "donat-widget/internal/api/http/handlers/target" - . "donat-widget/internal/api/http/handlers/widget" ) var PREFIX = "/api/widget" @@ -74,6 +73,8 @@ func IncludeDonatHandlers( ) { server.POST(PREFIX+"/donat/create", CreateDonat(donatService)) + server.GET(PREFIX+"/inner-donate-page", GetInnerDonatePage(donatService)) + server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService)) server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService)) @@ -85,15 +86,15 @@ func IncludeWidgetHandlers( widgetService model.WidgetService, authClient model.AuthClient, ) { - server.POST(PREFIX+"/create", CreateWidget(widgetService, authClient)) - - server.GET(PREFIX+"/html/:streamerID", GetWidgetHTML(widgetService)) - server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService)) - - server.POST(PREFIX+"/media/:mediaType/file/set", SetMediaFile(widgetService)) - server.GET(PREFIX+"/media/:mediaType/file/get/:widgetID", GetMediaFile(widgetService)) - - server.POST(PREFIX+"/media/:mediaType/url/set", SetMediaUrl(widgetService)) + //server.POST(PREFIX+"/create", model.CreateWidget(widgetService, authClient)) + // + //server.GET(PREFIX+"/html/:streamerID", model.GetWidgetHTML(widgetService)) + //server.GET(PREFIX+"/info/:widgetID", model.GetWidgetInfo(widgetService)) + // + //server.POST(PREFIX+"/media/:mediaType/file/set", model.SetMediaFile(widgetService)) + //server.GET(PREFIX+"/media/:mediaType/file/get/:widgetID", model.GetMediaFile(widgetService)) + // + //server.POST(PREFIX+"/media/:mediaType/url/set", model.SetMediaUrl(widgetService)) } diff --git a/internal/model/api/auth.go b/internal/model/api/auth.go index 1c17ad2..3b184f7 100644 --- a/internal/model/api/auth.go +++ b/internal/model/api/auth.go @@ -1,8 +1,8 @@ package api type CheckTokenResponse struct { - StreamerID int `json:"accountID"` - TwoFa bool `json:"twoFa"` + AccountID int `json:"accountID"` + TwoFa bool `json:"twoFa"` } type VerifyTokenResponse struct { diff --git a/internal/model/interfaces.go b/internal/model/interfaces.go index 2999905..8c40596 100644 --- a/internal/model/interfaces.go +++ b/internal/model/interfaces.go @@ -32,6 +32,8 @@ type WidgetRepo interface { } type DonatService interface { + CheckToken(request echo.Context) (api.CheckTokenResponse, error) + CreateDonat(ctx context.Context, streamerID StreamerID, orderID OrderID, targetID TargetID, amount DonatAmount, text string, donatUser string) (api.CreatePaymentResponse, error) GetDonatByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Donat, error) @@ -62,9 +64,13 @@ type DonatRepo interface { MarkDonatPaid(ctx context.Context, orderID OrderID) error MarkDonatView(ctx context.Context, DonatID DonatID) error + + GetDonatPage(ctx context.Context, streamerID StreamerID) (DonatePage, error) } type TargetService interface { + CheckToken(request echo.Context) (api.CheckTokenResponse, error) + CreateTarget(ctx context.Context, streamerID StreamerID, amount DonatAmount, text string) (TargetID, error) GetAllTarget(ctx context.Context, streamerID StreamerID) ([]*Target, error) AddAmountToTarget(ctx context.Context, targetID TargetID, amount DonatAmount) error @@ -100,6 +106,6 @@ type Db interface { } type AuthClient interface { - CheckToken(request echo.Context) (api.CheckTokenResponse, error) + CheckToken(token Token) (api.CheckTokenResponse, error) VerifyTwoFa(twoFaCode string, streamerID StreamerID) (bool, error) } diff --git a/internal/model/models.go b/internal/model/models.go index a10c392..28e51fc 100644 --- a/internal/model/models.go +++ b/internal/model/models.go @@ -54,12 +54,12 @@ type Target struct { type DonatePage struct { id int `db:"id"` - streamerID int `db:"streamer_id"` - description string `db:"description"` - textAfterDonat string `db:"text_after_donat"` - pageBackground string `db:"page_background"` - avatar string `db:"avatar"` - backgroundImg string `db:"background_img"` + StreamerID int `db:"streamer_id"` + Description string `db:"description"` + TextAfterDonat string `db:"text_after_donat"` + PageBackground string `db:"page_background"` + Avatar string `db:"avatar"` + BackgroundImg string `db:"background_img"` } type Moderation struct { diff --git a/internal/model/sql/query.go b/internal/model/sql/query.go index 0ebb0e1..4f0221a 100644 --- a/internal/model/sql/query.go +++ b/internal/model/sql/query.go @@ -81,3 +81,7 @@ UPDATE targets SET collected = collected + (@amount) WHERE id = (@target_id); ` + +var GetDonationPage = ` +SELECT * FROM donate_pages WHERE streamer_id = (@streamer_id); +` diff --git a/internal/model/types.go b/internal/model/types.go index 29f07b9..5f974ce 100644 --- a/internal/model/types.go +++ b/internal/model/types.go @@ -5,6 +5,7 @@ import ( "mime/multipart" ) +type Token string type StreamerID int type WidgetID int type TemplateID int diff --git a/internal/repository/donat/donat.go b/internal/repository/donat/donat.go index f8897d2..6b72cac 100644 --- a/internal/repository/donat/donat.go +++ b/internal/repository/donat/donat.go @@ -132,3 +132,30 @@ func (repoDonat *RepoDonat) MarkDonatPaid( return nil } + +func (repoDonat *RepoDonat) GetDonatPage( + ctx context.Context, + streamerID model.StreamerID, +) (model.DonatePage, error) { + args := pgx.NamedArgs{ + "streamer_id": streamerID, + } + rows, err := repoDonat.db.Select(ctx, sql.GetDonationPage, args) + if err != nil { + slog.Error(err.Error()) + return model.DonatePage{}, err + } + + var donatePage []*model.DonatePage + err = pgxscan.ScanAll(&donatePage, rows) + if err != nil { + slog.Error(err.Error()) + return model.DonatePage{}, err + } + if len(donatePage) == 0 { + return model.DonatePage{}, errors.New("donat not found") + } + + return *donatePage[0], nil + +} diff --git a/internal/service/donat/donat.go b/internal/service/donat/donat.go index 0cb2341..cdd3ce1 100644 --- a/internal/service/donat/donat.go +++ b/internal/service/donat/donat.go @@ -4,12 +4,15 @@ import ( "context" "donat-widget/internal/model" "donat-widget/internal/model/api" + "github.com/labstack/echo/v4" "log/slog" + "net/http" ) type ServiceDonat struct { donatRepo model.DonatRepo widgetRepo model.WidgetRepo + authClient model.AuthClient paymentClient model.PaymentClient } @@ -17,14 +20,40 @@ func New( donatRepo model.DonatRepo, widgetRepo model.WidgetRepo, paymentClient model.PaymentClient, + authClient model.AuthClient, ) *ServiceDonat { return &ServiceDonat{ donatRepo: donatRepo, widgetRepo: widgetRepo, paymentClient: paymentClient, + authClient: authClient, } } +func (donatService *ServiceDonat) CheckToken( + request echo.Context, +) (api.CheckTokenResponse, error) { + accessToken := model.Token(request.Request().Header.Get("Authorization")) + + checkTokenResponse, err := donatService.authClient.CheckToken(accessToken) + if err != nil { + slog.Error("Failed to check token", "error", err.Error()) + return api.CheckTokenResponse{}, echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + + if checkTokenResponse.AccountID == 0 { + slog.Error("Unauthorized account") + return api.CheckTokenResponse{}, echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized account") + } + + if checkTokenResponse.AccountID == -1 { + slog.Error("Expired token") + return api.CheckTokenResponse{}, echo.NewHTTPError(http.StatusUnauthorized, "Expired token") + } + + return checkTokenResponse, nil +} + func (donatService *ServiceDonat) CreateDonat( ctx context.Context, streamerID model.StreamerID, @@ -122,7 +151,21 @@ func (donatService *ServiceDonat) GetInnerDonatPage( ctx context.Context, streamerID model.StreamerID, ) (model.InnerDonatePageResponse, error) { - return model.InnerDonatePageResponse{}, nil + donatePage, err := donatService.donatRepo.GetDonatPage(ctx, streamerID) + if err != nil { + slog.Error(err.Error()) + return model.InnerDonatePageResponse{}, err + } + + var innerDonatePageResponse = model.InnerDonatePageResponse{ + Description: donatePage.Description, + TextAfterDonat: donatePage.TextAfterDonat, + PageBackground: donatePage.PageBackground, + Avatar: donatePage.Avatar, + BackgroundImg: donatePage.BackgroundImg, + } + + return innerDonatePageResponse, nil } func (donatService *ServiceDonat) GetOuterDonatPage( diff --git a/internal/service/target/target.go b/internal/service/target/target.go index 560c702..1b33c04 100644 --- a/internal/service/target/target.go +++ b/internal/service/target/target.go @@ -3,19 +3,25 @@ package target import ( "context" "donat-widget/internal/model" + "donat-widget/internal/model/api" + "github.com/labstack/echo/v4" "log/slog" + "net/http" ) func New( targetRepo model.TargetRepo, + authClient model.AuthClient, ) *ServiceTarget { return &ServiceTarget{ targetRepo: targetRepo, + authClient: authClient, } } type ServiceTarget struct { targetRepo model.TargetRepo + authClient model.AuthClient } func (targetService *ServiceTarget) CreateTarget( @@ -57,3 +63,27 @@ func (targetService *ServiceTarget) AddAmountToTarget( } return nil } + +func (donatService *ServiceTarget) CheckToken( + request echo.Context, +) (api.CheckTokenResponse, error) { + accessToken := model.Token(request.Request().Header.Get("Authorization")) + + checkTokenResponse, err := donatService.authClient.CheckToken(accessToken) + if err != nil { + slog.Error("Failed to check token", "error", err.Error()) + return api.CheckTokenResponse{}, echo.NewHTTPError(http.StatusInternalServerError, err.Error()) + } + + if checkTokenResponse.AccountID == 0 { + slog.Error("Unauthorized account") + return api.CheckTokenResponse{}, echo.NewHTTPError(http.StatusUnauthorized, "Unauthorized account") + } + + if checkTokenResponse.AccountID == -1 { + slog.Error("Expired token") + return api.CheckTokenResponse{}, echo.NewHTTPError(http.StatusUnauthorized, "Expired token") + } + + return checkTokenResponse, nil +} diff --git a/pkg/api/auth/auth.go b/pkg/api/auth/auth.go index 40757f4..acf2896 100644 --- a/pkg/api/auth/auth.go +++ b/pkg/api/auth/auth.go @@ -4,9 +4,9 @@ import ( "bytes" "donat-widget/internal/model" "donat-widget/internal/model/api" + "donat-widget/pkg/custom_response" "encoding/json" "errors" - "github.com/labstack/echo/v4" "io" "log/slog" "net/http" @@ -26,41 +26,38 @@ type ClientAuth struct { } func (c *ClientAuth) CheckToken( - request echo.Context, + accessToken model.Token, ) (api.CheckTokenResponse, error) { - _accessToken, err := request.Cookie("Access-Token") - if err != nil { - slog.Error("request.Cookie: " + err.Error()) - return api.CheckTokenResponse{}, err - } - accessToken := _accessToken.Value - req, err := http.NewRequest("GET", c.baseURL+"/token/check", nil) if err != nil { slog.Error("http.NewRequest: " + err.Error()) - return api.CheckTokenResponse{}, err + return api.CheckTokenResponse{}, errors.New(custom_response.InternalError) } - req.AddCookie(&http.Cookie{Name: "Access-Token", Value: accessToken}) + + req.Header.Set("Authorization", string(accessToken)) resp, err := c.client.Do(req) if err != nil { slog.Error("client.Do: " + err.Error()) - return api.CheckTokenResponse{}, err - } - if resp.StatusCode != http.StatusOK { - return api.CheckTokenResponse{}, errors.New("get failed: " + resp.Status) + return api.CheckTokenResponse{}, errors.New(custom_response.InternalError) } response, err := io.ReadAll(resp.Body) if err != nil { slog.Error("io.ReadAll: " + err.Error()) - return api.CheckTokenResponse{}, err + return api.CheckTokenResponse{}, errors.New(custom_response.InternalError) } - var checkTokenResponse api.CheckTokenResponse + if resp.StatusCode != http.StatusOK { + var errorResponse custom_response.MessageErrorResponse + err = json.Unmarshal(response, &errorResponse) + return api.CheckTokenResponse{}, errors.New(errorResponse.Message) + } + + checkTokenResponse := api.CheckTokenResponse{} err = json.Unmarshal(response, &checkTokenResponse) if err != nil { slog.Error("json.Unmarshal: " + err.Error()) - return api.CheckTokenResponse{}, err + return api.CheckTokenResponse{}, errors.New(custom_response.InternalError) } return checkTokenResponse, nil } diff --git a/pkg/custom_response/custom_response.go b/pkg/custom_response/custom_response.go new file mode 100644 index 0000000..de34ea7 --- /dev/null +++ b/pkg/custom_response/custom_response.go @@ -0,0 +1,26 @@ +package custom_response + +// Errors response +const ( + AccountAlreadyExists = "Account already exists" + InternalError = "Internal Error" + InvalidCredentials = "Invalid login or password" + ReadTokenError = "Error reading token." + InvalidToken = "Invalid token." + RefreshNotFound = "AccountByRefreshToken not found" + Conflict2FA = "2FA already exists" + AccountNotFound = "Account not found" + NotVerified2FA = "2FA not verified" + NotExists2FA = "2FA does not exist" +) + +// Success response +const ( + SuccessRefresh = "Refresh Token Successfully." + SuccessSet2FA = "2FA set successfully." + SuccessDel2FA = "2FA deleted successfully." +) + +type MessageErrorResponse struct { + Message string `json:"message"` +}