add auth client service

This commit is contained in:
harold 2025-02-28 10:05:23 +05:00
parent 4a82c1e208
commit 1469917c24
15 changed files with 422 additions and 270 deletions

View File

@ -28,7 +28,7 @@ import (
// @title Donate Auth Documentation // @title Donate Auth Documentation
// @version 3.0 // @version 3.0
// @description Donate auth service docs. // @description Donate auth service docs.
// @BasePath /api/donat-wiget // @BasePath /api/widget
// @securityDefinitions.apikey BearerAuth // @securityDefinitions.apikey BearerAuth
// @in header // @in header
// @name Authorization // @name Authorization
@ -53,8 +53,8 @@ func main() {
// SERVICES // SERVICES
widgetService := WidgetService.New(widgetRepo) widgetService := WidgetService.New(widgetRepo)
donatService := DonatService.New(donatRepo, widgetRepo, paymentClient) donatService := DonatService.New(donatRepo, widgetRepo, paymentClient, authClient)
targetService := TargetService.New(targetRepo) targetService := TargetService.New(targetRepo, authClient)
http.NewApp( http.NewApp(
db, db,

View File

@ -131,7 +131,19 @@ func MarkDonatView(donatService model.DonatService) echo.HandlerFunc {
// @Router /inner-donate-page [get] // @Router /inner-donate-page [get]
func GetInnerDonatePage(donatService model.DonatService) echo.HandlerFunc { func GetInnerDonatePage(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error { 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] // @Router /outer-donate-page [get]
func GetOuterDonatePage(donatService model.DonatService) echo.HandlerFunc { func GetOuterDonatePage(donatService model.DonatService) echo.HandlerFunc {
return func(request echo.Context) error { return func(request echo.Context) error {
return nil return nil
} }
} }

View File

@ -28,13 +28,17 @@ func CreateTarget(targetService model.TargetService, authClient model.AuthClient
return request.JSON(http.StatusInternalServerError, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())
} }
authData, err := authClient.CheckToken(request) authData, err := targetService.CheckToken(request)
if err != nil { if err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, 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 { if err != nil {
slog.Error(err.Error()) slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) return request.JSON(http.StatusInternalServerError, err.Error())

View File

@ -1,226 +1,226 @@
package widget //package widget
//
import ( //import (
"context" // "context"
"donat-widget/internal/model" // "donat-widget/internal/model"
"github.com/labstack/echo/v4" // "github.com/labstack/echo/v4"
"log/slog" // "log/slog"
"net/http" // "net/http"
"strconv" // "strconv"
) //)
//
func CreateWidget(widgetService model.WidgetService, authClient model.AuthClient) echo.HandlerFunc { //func CreateWidget(widgetService model.WidgetService, authClient model.AuthClient) echo.HandlerFunc {
type CreateWidgetBody struct { // type CreateWidgetBody struct {
TemplateID model.TemplateID `json:"templateID"` // TemplateID model.TemplateID `json:"templateID"`
MinAmount model.DonatAmount `json:"minAmount"` // MinAmount model.DonatAmount `json:"minAmount"`
Duration model.Duration `json:"duration"` // Duration model.Duration `json:"duration"`
} // }
//
type CreateWidgetResponse struct { // type CreateWidgetResponse struct {
WidgetID model.WidgetID `json:"widgetID"` // WidgetID model.WidgetID `json:"widgetID"`
} // }
return func(request echo.Context) error { // return func(request echo.Context) error {
ctx := context.Background() // ctx := context.Background()
var body CreateWidgetBody // var body CreateWidgetBody
if err := request.Bind(&body); err != nil { // if err := request.Bind(&body); err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
if err := request.Validate(&body); err != nil { // if err := request.Validate(&body); err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
authData, err := authClient.CheckToken(request) // authData, err := authClient.CheckToken(request)
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
if authData.StreamerID == 0 { // if authData.StreamerID == 0 {
slog.Error("Unauthorized account") // slog.Error("Unauthorized account")
return request.JSON(http.StatusUnauthorized, "Unauthorized") // return request.JSON(http.StatusUnauthorized, "Unauthorized")
} // }
if authData.StreamerID == -1 { // if authData.StreamerID == -1 {
slog.Error("Expired token") // slog.Error("Expired token")
return request.JSON(http.StatusUnauthorized, "Expired token") // return request.JSON(http.StatusUnauthorized, "Expired token")
} // }
//
widgetID, err := widgetService.CreateWidget( // widgetID, err := widgetService.CreateWidget(
ctx, // ctx,
model.StreamerID(authData.StreamerID), // model.StreamerID(authData.StreamerID),
body.TemplateID, // body.TemplateID,
body.Duration, // body.Duration,
body.MinAmount, // body.MinAmount,
) // )
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
response := CreateWidgetResponse{ // response := CreateWidgetResponse{
WidgetID: widgetID, // WidgetID: widgetID,
} // }
//
return request.JSON(200, response) // return request.JSON(200, response)
} // }
} //}
//
func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc { //func GetWidgetHTML(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { // return func(request echo.Context) error {
ctx := context.Background() // ctx := context.Background()
//
streamerID, err := strconv.Atoi(request.Param("streamerID")) // streamerID, err := strconv.Atoi(request.Param("streamerID"))
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
widgetHTML, err := widgetService.GetWidgetHTML( // widgetHTML, err := widgetService.GetWidgetHTML(
ctx, // ctx,
model.StreamerID(streamerID), // model.StreamerID(streamerID),
) // )
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
slog.Info("Get widget HTML successfully") // slog.Info("Get widget HTML successfully")
return request.HTML(200, string(widgetHTML)) // return request.HTML(200, string(widgetHTML))
} // }
} //}
//
func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc { //func GetWidgetInfo(widgetService model.WidgetService) echo.HandlerFunc {
type Response struct { // type Response struct {
AudioUrl model.MediaUrl `json:"audioUrl"` // AudioUrl model.MediaUrl `json:"audioUrl"`
ImageUrl model.MediaUrl `json:"imageUrl"` // ImageUrl model.MediaUrl `json:"imageUrl"`
Duration model.Duration `json:"duration"` // Duration model.Duration `json:"duration"`
} // }
return func(request echo.Context) error { // return func(request echo.Context) error {
ctx := context.Background() // ctx := context.Background()
//
widgetID, err := strconv.Atoi(request.Param("widgetID")) // widgetID, err := strconv.Atoi(request.Param("widgetID"))
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
widget, err := widgetService.GetWidgetByID(ctx, model.WidgetID(widgetID)) // widget, err := widgetService.GetWidgetByID(ctx, model.WidgetID(widgetID))
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
if len(widget) == 0 { // if len(widget) == 0 {
return request.JSON(http.StatusNotFound, "widget not found") // return request.JSON(http.StatusNotFound, "widget not found")
} // }
//
return request.JSON(200, widget) // return request.JSON(200, widget)
} // }
} //}
//
func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { //func SetMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { // return func(request echo.Context) error {
ctx := context.Background() // ctx := context.Background()
//
widgetID, err := strconv.Atoi(request.FormValue("widgetID")) // widgetID, err := strconv.Atoi(request.FormValue("widgetID"))
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
mediaType := request.Param("mediaType") // mediaType := request.Param("mediaType")
//
file, err := request.FormFile("file") // file, err := request.FormFile("file")
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
src, err := file.Open() // src, err := file.Open()
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
err = widgetService.SetMediaFile( // err = widgetService.SetMediaFile(
ctx, // ctx,
model.MediaType(mediaType), // model.MediaType(mediaType),
model.WidgetID(widgetID), // model.WidgetID(widgetID),
&src, // &src,
file.Filename, // file.Filename,
file.Size, // file.Size,
"", // "",
) // )
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
slog.Info("set " + mediaType + " file successfully") // slog.Info("set " + mediaType + " file successfully")
return request.String(200, "File successfully uploaded") // return request.String(200, "File successfully uploaded")
} // }
} //}
//
func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc { //func GetMediaFile(widgetService model.WidgetService) echo.HandlerFunc {
return func(request echo.Context) error { // return func(request echo.Context) error {
ctx := context.Background() // ctx := context.Background()
//
mediaType := request.Param("mediaType") // mediaType := request.Param("mediaType")
if mediaType != "background" && mediaType != "image" && mediaType != "audio" { // if mediaType != "background" && mediaType != "image" && mediaType != "audio" {
slog.Error("Path parameter 'mediaType' is invalid") // slog.Error("Path parameter 'mediaType' is invalid")
return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid") // return echo.NewHTTPError(400, "Path parameter 'mediaType' is invalid")
} // }
//
widgetID, err := strconv.Atoi(request.Param("widgetID")) // widgetID, err := strconv.Atoi(request.Param("widgetID"))
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
file, err := widgetService.GetMediaFile( // file, err := widgetService.GetMediaFile(
ctx, // ctx,
model.WidgetID(widgetID), // model.WidgetID(widgetID),
model.MediaType(mediaType), // model.MediaType(mediaType),
) // )
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
slog.Info("get " + mediaType + " file successfully") // slog.Info("get " + mediaType + " file successfully")
return request.Blob(200, "application/octet-stream", file) // return request.Blob(200, "application/octet-stream", file)
} // }
} //}
//
func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc { //func SetMediaUrl(widgetService model.WidgetService) echo.HandlerFunc {
type Body struct { // type Body struct {
WidgetID model.WidgetID `json:"widgetID" validate:"required"` // WidgetID model.WidgetID `json:"widgetID" validate:"required"`
MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"` // MediaUrl model.MediaUrl `json:"mediaUrl" validate:"required"`
} // }
return func(request echo.Context) error { // return func(request echo.Context) error {
ctx := context.Background() // ctx := context.Background()
var body Body // var body Body
if err := request.Bind(&body); err != nil { // if err := request.Bind(&body); err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
if err := request.Validate(&body); err != nil { // if err := request.Validate(&body); err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
mediaType := request.Param("mediaType") // mediaType := request.Param("mediaType")
//
err := widgetService.SetMediaUrl( // err := widgetService.SetMediaUrl(
ctx, // ctx,
model.MediaType(mediaType), // model.MediaType(mediaType),
body.WidgetID, // body.WidgetID,
body.MediaUrl, // body.MediaUrl,
) // )
if err != nil { // if err != nil {
slog.Error(err.Error()) // slog.Error(err.Error())
return request.JSON(http.StatusInternalServerError, err.Error()) // return request.JSON(http.StatusInternalServerError, err.Error())
} // }
//
return request.String(200, "Media URL successfully set") // return request.String(200, "Media URL successfully set")
} // }
} //}

View File

@ -18,7 +18,6 @@ import (
import ( import (
. "donat-widget/internal/api/http/handlers/donat" . "donat-widget/internal/api/http/handlers/donat"
. "donat-widget/internal/api/http/handlers/target" . "donat-widget/internal/api/http/handlers/target"
. "donat-widget/internal/api/http/handlers/widget"
) )
var PREFIX = "/api/widget" var PREFIX = "/api/widget"
@ -74,6 +73,8 @@ func IncludeDonatHandlers(
) { ) {
server.POST(PREFIX+"/donat/create", CreateDonat(donatService)) server.POST(PREFIX+"/donat/create", CreateDonat(donatService))
server.GET(PREFIX+"/inner-donate-page", GetInnerDonatePage(donatService))
server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService)) server.GET(PREFIX+"/donat/get/:streamerID", GetDonat(donatService))
server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService)) server.POST(PREFIX+"/donat/view/:donatID", MarkDonatView(donatService))
@ -85,15 +86,15 @@ func IncludeWidgetHandlers(
widgetService model.WidgetService, widgetService model.WidgetService,
authClient model.AuthClient, authClient model.AuthClient,
) { ) {
server.POST(PREFIX+"/create", CreateWidget(widgetService, authClient)) //server.POST(PREFIX+"/create", model.CreateWidget(widgetService, authClient))
//
server.GET(PREFIX+"/html/:streamerID", GetWidgetHTML(widgetService)) //server.GET(PREFIX+"/html/:streamerID", model.GetWidgetHTML(widgetService))
server.GET(PREFIX+"/info/:widgetID", GetWidgetInfo(widgetService)) //server.GET(PREFIX+"/info/:widgetID", model.GetWidgetInfo(widgetService))
//
server.POST(PREFIX+"/media/:mediaType/file/set", SetMediaFile(widgetService)) //server.POST(PREFIX+"/media/:mediaType/file/set", model.SetMediaFile(widgetService))
server.GET(PREFIX+"/media/:mediaType/file/get/:widgetID", GetMediaFile(widgetService)) //server.GET(PREFIX+"/media/:mediaType/file/get/:widgetID", model.GetMediaFile(widgetService))
//
server.POST(PREFIX+"/media/:mediaType/url/set", SetMediaUrl(widgetService)) //server.POST(PREFIX+"/media/:mediaType/url/set", model.SetMediaUrl(widgetService))
} }

View File

@ -1,7 +1,7 @@
package api package api
type CheckTokenResponse struct { type CheckTokenResponse struct {
StreamerID int `json:"accountID"` AccountID int `json:"accountID"`
TwoFa bool `json:"twoFa"` TwoFa bool `json:"twoFa"`
} }

View File

@ -32,6 +32,8 @@ type WidgetRepo interface {
} }
type DonatService 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) 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) GetDonatByStreamerID(ctx context.Context, streamerID StreamerID) ([]*Donat, error)
@ -62,9 +64,13 @@ type DonatRepo interface {
MarkDonatPaid(ctx context.Context, orderID OrderID) error MarkDonatPaid(ctx context.Context, orderID OrderID) error
MarkDonatView(ctx context.Context, DonatID DonatID) error MarkDonatView(ctx context.Context, DonatID DonatID) error
GetDonatPage(ctx context.Context, streamerID StreamerID) (DonatePage, error)
} }
type TargetService interface { type TargetService interface {
CheckToken(request echo.Context) (api.CheckTokenResponse, error)
CreateTarget(ctx context.Context, streamerID StreamerID, amount DonatAmount, text string) (TargetID, error) CreateTarget(ctx context.Context, streamerID StreamerID, amount DonatAmount, text string) (TargetID, error)
GetAllTarget(ctx context.Context, streamerID StreamerID) ([]*Target, error) GetAllTarget(ctx context.Context, streamerID StreamerID) ([]*Target, error)
AddAmountToTarget(ctx context.Context, targetID TargetID, amount DonatAmount) error AddAmountToTarget(ctx context.Context, targetID TargetID, amount DonatAmount) error
@ -100,6 +106,6 @@ type Db interface {
} }
type AuthClient interface { type AuthClient interface {
CheckToken(request echo.Context) (api.CheckTokenResponse, error) CheckToken(token Token) (api.CheckTokenResponse, error)
VerifyTwoFa(twoFaCode string, streamerID StreamerID) (bool, error) VerifyTwoFa(twoFaCode string, streamerID StreamerID) (bool, error)
} }

View File

@ -54,12 +54,12 @@ type Target struct {
type DonatePage struct { type DonatePage struct {
id int `db:"id"` id int `db:"id"`
streamerID int `db:"streamer_id"` StreamerID int `db:"streamer_id"`
description string `db:"description"` Description string `db:"description"`
textAfterDonat string `db:"text_after_donat"` TextAfterDonat string `db:"text_after_donat"`
pageBackground string `db:"page_background"` PageBackground string `db:"page_background"`
avatar string `db:"avatar"` Avatar string `db:"avatar"`
backgroundImg string `db:"background_img"` BackgroundImg string `db:"background_img"`
} }
type Moderation struct { type Moderation struct {

View File

@ -81,3 +81,7 @@ UPDATE targets
SET collected = collected + (@amount) SET collected = collected + (@amount)
WHERE id = (@target_id); WHERE id = (@target_id);
` `
var GetDonationPage = `
SELECT * FROM donate_pages WHERE streamer_id = (@streamer_id);
`

View File

@ -5,6 +5,7 @@ import (
"mime/multipart" "mime/multipart"
) )
type Token string
type StreamerID int type StreamerID int
type WidgetID int type WidgetID int
type TemplateID int type TemplateID int

View File

@ -132,3 +132,30 @@ func (repoDonat *RepoDonat) MarkDonatPaid(
return nil 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
}

View File

@ -4,12 +4,15 @@ import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/api" "donat-widget/internal/model/api"
"github.com/labstack/echo/v4"
"log/slog" "log/slog"
"net/http"
) )
type ServiceDonat struct { type ServiceDonat struct {
donatRepo model.DonatRepo donatRepo model.DonatRepo
widgetRepo model.WidgetRepo widgetRepo model.WidgetRepo
authClient model.AuthClient
paymentClient model.PaymentClient paymentClient model.PaymentClient
} }
@ -17,14 +20,40 @@ func New(
donatRepo model.DonatRepo, donatRepo model.DonatRepo,
widgetRepo model.WidgetRepo, widgetRepo model.WidgetRepo,
paymentClient model.PaymentClient, paymentClient model.PaymentClient,
authClient model.AuthClient,
) *ServiceDonat { ) *ServiceDonat {
return &ServiceDonat{ return &ServiceDonat{
donatRepo: donatRepo, donatRepo: donatRepo,
widgetRepo: widgetRepo, widgetRepo: widgetRepo,
paymentClient: paymentClient, 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( func (donatService *ServiceDonat) CreateDonat(
ctx context.Context, ctx context.Context,
streamerID model.StreamerID, streamerID model.StreamerID,
@ -122,7 +151,21 @@ func (donatService *ServiceDonat) GetInnerDonatPage(
ctx context.Context, ctx context.Context,
streamerID model.StreamerID, streamerID model.StreamerID,
) (model.InnerDonatePageResponse, error) { ) (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( func (donatService *ServiceDonat) GetOuterDonatPage(

View File

@ -3,19 +3,25 @@ package target
import ( import (
"context" "context"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/api"
"github.com/labstack/echo/v4"
"log/slog" "log/slog"
"net/http"
) )
func New( func New(
targetRepo model.TargetRepo, targetRepo model.TargetRepo,
authClient model.AuthClient,
) *ServiceTarget { ) *ServiceTarget {
return &ServiceTarget{ return &ServiceTarget{
targetRepo: targetRepo, targetRepo: targetRepo,
authClient: authClient,
} }
} }
type ServiceTarget struct { type ServiceTarget struct {
targetRepo model.TargetRepo targetRepo model.TargetRepo
authClient model.AuthClient
} }
func (targetService *ServiceTarget) CreateTarget( func (targetService *ServiceTarget) CreateTarget(
@ -57,3 +63,27 @@ func (targetService *ServiceTarget) AddAmountToTarget(
} }
return nil 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
}

View File

@ -4,9 +4,9 @@ import (
"bytes" "bytes"
"donat-widget/internal/model" "donat-widget/internal/model"
"donat-widget/internal/model/api" "donat-widget/internal/model/api"
"donat-widget/pkg/custom_response"
"encoding/json" "encoding/json"
"errors" "errors"
"github.com/labstack/echo/v4"
"io" "io"
"log/slog" "log/slog"
"net/http" "net/http"
@ -26,41 +26,38 @@ type ClientAuth struct {
} }
func (c *ClientAuth) CheckToken( func (c *ClientAuth) CheckToken(
request echo.Context, accessToken model.Token,
) (api.CheckTokenResponse, error) { ) (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) req, err := http.NewRequest("GET", c.baseURL+"/token/check", nil)
if err != nil { if err != nil {
slog.Error("http.NewRequest: " + err.Error()) 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) resp, err := c.client.Do(req)
if err != nil { if err != nil {
slog.Error("client.Do: " + err.Error()) slog.Error("client.Do: " + err.Error())
return api.CheckTokenResponse{}, err return api.CheckTokenResponse{}, errors.New(custom_response.InternalError)
}
if resp.StatusCode != http.StatusOK {
return api.CheckTokenResponse{}, errors.New("get failed: " + resp.Status)
} }
response, err := io.ReadAll(resp.Body) response, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
slog.Error("io.ReadAll: " + err.Error()) 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) err = json.Unmarshal(response, &checkTokenResponse)
if err != nil { if err != nil {
slog.Error("json.Unmarshal: " + err.Error()) slog.Error("json.Unmarshal: " + err.Error())
return api.CheckTokenResponse{}, err return api.CheckTokenResponse{}, errors.New(custom_response.InternalError)
} }
return checkTokenResponse, nil return checkTokenResponse, nil
} }

View File

@ -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"`
}