Spaces:
Configuration error
Configuration error
Commit ·
895f95d
1
Parent(s): f82cdef
Deploy files from GitHub repository
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- services/external_authentication_service.go +18 -1
- space/controller/academy/academy_controller.go +31 -0
- space/logs/error_log.txt +2 -0
- space/models/database_orm_model.go +7 -7
- space/repositories/academy_repository.go +28 -2
- space/router/academy_route.go +16 -0
- space/router/router.go +1 -1
- space/services/academy_service.go +75 -11
- space/services/email_verification_service.go +5 -2
- space/services/forgot_password_service.go +4 -1
- space/space/logs/error_log.txt +0 -1
- space/space/models/response_model.go +9 -6
- space/space/repositories/academy_repository.go +47 -0
- space/space/services/academy_service.go +40 -0
- space/space/services/external_authentication_service.go +1 -0
- space/space/services/forgot_password_service.go +11 -7
- space/space/space/space/go.mod +2 -5
- space/space/space/space/go.sum +17 -13
- space/space/space/space/space/models/request_model.go +1 -1
- space/space/space/space/space/models/response_model.go +10 -0
- space/space/space/space/space/services/forgot_password_service.go +7 -3
- space/space/space/space/space/space/controller/auth/auth_external_controller.go +1 -1
- space/space/space/space/space/space/controller/auth/auth_forgot_password_controller.go +28 -0
- space/space/space/space/space/space/controller/email/email_validate_controller.go +0 -1
- space/space/space/space/space/space/models/request_model.go +9 -4
- space/space/space/space/space/space/repositories/account_repository.go +2 -4
- space/space/space/space/space/space/router/auth_route.go +2 -0
- space/space/space/space/space/space/services/authentication_service.go +2 -1
- space/space/space/space/space/space/services/email_verification_service.go +5 -1
- space/space/space/space/space/space/services/external_authentication_service.go +6 -1
- space/space/space/space/space/space/services/forgot_password_service.go +105 -0
- space/space/space/space/space/space/services/user_profile_service.go +20 -5
- space/space/space/space/space/space/space/space/services/email_verification_service.go +11 -60
- space/space/space/space/space/space/space/space/space/space/services/email_verification_service.go +60 -11
- space/space/space/space/space/space/space/space/space/space/space/space/models/request_model.go +4 -2
- space/space/space/space/space/space/space/space/space/space/space/space/services/authentication_service.go +2 -0
- space/space/space/space/space/space/space/space/space/space/space/space/services/email_verification_service.go +4 -0
- space/space/space/space/space/space/space/space/space/space/space/space/services/user_profile_service.go +8 -3
- space/space/space/space/space/space/space/space/space/space/space/space/space/repositories/account_repository.go +9 -0
- space/space/space/space/space/space/space/space/space/space/space/space/space/services/external_authentication_service.go +1 -1
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/services/user_profile_service.go +8 -2
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/docker-compose.yml +1 -1
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/Dockerfile +3 -0
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/controller/user/user_profile_controller.go +1 -1
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/controller/user/user_update_profile_controller.go +2 -4
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/logs/error_log.txt +1 -0
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/models/response_model.go +5 -0
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/repositories/account_repository.go +0 -4
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/repositories/forgot_password_repository.go +22 -0
- space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/router/router.go +8 -1
services/external_authentication_service.go
CHANGED
|
@@ -32,17 +32,34 @@ func (s *GoogleAuthService) Authenticate(isAgree bool) {
|
|
| 32 |
}
|
| 33 |
s.Constructor.UUID = uuid.NewV4()
|
| 34 |
s.Constructor.OauthProvider = "Google"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
createAccount := repositories.CreateAccount(models.Account{
|
| 36 |
UUID: uuid.NewV4(),
|
| 37 |
Email: email.(string),
|
| 38 |
IsEmailVerified: true,
|
| 39 |
})
|
|
|
|
| 40 |
s.Constructor.AccountID = createAccount.Result.Id
|
| 41 |
createGoogleAuth := repositories.CreateExternalAuth(s.Constructor)
|
| 42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
s.Error = createGoogleAuth.RowsError
|
| 44 |
s.Error = errors.Join(s.Error, createAccount.RowsError)
|
| 45 |
}
|
|
|
|
| 46 |
accountData := repositories.GetAccountById(GoogleAuth.Result.AccountID)
|
| 47 |
token, err_tok := GenerateToken(&accountData.Result)
|
| 48 |
|
|
|
|
| 32 |
}
|
| 33 |
s.Constructor.UUID = uuid.NewV4()
|
| 34 |
s.Constructor.OauthProvider = "Google"
|
| 35 |
+
checkRegisteredEmail := repositories.GetAccountbyEmail(email.(string))
|
| 36 |
+
if !checkRegisteredEmail.NoRecord {
|
| 37 |
+
s.Exception.DataDuplicate = true
|
| 38 |
+
s.Exception.Message = "Account with email" + email.(string) + "already registered!"
|
| 39 |
+
return
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
createAccount := repositories.CreateAccount(models.Account{
|
| 43 |
UUID: uuid.NewV4(),
|
| 44 |
Email: email.(string),
|
| 45 |
IsEmailVerified: true,
|
| 46 |
})
|
| 47 |
+
|
| 48 |
s.Constructor.AccountID = createAccount.Result.Id
|
| 49 |
createGoogleAuth := repositories.CreateExternalAuth(s.Constructor)
|
| 50 |
+
|
| 51 |
+
GoogleAuth.Result.AccountID = createGoogleAuth.Result.AccountID
|
| 52 |
+
userProfile := UserProfileService{}
|
| 53 |
+
userProfile.Constructor.AccountID = GoogleAuth.Result.AccountID
|
| 54 |
+
userProfile.Create()
|
| 55 |
+
if userProfile.Error != nil {
|
| 56 |
+
s.Error = userProfile.Error
|
| 57 |
+
return
|
| 58 |
+
}
|
| 59 |
s.Error = createGoogleAuth.RowsError
|
| 60 |
s.Error = errors.Join(s.Error, createAccount.RowsError)
|
| 61 |
}
|
| 62 |
+
|
| 63 |
accountData := repositories.GetAccountById(GoogleAuth.Result.AccountID)
|
| 64 |
token, err_tok := GenerateToken(&accountData.Result)
|
| 65 |
|
space/controller/academy/academy_controller.go
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package academy
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"api.qobiltu.id/controller"
|
| 5 |
+
"api.qobiltu.id/models"
|
| 6 |
+
"api.qobiltu.id/services"
|
| 7 |
+
"github.com/gin-gonic/gin"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
func List(c *gin.Context) {
|
| 11 |
+
academy := services.AcademyService{}
|
| 12 |
+
academyController := controller.Controller[any, models.Academy, models.AllAcademyResponse]{
|
| 13 |
+
Service: &academy.Service,
|
| 14 |
+
}
|
| 15 |
+
academyController.Service.Constructor.Slug = c.Param("slug")
|
| 16 |
+
academy.Retrieve()
|
| 17 |
+
academyController.Response(c)
|
| 18 |
+
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
func Create(c *gin.Context) {
|
| 22 |
+
createAcademy := services.CreateAcademyService{}
|
| 23 |
+
academyController := controller.Controller[models.AllAcademyResponse, models.AllAcademyResponse, models.AllAcademyResponse]{
|
| 24 |
+
Service: &createAcademy.Service,
|
| 25 |
+
}
|
| 26 |
+
academyController.RequestJSON(c, func() {
|
| 27 |
+
academyController.Service.Constructor.Academies = academyController.Request.Academies
|
| 28 |
+
createAcademy.Create()
|
| 29 |
+
})
|
| 30 |
+
|
| 31 |
+
}
|
space/logs/error_log.txt
CHANGED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2025/04/20 10:05:28 Error Log : duplicated key not allowed
|
| 2 |
+
2025/04/20 10:11:41 Error Log : duplicated key not allowed
|
space/models/database_orm_model.go
CHANGED
|
@@ -30,7 +30,7 @@ type AccountDetails struct {
|
|
| 30 |
LastEducation *string `json:"last_education"`
|
| 31 |
MaritalStatus *string `json:"marital_status"`
|
| 32 |
Avatar *string `json:"avatar"`
|
| 33 |
-
PhoneNumber *
|
| 34 |
}
|
| 35 |
|
| 36 |
type EmailVerification struct {
|
|
@@ -85,12 +85,12 @@ type AcademyMaterial struct {
|
|
| 85 |
}
|
| 86 |
|
| 87 |
type AcademyContent struct {
|
| 88 |
-
ID uint
|
| 89 |
-
UUID
|
| 90 |
-
Title string
|
| 91 |
-
Order uint
|
| 92 |
-
AcademyMaterialID uint
|
| 93 |
-
Description string
|
| 94 |
}
|
| 95 |
type OptionCategory struct {
|
| 96 |
ID uint `gorm:"primaryKey" json:"id"`
|
|
|
|
| 30 |
LastEducation *string `json:"last_education"`
|
| 31 |
MaritalStatus *string `json:"marital_status"`
|
| 32 |
Avatar *string `json:"avatar"`
|
| 33 |
+
PhoneNumber *string `json:"phone_number"`
|
| 34 |
}
|
| 35 |
|
| 36 |
type EmailVerification struct {
|
|
|
|
| 85 |
}
|
| 86 |
|
| 87 |
type AcademyContent struct {
|
| 88 |
+
ID uint `gorm:"primaryKey" json:"id"`
|
| 89 |
+
UUID uuid.UUID `json:"uuid"`
|
| 90 |
+
Title string `json:"title"`
|
| 91 |
+
Order uint `json:"order"`
|
| 92 |
+
AcademyMaterialID uint `json:"academy_material_id"`
|
| 93 |
+
Description string `json:"description"`
|
| 94 |
}
|
| 95 |
type OptionCategory struct {
|
| 96 |
ID uint `gorm:"primaryKey" json:"id"`
|
space/repositories/academy_repository.go
CHANGED
|
@@ -13,9 +13,9 @@ func GetAllAcademy() Repository[models.Academy, []models.Academy] {
|
|
| 13 |
return *repo
|
| 14 |
}
|
| 15 |
|
| 16 |
-
func
|
| 17 |
repo := Construct[models.Academy, models.Academy](
|
| 18 |
-
models.Academy{
|
| 19 |
)
|
| 20 |
repo.Transactions(
|
| 21 |
WhereGivenConstructor[models.Academy, models.Academy],
|
|
@@ -45,3 +45,29 @@ func GetAllAcademyContentsByMaterialID(materialId uint) Repository[models.Academ
|
|
| 45 |
)
|
| 46 |
return *repo
|
| 47 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
return *repo
|
| 14 |
}
|
| 15 |
|
| 16 |
+
func GetAcademyDataBySlug(slug string) Repository[models.Academy, models.Academy] {
|
| 17 |
repo := Construct[models.Academy, models.Academy](
|
| 18 |
+
models.Academy{Slug: slug},
|
| 19 |
)
|
| 20 |
repo.Transactions(
|
| 21 |
WhereGivenConstructor[models.Academy, models.Academy],
|
|
|
|
| 45 |
)
|
| 46 |
return *repo
|
| 47 |
}
|
| 48 |
+
|
| 49 |
+
func CreateAcademy(academies models.Academy) Repository[models.Academy, models.Academy] {
|
| 50 |
+
repo := Construct[models.Academy, models.Academy](
|
| 51 |
+
academies,
|
| 52 |
+
)
|
| 53 |
+
|
| 54 |
+
Create(repo)
|
| 55 |
+
return *repo
|
| 56 |
+
}
|
| 57 |
+
|
| 58 |
+
func CreateAcademyMaterial(academyMaterial models.AcademyMaterial) Repository[models.AcademyMaterial, models.AcademyMaterial] {
|
| 59 |
+
repo := Construct[models.AcademyMaterial, models.AcademyMaterial](
|
| 60 |
+
academyMaterial,
|
| 61 |
+
)
|
| 62 |
+
|
| 63 |
+
Create(repo)
|
| 64 |
+
return *repo
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
func CreateAcademyContent(academyContent models.AcademyContent) Repository[models.AcademyContent, models.AcademyContent] {
|
| 68 |
+
repo := Construct[models.AcademyContent, models.AcademyContent](
|
| 69 |
+
academyContent,
|
| 70 |
+
)
|
| 71 |
+
Create(repo)
|
| 72 |
+
return *repo
|
| 73 |
+
}
|
space/router/academy_route.go
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package router
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
AcademyController "api.qobiltu.id/controller/academy"
|
| 5 |
+
"api.qobiltu.id/middleware"
|
| 6 |
+
"github.com/gin-gonic/gin"
|
| 7 |
+
)
|
| 8 |
+
|
| 9 |
+
func AcademyRoute(router *gin.Engine) {
|
| 10 |
+
routerGroup := router.Group("/api/v1/academy")
|
| 11 |
+
{
|
| 12 |
+
routerGroup.GET("/list/:slug", middleware.AuthUser, AcademyController.List)
|
| 13 |
+
routerGroup.GET("/list", middleware.AuthUser, AcademyController.List)
|
| 14 |
+
routerGroup.POST("/create", middleware.AuthUser, AcademyController.Create)
|
| 15 |
+
}
|
| 16 |
+
}
|
space/router/router.go
CHANGED
|
@@ -16,7 +16,7 @@ func StartService() {
|
|
| 16 |
UserRoute(router)
|
| 17 |
EmailRoute(router)
|
| 18 |
OptionsRoute(router)
|
| 19 |
-
|
| 20 |
err := router.Run(config.TCP_ADDRESS)
|
| 21 |
if err != nil {
|
| 22 |
log.Fatalf("Failed to run server: %v", err)
|
|
|
|
| 16 |
UserRoute(router)
|
| 17 |
EmailRoute(router)
|
| 18 |
OptionsRoute(router)
|
| 19 |
+
AcademyRoute(router)
|
| 20 |
err := router.Run(config.TCP_ADDRESS)
|
| 21 |
if err != nil {
|
| 22 |
log.Fatalf("Failed to run server: %v", err)
|
space/services/academy_service.go
CHANGED
|
@@ -3,38 +3,102 @@ package services
|
|
| 3 |
import (
|
| 4 |
"api.qobiltu.id/models"
|
| 5 |
"api.qobiltu.id/repositories"
|
|
|
|
|
|
|
| 6 |
)
|
| 7 |
|
| 8 |
type AcademyService struct {
|
| 9 |
Service[models.Academy, models.AllAcademyResponse]
|
| 10 |
}
|
| 11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
func (s *AcademyService) Retrieve() {
|
| 13 |
-
if s.Constructor.
|
| 14 |
-
AcademyRepo := repositories.
|
| 15 |
s.Error = AcademyRepo.RowsError
|
| 16 |
if AcademyRepo.NoRecord {
|
| 17 |
s.Exception.Message = "Academy not found"
|
| 18 |
s.Exception.DataNotFound = true
|
| 19 |
return
|
| 20 |
}
|
| 21 |
-
|
| 22 |
-
for _, academyMaterial := range repositories.GetAllAcademyMaterialsByAcademyID(s.Constructor.ID).Result {
|
| 23 |
-
ArrMaterials = append(ArrMaterials, models.AcademyMaterialResponse{
|
| 24 |
-
Materials: academyMaterial,
|
| 25 |
-
Contents: repositories.GetAllAcademyContentsByMaterialID(academyMaterial.ID).Result,
|
| 26 |
-
})
|
| 27 |
-
}
|
| 28 |
s.Result = models.AllAcademyResponse{
|
| 29 |
Academies: []models.AcademyResponse{
|
| 30 |
models.AcademyResponse{
|
| 31 |
Academy: AcademyRepo.Result,
|
| 32 |
-
Materials:
|
| 33 |
},
|
| 34 |
},
|
| 35 |
}
|
| 36 |
} else {
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
}
|
|
|
|
| 39 |
|
| 40 |
}
|
|
|
|
| 3 |
import (
|
| 4 |
"api.qobiltu.id/models"
|
| 5 |
"api.qobiltu.id/repositories"
|
| 6 |
+
"github.com/gosimple/slug"
|
| 7 |
+
uuid "github.com/satori/go.uuid"
|
| 8 |
)
|
| 9 |
|
| 10 |
type AcademyService struct {
|
| 11 |
Service[models.Academy, models.AllAcademyResponse]
|
| 12 |
}
|
| 13 |
|
| 14 |
+
type CreateAcademyService struct {
|
| 15 |
+
Service[models.AllAcademyResponse, models.AllAcademyResponse]
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
func castAcademyMaterials(academyId uint) []models.AcademyMaterialResponse {
|
| 19 |
+
var ArrMaterials []models.AcademyMaterialResponse
|
| 20 |
+
for _, academyMaterial := range repositories.GetAllAcademyMaterialsByAcademyID(academyId).Result {
|
| 21 |
+
ArrMaterials = append(ArrMaterials, models.AcademyMaterialResponse{
|
| 22 |
+
Materials: academyMaterial,
|
| 23 |
+
Contents: repositories.GetAllAcademyContentsByMaterialID(academyMaterial.ID).Result,
|
| 24 |
+
})
|
| 25 |
+
}
|
| 26 |
+
return ArrMaterials
|
| 27 |
+
}
|
| 28 |
func (s *AcademyService) Retrieve() {
|
| 29 |
+
if s.Constructor.Slug != "" {
|
| 30 |
+
AcademyRepo := repositories.GetAcademyDataBySlug(s.Constructor.Slug)
|
| 31 |
s.Error = AcademyRepo.RowsError
|
| 32 |
if AcademyRepo.NoRecord {
|
| 33 |
s.Exception.Message = "Academy not found"
|
| 34 |
s.Exception.DataNotFound = true
|
| 35 |
return
|
| 36 |
}
|
| 37 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
s.Result = models.AllAcademyResponse{
|
| 39 |
Academies: []models.AcademyResponse{
|
| 40 |
models.AcademyResponse{
|
| 41 |
Academy: AcademyRepo.Result,
|
| 42 |
+
Materials: castAcademyMaterials(s.Constructor.ID),
|
| 43 |
},
|
| 44 |
},
|
| 45 |
}
|
| 46 |
} else {
|
| 47 |
+
AcademyRepo := repositories.GetAllAcademy()
|
| 48 |
+
s.Error = AcademyRepo.RowsError
|
| 49 |
+
var ArrAcademy []models.AcademyResponse
|
| 50 |
+
for _, academy := range AcademyRepo.Result {
|
| 51 |
+
ArrAcademy = append(ArrAcademy, models.AcademyResponse{
|
| 52 |
+
Academy: academy,
|
| 53 |
+
Materials: castAcademyMaterials(academy.ID),
|
| 54 |
+
})
|
| 55 |
+
}
|
| 56 |
+
s.Result = models.AllAcademyResponse{
|
| 57 |
+
Academies: ArrAcademy,
|
| 58 |
+
}
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
func (s *CreateAcademyService) Create() {
|
| 64 |
+
var ArrAcademy []models.AcademyResponse
|
| 65 |
+
for _, academy := range s.Constructor.Academies {
|
| 66 |
+
academy.Academy.UUID = uuid.NewV4()
|
| 67 |
+
if academy.Academy.Slug == "" {
|
| 68 |
+
academy.Academy.Slug = slug.Make(academy.Academy.Title)
|
| 69 |
+
}
|
| 70 |
+
|
| 71 |
+
createdAcademy := repositories.CreateAcademy(academy.Academy)
|
| 72 |
+
if createdAcademy.RowsError != nil {
|
| 73 |
+
s.Error = createdAcademy.RowsError
|
| 74 |
+
return
|
| 75 |
+
}
|
| 76 |
+
for _, material := range academy.Materials {
|
| 77 |
+
material.Materials.AcademyID = createdAcademy.Result.ID
|
| 78 |
+
material.Materials.UUID = uuid.NewV4()
|
| 79 |
+
if material.Materials.Slug == "" {
|
| 80 |
+
material.Materials.Slug = slug.Make(material.Materials.Title)
|
| 81 |
+
}
|
| 82 |
+
createdMaterial := repositories.CreateAcademyMaterial(material.Materials)
|
| 83 |
+
if createdMaterial.RowsError != nil {
|
| 84 |
+
s.Error = createdMaterial.RowsError
|
| 85 |
+
return
|
| 86 |
+
}
|
| 87 |
+
for _, content := range material.Contents {
|
| 88 |
+
content.UUID = uuid.NewV4()
|
| 89 |
+
content.AcademyMaterialID = createdMaterial.Result.ID
|
| 90 |
+
createdContent := repositories.CreateAcademyContent(content)
|
| 91 |
+
if createdContent.RowsError != nil {
|
| 92 |
+
s.Error = createdContent.RowsError
|
| 93 |
+
return
|
| 94 |
+
}
|
| 95 |
+
ArrAcademy = append(ArrAcademy, models.AcademyResponse{
|
| 96 |
+
Academy: createdAcademy.Result,
|
| 97 |
+
Materials: castAcademyMaterials(createdAcademy.Result.ID),
|
| 98 |
+
})
|
| 99 |
+
}
|
| 100 |
+
}
|
| 101 |
}
|
| 102 |
+
s.Result = models.AllAcademyResponse{Academies: ArrAcademy}
|
| 103 |
|
| 104 |
}
|
space/services/email_verification_service.go
CHANGED
|
@@ -29,7 +29,10 @@ func (s *EmailVerificationService) Create() {
|
|
| 29 |
remainingTime := time.Duration(config.EMAIL_VERIFICATION_DURATION) * time.Hour
|
| 30 |
dueTime := CalculateDueTime(remainingTime)
|
| 31 |
|
| 32 |
-
token := uint(rand.IntN(
|
|
|
|
|
|
|
|
|
|
| 33 |
s.Constructor.UUID = uuid.NewV4()
|
| 34 |
|
| 35 |
repo := repositories.CreateEmailVerification(s.Constructor.UUID, s.Constructor.AccountID, dueTime, token)
|
|
@@ -83,7 +86,7 @@ func (s *EmailVerificationService) Validate() {
|
|
| 83 |
}
|
| 84 |
account := repositories.GetAccountById(repo.Result.AccountID)
|
| 85 |
account.Result.IsEmailVerified = true
|
| 86 |
-
|
| 87 |
repositories.UpdateAccount(account.Result)
|
| 88 |
s.Result = repo.Result
|
| 89 |
}
|
|
|
|
| 29 |
remainingTime := time.Duration(config.EMAIL_VERIFICATION_DURATION) * time.Hour
|
| 30 |
dueTime := CalculateDueTime(remainingTime)
|
| 31 |
|
| 32 |
+
token := uint(rand.IntN(1000000))
|
| 33 |
+
for token < 1000000 {
|
| 34 |
+
token = uint(rand.IntN(1000000))
|
| 35 |
+
}
|
| 36 |
s.Constructor.UUID = uuid.NewV4()
|
| 37 |
|
| 38 |
repo := repositories.CreateEmailVerification(s.Constructor.UUID, s.Constructor.AccountID, dueTime, token)
|
|
|
|
| 86 |
}
|
| 87 |
account := repositories.GetAccountById(repo.Result.AccountID)
|
| 88 |
account.Result.IsEmailVerified = true
|
| 89 |
+
|
| 90 |
repositories.UpdateAccount(account.Result)
|
| 91 |
s.Result = repo.Result
|
| 92 |
}
|
space/services/forgot_password_service.go
CHANGED
|
@@ -34,7 +34,10 @@ func (s *ForgotPasswordService) Create(email string) {
|
|
| 34 |
remainingTime := time.Duration(config.EMAIL_VERIFICATION_DURATION) * time.Hour
|
| 35 |
dueTime := CalculateDueTime(remainingTime)
|
| 36 |
|
| 37 |
-
token := uint(rand.IntN(
|
|
|
|
|
|
|
|
|
|
| 38 |
s.Constructor.UUID = uuid.NewV4()
|
| 39 |
s.Constructor.ExpiredAt = dueTime
|
| 40 |
s.Constructor.AccountID = accountRepo.Result.Id
|
|
|
|
| 34 |
remainingTime := time.Duration(config.EMAIL_VERIFICATION_DURATION) * time.Hour
|
| 35 |
dueTime := CalculateDueTime(remainingTime)
|
| 36 |
|
| 37 |
+
token := uint(rand.IntN(1000000))
|
| 38 |
+
for token < 1000000 {
|
| 39 |
+
token = uint(rand.IntN(1000000))
|
| 40 |
+
}
|
| 41 |
s.Constructor.UUID = uuid.NewV4()
|
| 42 |
s.Constructor.ExpiredAt = dueTime
|
| 43 |
s.Constructor.AccountID = accountRepo.Result.Id
|
space/space/logs/error_log.txt
CHANGED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
|
|
|
|
|
|
space/space/models/response_model.go
CHANGED
|
@@ -31,12 +31,15 @@ type UserProfileResponse struct {
|
|
| 31 |
Details AccountDetails `json:"details"`
|
| 32 |
}
|
| 33 |
|
| 34 |
-
type
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
-
type
|
| 41 |
-
|
| 42 |
}
|
|
|
|
| 31 |
Details AccountDetails `json:"details"`
|
| 32 |
}
|
| 33 |
|
| 34 |
+
type AcademyMaterialResponse struct {
|
| 35 |
+
Materials AcademyMaterial
|
| 36 |
+
Contents []AcademyContent
|
| 37 |
+
}
|
| 38 |
+
type AcademyResponse struct {
|
| 39 |
+
Academy Academy `json:"academy"`
|
| 40 |
+
Materials []AcademyMaterialResponse `json:"academy_materials"`
|
| 41 |
}
|
| 42 |
|
| 43 |
+
type AllAcademyResponse struct {
|
| 44 |
+
Academies []AcademyResponse `json:"academy_dasar"`
|
| 45 |
}
|
space/space/repositories/academy_repository.go
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package repositories
|
| 2 |
+
|
| 3 |
+
import "api.qobiltu.id/models"
|
| 4 |
+
|
| 5 |
+
func GetAllAcademy() Repository[models.Academy, []models.Academy] {
|
| 6 |
+
repo := Construct[models.Academy, []models.Academy](
|
| 7 |
+
models.Academy{},
|
| 8 |
+
)
|
| 9 |
+
repo.Transactions(
|
| 10 |
+
WhereGivenConstructor[models.Academy, []models.Academy],
|
| 11 |
+
Find[models.Academy, []models.Academy],
|
| 12 |
+
)
|
| 13 |
+
return *repo
|
| 14 |
+
}
|
| 15 |
+
|
| 16 |
+
func GetAcademyDataById(academyId uint) Repository[models.Academy, models.Academy] {
|
| 17 |
+
repo := Construct[models.Academy, models.Academy](
|
| 18 |
+
models.Academy{ID: academyId},
|
| 19 |
+
)
|
| 20 |
+
repo.Transactions(
|
| 21 |
+
WhereGivenConstructor[models.Academy, models.Academy],
|
| 22 |
+
Find[models.Academy, models.Academy],
|
| 23 |
+
)
|
| 24 |
+
return *repo
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
func GetAllAcademyMaterialsByAcademyID(acaddemyId uint) Repository[models.AcademyMaterial, []models.AcademyMaterial] {
|
| 28 |
+
repo := Construct[models.AcademyMaterial, []models.AcademyMaterial](
|
| 29 |
+
models.AcademyMaterial{AcademyID: acaddemyId},
|
| 30 |
+
)
|
| 31 |
+
repo.Transactions(
|
| 32 |
+
WhereGivenConstructor[models.AcademyMaterial, []models.AcademyMaterial],
|
| 33 |
+
Find[models.AcademyMaterial, []models.AcademyMaterial],
|
| 34 |
+
)
|
| 35 |
+
return *repo
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
func GetAllAcademyContentsByMaterialID(materialId uint) Repository[models.AcademyContent, []models.AcademyContent] {
|
| 39 |
+
repo := Construct[models.AcademyContent, []models.AcademyContent](
|
| 40 |
+
models.AcademyContent{AcademyMaterialID: materialId},
|
| 41 |
+
)
|
| 42 |
+
repo.Transactions(
|
| 43 |
+
WhereGivenConstructor[models.AcademyContent, []models.AcademyContent],
|
| 44 |
+
Find[models.AcademyContent, []models.AcademyContent],
|
| 45 |
+
)
|
| 46 |
+
return *repo
|
| 47 |
+
}
|
space/space/services/academy_service.go
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package services
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"api.qobiltu.id/models"
|
| 5 |
+
"api.qobiltu.id/repositories"
|
| 6 |
+
)
|
| 7 |
+
|
| 8 |
+
type AcademyService struct {
|
| 9 |
+
Service[models.Academy, models.AllAcademyResponse]
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
func (s *AcademyService) Retrieve() {
|
| 13 |
+
if s.Constructor.ID != 0 {
|
| 14 |
+
AcademyRepo := repositories.GetAcademyDataById(s.Constructor.ID)
|
| 15 |
+
s.Error = AcademyRepo.RowsError
|
| 16 |
+
if AcademyRepo.NoRecord {
|
| 17 |
+
s.Exception.Message = "Academy not found"
|
| 18 |
+
s.Exception.DataNotFound = true
|
| 19 |
+
return
|
| 20 |
+
}
|
| 21 |
+
var ArrMaterials []models.AcademyMaterialResponse
|
| 22 |
+
for _, academyMaterial := range repositories.GetAllAcademyMaterialsByAcademyID(s.Constructor.ID).Result {
|
| 23 |
+
ArrMaterials = append(ArrMaterials, models.AcademyMaterialResponse{
|
| 24 |
+
Materials: academyMaterial,
|
| 25 |
+
Contents: repositories.GetAllAcademyContentsByMaterialID(academyMaterial.ID).Result,
|
| 26 |
+
})
|
| 27 |
+
}
|
| 28 |
+
s.Result = models.AllAcademyResponse{
|
| 29 |
+
Academies: []models.AcademyResponse{
|
| 30 |
+
models.AcademyResponse{
|
| 31 |
+
Academy: AcademyRepo.Result,
|
| 32 |
+
Materials: ArrMaterials,
|
| 33 |
+
},
|
| 34 |
+
},
|
| 35 |
+
}
|
| 36 |
+
} else {
|
| 37 |
+
// AcademyRepo := repositories.GetAllAcademy()
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
}
|
space/space/services/external_authentication_service.go
CHANGED
|
@@ -33,6 +33,7 @@ func (s *GoogleAuthService) Authenticate(isAgree bool) {
|
|
| 33 |
s.Constructor.UUID = uuid.NewV4()
|
| 34 |
s.Constructor.OauthProvider = "Google"
|
| 35 |
createAccount := repositories.CreateAccount(models.Account{
|
|
|
|
| 36 |
Email: email.(string),
|
| 37 |
IsEmailVerified: true,
|
| 38 |
})
|
|
|
|
| 33 |
s.Constructor.UUID = uuid.NewV4()
|
| 34 |
s.Constructor.OauthProvider = "Google"
|
| 35 |
createAccount := repositories.CreateAccount(models.Account{
|
| 36 |
+
UUID: uuid.NewV4(),
|
| 37 |
Email: email.(string),
|
| 38 |
IsEmailVerified: true,
|
| 39 |
})
|
space/space/services/forgot_password_service.go
CHANGED
|
@@ -71,13 +71,6 @@ func (s *ForgotPasswordService) Create(email string) {
|
|
| 71 |
}
|
| 72 |
|
| 73 |
func (s *ForgotPasswordService) Validate(newPassword *string) {
|
| 74 |
-
accountRepo := repositories.GetAccountById(s.Constructor.AccountID)
|
| 75 |
-
if accountRepo.NoRecord {
|
| 76 |
-
s.Error = accountRepo.RowsError
|
| 77 |
-
s.Exception.DataNotFound = true
|
| 78 |
-
s.Exception.Message = "There is no account data with given credentials!"
|
| 79 |
-
return
|
| 80 |
-
}
|
| 81 |
|
| 82 |
fgPasswordRepo := repositories.GetForgotPasswordByToken(s.Constructor.Token)
|
| 83 |
s.Error = fgPasswordRepo.RowsError
|
|
@@ -91,13 +84,24 @@ func (s *ForgotPasswordService) Validate(newPassword *string) {
|
|
| 91 |
s.Exception.Message = "Token has expired!"
|
| 92 |
return
|
| 93 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 94 |
s.Result = fgPasswordRepo.Result
|
| 95 |
if newPassword == nil {
|
| 96 |
return
|
| 97 |
}
|
|
|
|
|
|
|
| 98 |
hashed_password, _ := HashPassword(*newPassword)
|
| 99 |
accountRepo.Result.Password = hashed_password
|
| 100 |
changePassword := repositories.UpdateAccount(accountRepo.Result)
|
|
|
|
| 101 |
if changePassword.RowsError != nil {
|
| 102 |
s.Error = changePassword.RowsError
|
| 103 |
s.Exception.QueryError = true
|
|
|
|
| 71 |
}
|
| 72 |
|
| 73 |
func (s *ForgotPasswordService) Validate(newPassword *string) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
|
| 75 |
fgPasswordRepo := repositories.GetForgotPasswordByToken(s.Constructor.Token)
|
| 76 |
s.Error = fgPasswordRepo.RowsError
|
|
|
|
| 84 |
s.Exception.Message = "Token has expired!"
|
| 85 |
return
|
| 86 |
}
|
| 87 |
+
|
| 88 |
+
accountRepo := repositories.GetAccountById(fgPasswordRepo.Result.AccountID)
|
| 89 |
+
if accountRepo.NoRecord {
|
| 90 |
+
s.Error = accountRepo.RowsError
|
| 91 |
+
s.Exception.DataNotFound = true
|
| 92 |
+
s.Exception.Message = "There is no account data with given credentials!"
|
| 93 |
+
return
|
| 94 |
+
}
|
| 95 |
s.Result = fgPasswordRepo.Result
|
| 96 |
if newPassword == nil {
|
| 97 |
return
|
| 98 |
}
|
| 99 |
+
// fmt.Println("Previous Account", accountRepo.Result)
|
| 100 |
+
// fmt.Println("New password", *newPassword)
|
| 101 |
hashed_password, _ := HashPassword(*newPassword)
|
| 102 |
accountRepo.Result.Password = hashed_password
|
| 103 |
changePassword := repositories.UpdateAccount(accountRepo.Result)
|
| 104 |
+
// fmt.Println("New Account", changePassword.Result)
|
| 105 |
if changePassword.RowsError != nil {
|
| 106 |
s.Error = changePassword.RowsError
|
| 107 |
s.Exception.QueryError = true
|
space/space/space/space/go.mod
CHANGED
|
@@ -5,9 +5,11 @@ go 1.24.0
|
|
| 5 |
require (
|
| 6 |
github.com/gin-gonic/gin v1.10.0
|
| 7 |
github.com/golang-jwt/jwt/v5 v5.2.1
|
|
|
|
| 8 |
github.com/joho/godotenv v1.5.1
|
| 9 |
github.com/satori/go.uuid v1.2.0
|
| 10 |
golang.org/x/crypto v0.36.0
|
|
|
|
| 11 |
gorm.io/driver/postgres v1.5.11
|
| 12 |
gorm.io/gorm v1.25.12
|
| 13 |
)
|
|
@@ -31,7 +33,6 @@ require (
|
|
| 31 |
github.com/google/s2a-go v0.1.9 // indirect
|
| 32 |
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
| 33 |
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
| 34 |
-
github.com/gosimple/slug v1.15.0 // indirect
|
| 35 |
github.com/gosimple/unidecode v1.0.1 // indirect
|
| 36 |
github.com/jackc/pgpassfile v1.0.0 // indirect
|
| 37 |
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
|
@@ -41,13 +42,11 @@ require (
|
|
| 41 |
github.com/jinzhu/now v1.1.5 // indirect
|
| 42 |
github.com/json-iterator/go v1.1.12 // indirect
|
| 43 |
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
| 44 |
-
github.com/kr/text v0.2.0 // indirect
|
| 45 |
github.com/leodido/go-urn v1.4.0 // indirect
|
| 46 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 47 |
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
| 48 |
github.com/modern-go/reflect2 v1.0.2 // indirect
|
| 49 |
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
| 50 |
-
github.com/rogpeppe/go-internal v1.13.1 // indirect
|
| 51 |
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
| 52 |
github.com/ugorji/go/codec v1.2.12 // indirect
|
| 53 |
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
|
@@ -56,13 +55,11 @@ require (
|
|
| 56 |
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
| 57 |
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
| 58 |
golang.org/x/arch v0.15.0 // indirect
|
| 59 |
-
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
| 60 |
golang.org/x/net v0.37.0 // indirect
|
| 61 |
golang.org/x/oauth2 v0.28.0 // indirect
|
| 62 |
golang.org/x/sync v0.12.0 // indirect
|
| 63 |
golang.org/x/sys v0.31.0 // indirect
|
| 64 |
golang.org/x/text v0.23.0 // indirect
|
| 65 |
-
google.golang.org/api v0.228.0 // indirect
|
| 66 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
| 67 |
google.golang.org/grpc v1.71.0 // indirect
|
| 68 |
google.golang.org/protobuf v1.36.6 // indirect
|
|
|
|
| 5 |
require (
|
| 6 |
github.com/gin-gonic/gin v1.10.0
|
| 7 |
github.com/golang-jwt/jwt/v5 v5.2.1
|
| 8 |
+
github.com/gosimple/slug v1.15.0
|
| 9 |
github.com/joho/godotenv v1.5.1
|
| 10 |
github.com/satori/go.uuid v1.2.0
|
| 11 |
golang.org/x/crypto v0.36.0
|
| 12 |
+
google.golang.org/api v0.228.0
|
| 13 |
gorm.io/driver/postgres v1.5.11
|
| 14 |
gorm.io/gorm v1.25.12
|
| 15 |
)
|
|
|
|
| 33 |
github.com/google/s2a-go v0.1.9 // indirect
|
| 34 |
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
| 35 |
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
|
|
|
|
| 36 |
github.com/gosimple/unidecode v1.0.1 // indirect
|
| 37 |
github.com/jackc/pgpassfile v1.0.0 // indirect
|
| 38 |
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
|
|
|
| 42 |
github.com/jinzhu/now v1.1.5 // indirect
|
| 43 |
github.com/json-iterator/go v1.1.12 // indirect
|
| 44 |
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
|
|
|
| 45 |
github.com/leodido/go-urn v1.4.0 // indirect
|
| 46 |
github.com/mattn/go-isatty v0.0.20 // indirect
|
| 47 |
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
| 48 |
github.com/modern-go/reflect2 v1.0.2 // indirect
|
| 49 |
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
|
|
|
|
| 50 |
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
| 51 |
github.com/ugorji/go/codec v1.2.12 // indirect
|
| 52 |
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
|
|
|
| 55 |
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
| 56 |
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
| 57 |
golang.org/x/arch v0.15.0 // indirect
|
|
|
|
| 58 |
golang.org/x/net v0.37.0 // indirect
|
| 59 |
golang.org/x/oauth2 v0.28.0 // indirect
|
| 60 |
golang.org/x/sync v0.12.0 // indirect
|
| 61 |
golang.org/x/sys v0.31.0 // indirect
|
| 62 |
golang.org/x/text v0.23.0 // indirect
|
|
|
|
| 63 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 // indirect
|
| 64 |
google.golang.org/grpc v1.71.0 // indirect
|
| 65 |
google.golang.org/protobuf v1.36.6 // indirect
|
space/space/space/space/go.sum
CHANGED
|
@@ -12,7 +12,6 @@ github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFos
|
|
| 12 |
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
| 13 |
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
| 14 |
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
| 15 |
-
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
| 16 |
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
| 17 |
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
| 18 |
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
@@ -41,11 +40,15 @@ github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
|
| 41 |
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
| 42 |
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
| 43 |
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
| 44 |
-
github.com/
|
| 45 |
-
github.com/
|
|
|
|
|
|
|
| 46 |
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
| 47 |
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
| 48 |
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
|
|
|
|
|
|
| 49 |
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
| 50 |
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
| 51 |
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
|
@@ -74,8 +77,8 @@ github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa02
|
|
| 74 |
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
| 75 |
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
| 76 |
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
| 77 |
-
github.com/kr/pretty v0.3.
|
| 78 |
-
github.com/kr/pretty v0.3.
|
| 79 |
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
| 80 |
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
| 81 |
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
|
@@ -91,8 +94,7 @@ github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNH
|
|
| 91 |
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
| 92 |
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
| 93 |
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
| 94 |
-
github.com/rogpeppe/go-internal v1.
|
| 95 |
-
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
| 96 |
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
| 97 |
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
| 98 |
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
|
@@ -114,20 +116,24 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E
|
|
| 114 |
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
| 115 |
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
| 116 |
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
|
|
|
|
|
|
| 117 |
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
| 118 |
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
| 119 |
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
| 120 |
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
| 121 |
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
| 122 |
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
| 124 |
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
| 125 |
golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=
|
| 126 |
golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
| 127 |
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
| 128 |
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
| 129 |
-
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
| 130 |
-
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
| 131 |
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
| 132 |
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
| 133 |
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
|
@@ -139,16 +145,14 @@ golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
|
| 139 |
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
| 140 |
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
| 141 |
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
| 142 |
-
golang.org/x/
|
| 143 |
-
golang.org/x/
|
| 144 |
google.golang.org/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs=
|
| 145 |
google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4=
|
| 146 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
|
| 147 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
| 148 |
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
| 149 |
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
| 150 |
-
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
| 151 |
-
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
| 152 |
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
| 153 |
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
| 154 |
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
|
|
|
| 12 |
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
| 13 |
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
| 14 |
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
|
|
|
| 15 |
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
| 16 |
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
| 17 |
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
|
|
|
| 40 |
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
| 41 |
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
|
| 42 |
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
|
| 43 |
+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
| 44 |
+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
| 45 |
+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
| 46 |
+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
| 47 |
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
| 48 |
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
|
| 49 |
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
|
| 50 |
+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
| 51 |
+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
| 52 |
github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4=
|
| 53 |
github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
|
| 54 |
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
|
|
|
|
| 77 |
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
| 78 |
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
| 79 |
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
| 80 |
+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
| 81 |
+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
| 82 |
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
| 83 |
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
| 84 |
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
|
|
|
| 94 |
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
|
| 95 |
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
| 96 |
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
| 97 |
+
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
|
|
|
| 98 |
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
| 99 |
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
| 100 |
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
|
|
|
| 116 |
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
| 117 |
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
| 118 |
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
| 119 |
+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
|
| 120 |
+
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
|
| 121 |
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
|
| 122 |
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
|
| 123 |
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
| 124 |
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
| 125 |
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
| 126 |
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
| 127 |
+
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
| 128 |
+
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
| 129 |
+
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
| 130 |
+
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
| 131 |
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
| 132 |
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
| 133 |
golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw=
|
| 134 |
golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE=
|
| 135 |
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
| 136 |
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
|
|
|
|
|
|
| 137 |
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
| 138 |
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
| 139 |
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
|
|
|
| 145 |
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
| 146 |
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
| 147 |
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
| 148 |
+
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
| 149 |
+
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
| 150 |
google.golang.org/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs=
|
| 151 |
google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4=
|
| 152 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4 h1:iK2jbkWL86DXjEx0qiHcRE9dE4/Ahua5k6V8OWFb//c=
|
| 153 |
google.golang.org/genproto/googleapis/rpc v0.0.0-20250313205543-e70fdf4c4cb4/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
| 154 |
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
| 155 |
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
|
|
|
|
|
|
| 156 |
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
| 157 |
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
| 158 |
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
space/space/space/space/space/models/request_model.go
CHANGED
|
@@ -38,5 +38,5 @@ type ForgotPasswordRequest struct {
|
|
| 38 |
}
|
| 39 |
type ValidateForgotPasswordRequest struct {
|
| 40 |
Token uint `json:"token" binding:"required"`
|
| 41 |
-
NewPassword string `json:"new_password"
|
| 42 |
}
|
|
|
|
| 38 |
}
|
| 39 |
type ValidateForgotPasswordRequest struct {
|
| 40 |
Token uint `json:"token" binding:"required"`
|
| 41 |
+
NewPassword string `json:"new_password"`
|
| 42 |
}
|
space/space/space/space/space/models/response_model.go
CHANGED
|
@@ -30,3 +30,13 @@ type UserProfileResponse struct {
|
|
| 30 |
Account Account `json:"account"`
|
| 31 |
Details AccountDetails `json:"details"`
|
| 32 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
Account Account `json:"account"`
|
| 31 |
Details AccountDetails `json:"details"`
|
| 32 |
}
|
| 33 |
+
|
| 34 |
+
type AkademiDasar struct {
|
| 35 |
+
Academies Academy `json:"academy"`
|
| 36 |
+
Materials []AcademyMaterial `json:"academy_material"`
|
| 37 |
+
Contents []AcademyContent `json:"academy_content"`
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
type AkademiDasarResponse struct {
|
| 41 |
+
AkademiDasar []AkademiDasar `json:"academy_dasar"`
|
| 42 |
+
}
|
space/space/space/space/space/services/forgot_password_service.go
CHANGED
|
@@ -70,7 +70,7 @@ func (s *ForgotPasswordService) Create(email string) {
|
|
| 70 |
// s.Result.Token = 0
|
| 71 |
}
|
| 72 |
|
| 73 |
-
func (s *ForgotPasswordService) Validate(newPassword string) {
|
| 74 |
accountRepo := repositories.GetAccountById(s.Constructor.AccountID)
|
| 75 |
if accountRepo.NoRecord {
|
| 76 |
s.Error = accountRepo.RowsError
|
|
@@ -91,7 +91,11 @@ func (s *ForgotPasswordService) Validate(newPassword string) {
|
|
| 91 |
s.Exception.Message = "Token has expired!"
|
| 92 |
return
|
| 93 |
}
|
| 94 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
accountRepo.Result.Password = hashed_password
|
| 96 |
changePassword := repositories.UpdateAccount(accountRepo.Result)
|
| 97 |
if changePassword.RowsError != nil {
|
|
@@ -101,5 +105,5 @@ func (s *ForgotPasswordService) Validate(newPassword string) {
|
|
| 101 |
return
|
| 102 |
}
|
| 103 |
// fgPasswordRepo.Result.Token = 0
|
| 104 |
-
|
| 105 |
}
|
|
|
|
| 70 |
// s.Result.Token = 0
|
| 71 |
}
|
| 72 |
|
| 73 |
+
func (s *ForgotPasswordService) Validate(newPassword *string) {
|
| 74 |
accountRepo := repositories.GetAccountById(s.Constructor.AccountID)
|
| 75 |
if accountRepo.NoRecord {
|
| 76 |
s.Error = accountRepo.RowsError
|
|
|
|
| 91 |
s.Exception.Message = "Token has expired!"
|
| 92 |
return
|
| 93 |
}
|
| 94 |
+
s.Result = fgPasswordRepo.Result
|
| 95 |
+
if newPassword == nil {
|
| 96 |
+
return
|
| 97 |
+
}
|
| 98 |
+
hashed_password, _ := HashPassword(*newPassword)
|
| 99 |
accountRepo.Result.Password = hashed_password
|
| 100 |
changePassword := repositories.UpdateAccount(accountRepo.Result)
|
| 101 |
if changePassword.RowsError != nil {
|
|
|
|
| 105 |
return
|
| 106 |
}
|
| 107 |
// fgPasswordRepo.Result.Token = 0
|
| 108 |
+
|
| 109 |
}
|
space/space/space/space/space/space/controller/auth/auth_external_controller.go
CHANGED
|
@@ -14,7 +14,7 @@ func ExternalAuth(c *gin.Context) {
|
|
| 14 |
GoogleLogin := services.GoogleAuthService{}
|
| 15 |
ExternalAuthController.Service = &GoogleLogin.Service
|
| 16 |
ExternalAuthController.Service.Constructor.OauthID = ExternalAuthController.Request.OauthID
|
| 17 |
-
GoogleLogin.Authenticate()
|
| 18 |
}
|
| 19 |
})
|
| 20 |
}
|
|
|
|
| 14 |
GoogleLogin := services.GoogleAuthService{}
|
| 15 |
ExternalAuthController.Service = &GoogleLogin.Service
|
| 16 |
ExternalAuthController.Service.Constructor.OauthID = ExternalAuthController.Request.OauthID
|
| 17 |
+
GoogleLogin.Authenticate(ExternalAuthController.Request.IsAgreeTerms && !ExternalAuthController.Request.IsSexualDisease)
|
| 18 |
}
|
| 19 |
})
|
| 20 |
}
|
space/space/space/space/space/space/controller/auth/auth_forgot_password_controller.go
CHANGED
|
@@ -1 +1,29 @@
|
|
| 1 |
package auth
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
package auth
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"api.qobiltu.id/controller"
|
| 5 |
+
"api.qobiltu.id/models"
|
| 6 |
+
"api.qobiltu.id/services"
|
| 7 |
+
"github.com/gin-gonic/gin"
|
| 8 |
+
)
|
| 9 |
+
|
| 10 |
+
func CreateForgotPassword(c *gin.Context) {
|
| 11 |
+
ForgotPassword := services.ForgotPasswordService{}
|
| 12 |
+
ForgotPasswordController := controller.Controller[models.ForgotPasswordRequest, models.ForgotPassword, models.ForgotPassword]{
|
| 13 |
+
Service: &ForgotPassword.Service,
|
| 14 |
+
}
|
| 15 |
+
ForgotPasswordController.RequestJSON(c, func() {
|
| 16 |
+
ForgotPassword.Create(ForgotPasswordController.Request.Email)
|
| 17 |
+
})
|
| 18 |
+
|
| 19 |
+
}
|
| 20 |
+
func ValidateForgotPassword(c *gin.Context) {
|
| 21 |
+
ForgotPassword := services.ForgotPasswordService{}
|
| 22 |
+
ForgotPasswordController := controller.Controller[models.ValidateForgotPasswordRequest, models.ForgotPassword, models.ForgotPassword]{
|
| 23 |
+
Service: &ForgotPassword.Service,
|
| 24 |
+
}
|
| 25 |
+
ForgotPasswordController.RequestJSON(c, func() {
|
| 26 |
+
ForgotPasswordController.Service.Constructor.Token = ForgotPasswordController.Request.Token
|
| 27 |
+
ForgotPassword.Validate(&ForgotPasswordController.Request.NewPassword)
|
| 28 |
+
})
|
| 29 |
+
}
|
space/space/space/space/space/space/controller/email/email_validate_controller.go
CHANGED
|
@@ -16,7 +16,6 @@ func Verify(c *gin.Context) {
|
|
| 16 |
emailVerificationController.Service.Constructor.AccountID = uint(emailVerificationController.AccountData.UserID)
|
| 17 |
emailVerificationController.RequestJSON(c, func() {
|
| 18 |
emailVerificationController.Service.Constructor.Token = emailVerificationController.Request.Token
|
| 19 |
-
emailVerificationController.Service.Constructor.UUID = emailVerificationController.Request.UUID
|
| 20 |
emailVerification.Validate()
|
| 21 |
})
|
| 22 |
})
|
|
|
|
| 16 |
emailVerificationController.Service.Constructor.AccountID = uint(emailVerificationController.AccountData.UserID)
|
| 17 |
emailVerificationController.RequestJSON(c, func() {
|
| 18 |
emailVerificationController.Service.Constructor.Token = emailVerificationController.Request.Token
|
|
|
|
| 19 |
emailVerification.Validate()
|
| 20 |
})
|
| 21 |
})
|
space/space/space/space/space/space/models/request_model.go
CHANGED
|
@@ -1,7 +1,5 @@
|
|
| 1 |
package models
|
| 2 |
|
| 3 |
-
import uuid "github.com/satori/go.uuid"
|
| 4 |
-
|
| 5 |
type LoginRequest struct {
|
| 6 |
Email string `json:"email" binding:"required"`
|
| 7 |
Password string `json:"password" binding:"required"`
|
|
@@ -20,8 +18,7 @@ type ChangePasswordRequest struct {
|
|
| 20 |
}
|
| 21 |
|
| 22 |
type CreateVerifyEmailRequest struct {
|
| 23 |
-
Token uint
|
| 24 |
-
UUID uuid.UUID `json:"uuid" binding:"required"`
|
| 25 |
}
|
| 26 |
|
| 27 |
type OptionsRequest struct {
|
|
@@ -35,3 +32,11 @@ type ExternalAuthRequest struct {
|
|
| 35 |
IsAgreeTerms bool `json:"is_agree_terms"`
|
| 36 |
IsSexualDisease bool `json:"is_sexual_disease"`
|
| 37 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
package models
|
| 2 |
|
|
|
|
|
|
|
| 3 |
type LoginRequest struct {
|
| 4 |
Email string `json:"email" binding:"required"`
|
| 5 |
Password string `json:"password" binding:"required"`
|
|
|
|
| 18 |
}
|
| 19 |
|
| 20 |
type CreateVerifyEmailRequest struct {
|
| 21 |
+
Token uint `json:"token" binding:"required"`
|
|
|
|
| 22 |
}
|
| 23 |
|
| 24 |
type OptionsRequest struct {
|
|
|
|
| 32 |
IsAgreeTerms bool `json:"is_agree_terms"`
|
| 33 |
IsSexualDisease bool `json:"is_sexual_disease"`
|
| 34 |
}
|
| 35 |
+
|
| 36 |
+
type ForgotPasswordRequest struct {
|
| 37 |
+
Email string `json:"email" binding:"required,email"`
|
| 38 |
+
}
|
| 39 |
+
type ValidateForgotPasswordRequest struct {
|
| 40 |
+
Token uint `json:"token" binding:"required"`
|
| 41 |
+
NewPassword string `json:"new_password" binding:"required"`
|
| 42 |
+
}
|
space/space/space/space/space/space/repositories/account_repository.go
CHANGED
|
@@ -39,10 +39,8 @@ func UpdateAccount(account models.Account) Repository[models.Account, models.Acc
|
|
| 39 |
repo := Construct[models.Account, models.Account](
|
| 40 |
account,
|
| 41 |
)
|
| 42 |
-
repo.
|
| 43 |
-
|
| 44 |
-
Update[models.Account],
|
| 45 |
-
)
|
| 46 |
return *repo
|
| 47 |
}
|
| 48 |
|
|
|
|
| 39 |
repo := Construct[models.Account, models.Account](
|
| 40 |
account,
|
| 41 |
)
|
| 42 |
+
repo.Transaction.Save(&repo.Constructor)
|
| 43 |
+
repo.Result = repo.Constructor
|
|
|
|
|
|
|
| 44 |
return *repo
|
| 45 |
}
|
| 46 |
|
space/space/space/space/space/space/router/auth_route.go
CHANGED
|
@@ -13,5 +13,7 @@ func AuthRoute(router *gin.Engine) {
|
|
| 13 |
routerGroup.POST("/login", AuthController.Login)
|
| 14 |
routerGroup.POST("/register", AuthController.Register)
|
| 15 |
routerGroup.PUT("/change-password", middleware.AuthUser, AuthController.ChangePassword)
|
|
|
|
|
|
|
| 16 |
}
|
| 17 |
}
|
|
|
|
| 13 |
routerGroup.POST("/login", AuthController.Login)
|
| 14 |
routerGroup.POST("/register", AuthController.Register)
|
| 15 |
routerGroup.PUT("/change-password", middleware.AuthUser, AuthController.ChangePassword)
|
| 16 |
+
routerGroup.POST("/forgot-password", AuthController.CreateForgotPassword)
|
| 17 |
+
routerGroup.PUT("/forgot-password", AuthController.ValidateForgotPassword)
|
| 18 |
}
|
| 19 |
}
|
space/space/space/space/space/space/services/authentication_service.go
CHANGED
|
@@ -58,7 +58,8 @@ func (s *AuthenticationService) Update(oldPassword string, newPassword string) {
|
|
| 58 |
s.Exception.Message = "incorrect old password!"
|
| 59 |
return
|
| 60 |
}
|
| 61 |
-
|
|
|
|
| 62 |
changePassword := repositories.UpdateAccount(accountData.Result)
|
| 63 |
changePassword.Result.Password = "SECRET"
|
| 64 |
s.Result = models.AuthenticatedUser{
|
|
|
|
| 58 |
s.Exception.Message = "incorrect old password!"
|
| 59 |
return
|
| 60 |
}
|
| 61 |
+
hashed_password, _ := HashPassword(newPassword)
|
| 62 |
+
accountData.Result.Password = hashed_password
|
| 63 |
changePassword := repositories.UpdateAccount(accountData.Result)
|
| 64 |
changePassword.Result.Password = "SECRET"
|
| 65 |
s.Result = models.AuthenticatedUser{
|
space/space/space/space/space/space/services/email_verification_service.go
CHANGED
|
@@ -61,6 +61,7 @@ func (s *EmailVerificationService) Create() {
|
|
| 61 |
return
|
| 62 |
}
|
| 63 |
}(accountRepo.Result.Email, token)
|
|
|
|
| 64 |
}
|
| 65 |
|
| 66 |
func (s *EmailVerificationService) Validate() {
|
|
@@ -80,8 +81,11 @@ func (s *EmailVerificationService) Validate() {
|
|
| 80 |
s.Delete()
|
| 81 |
return
|
| 82 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
s.Result = repo.Result
|
| 84 |
-
s.Delete()
|
| 85 |
}
|
| 86 |
|
| 87 |
func (s *EmailVerificationService) Delete() {
|
|
|
|
| 61 |
return
|
| 62 |
}
|
| 63 |
}(accountRepo.Result.Email, token)
|
| 64 |
+
// s.Result.Token = 0
|
| 65 |
}
|
| 66 |
|
| 67 |
func (s *EmailVerificationService) Validate() {
|
|
|
|
| 81 |
s.Delete()
|
| 82 |
return
|
| 83 |
}
|
| 84 |
+
account := repositories.GetAccountById(repo.Result.AccountID)
|
| 85 |
+
account.Result.IsEmailVerified = true
|
| 86 |
+
|
| 87 |
+
repositories.UpdateAccount(account.Result)
|
| 88 |
s.Result = repo.Result
|
|
|
|
| 89 |
}
|
| 90 |
|
| 91 |
func (s *EmailVerificationService) Delete() {
|
space/space/space/space/space/space/services/external_authentication_service.go
CHANGED
|
@@ -14,7 +14,7 @@ type GoogleAuthService struct {
|
|
| 14 |
Service[models.ExternalAuth, models.AuthenticatedUser]
|
| 15 |
}
|
| 16 |
|
| 17 |
-
func (s *GoogleAuthService) Authenticate() {
|
| 18 |
GoogleAuth := repositories.GetExternalAccountByOauthId(s.Constructor.OauthID)
|
| 19 |
payload, errGoogleAuth := idtoken.Validate(context.Background(), s.Constructor.OauthID, "")
|
| 20 |
s.Error = errGoogleAuth
|
|
@@ -25,6 +25,11 @@ func (s *GoogleAuthService) Authenticate() {
|
|
| 25 |
}
|
| 26 |
email := payload.Claims["email"]
|
| 27 |
if GoogleAuth.NoRecord {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
s.Constructor.UUID = uuid.NewV4()
|
| 29 |
s.Constructor.OauthProvider = "Google"
|
| 30 |
createAccount := repositories.CreateAccount(models.Account{
|
|
|
|
| 14 |
Service[models.ExternalAuth, models.AuthenticatedUser]
|
| 15 |
}
|
| 16 |
|
| 17 |
+
func (s *GoogleAuthService) Authenticate(isAgree bool) {
|
| 18 |
GoogleAuth := repositories.GetExternalAccountByOauthId(s.Constructor.OauthID)
|
| 19 |
payload, errGoogleAuth := idtoken.Validate(context.Background(), s.Constructor.OauthID, "")
|
| 20 |
s.Error = errGoogleAuth
|
|
|
|
| 25 |
}
|
| 26 |
email := payload.Claims["email"]
|
| 27 |
if GoogleAuth.NoRecord {
|
| 28 |
+
if !isAgree {
|
| 29 |
+
s.Exception.BadRequest = true
|
| 30 |
+
s.Exception.Message = "Please agree to the terms and conditions to create an account"
|
| 31 |
+
return
|
| 32 |
+
}
|
| 33 |
s.Constructor.UUID = uuid.NewV4()
|
| 34 |
s.Constructor.OauthProvider = "Google"
|
| 35 |
createAccount := repositories.CreateAccount(models.Account{
|
space/space/space/space/space/space/services/forgot_password_service.go
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package services
|
| 2 |
+
|
| 3 |
+
import (
|
| 4 |
+
"fmt"
|
| 5 |
+
"log"
|
| 6 |
+
"math/rand/v2"
|
| 7 |
+
"net/smtp"
|
| 8 |
+
"time"
|
| 9 |
+
|
| 10 |
+
"api.qobiltu.id/config"
|
| 11 |
+
"api.qobiltu.id/models"
|
| 12 |
+
"api.qobiltu.id/repositories"
|
| 13 |
+
uuid "github.com/satori/go.uuid"
|
| 14 |
+
)
|
| 15 |
+
|
| 16 |
+
type ForgotPasswordService struct {
|
| 17 |
+
Service[models.ForgotPassword, models.ForgotPassword]
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
func (s *ForgotPasswordService) Create(email string) {
|
| 21 |
+
if email == "" {
|
| 22 |
+
s.Exception.BadRequest = true
|
| 23 |
+
s.Exception.Message = "Email is required!"
|
| 24 |
+
return
|
| 25 |
+
}
|
| 26 |
+
accountRepo := repositories.GetAccountbyEmail(email)
|
| 27 |
+
if accountRepo.NoRecord {
|
| 28 |
+
s.Error = accountRepo.RowsError
|
| 29 |
+
s.Exception.DataNotFound = true
|
| 30 |
+
s.Exception.Message = "There is no account data with given credentials!"
|
| 31 |
+
return
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
remainingTime := time.Duration(config.EMAIL_VERIFICATION_DURATION) * time.Hour
|
| 35 |
+
dueTime := CalculateDueTime(remainingTime)
|
| 36 |
+
|
| 37 |
+
token := uint(rand.IntN(100000))
|
| 38 |
+
s.Constructor.UUID = uuid.NewV4()
|
| 39 |
+
s.Constructor.ExpiredAt = dueTime
|
| 40 |
+
s.Constructor.AccountID = accountRepo.Result.Id
|
| 41 |
+
s.Constructor.Token = token
|
| 42 |
+
repo := repositories.CreateForgotPassword(s.Constructor)
|
| 43 |
+
|
| 44 |
+
s.Error = repo.RowsError
|
| 45 |
+
s.Result = repo.Result
|
| 46 |
+
// ⬇ Kirim token ke email user menggunakan SMTP
|
| 47 |
+
go func(toEmail string, token uint) {
|
| 48 |
+
from := config.SMTP_SENDER_EMAIL
|
| 49 |
+
password := config.SMTP_SENDER_PASSWORD
|
| 50 |
+
smtpHost := config.SMTP_HOST
|
| 51 |
+
smtpPort := config.SMTP_PORT
|
| 52 |
+
|
| 53 |
+
auth := smtp.PlainAuth("", from, password, smtpHost)
|
| 54 |
+
|
| 55 |
+
subject := "Forgot Password Token"
|
| 56 |
+
body := fmt.Sprintf("Your Forgot Password token is: %06d\nPlease use it before it expires.", token)
|
| 57 |
+
|
| 58 |
+
msg := []byte("To: " + toEmail + "\r\n" +
|
| 59 |
+
"Subject: " + subject + "\r\n" +
|
| 60 |
+
"\r\n" +
|
| 61 |
+
body + "\r\n")
|
| 62 |
+
|
| 63 |
+
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{toEmail}, msg)
|
| 64 |
+
if err != nil {
|
| 65 |
+
s.Error = err
|
| 66 |
+
log.Printf("Error sending verification email: %v", err)
|
| 67 |
+
return
|
| 68 |
+
}
|
| 69 |
+
}(accountRepo.Result.Email, token)
|
| 70 |
+
// s.Result.Token = 0
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
func (s *ForgotPasswordService) Validate(newPassword string) {
|
| 74 |
+
accountRepo := repositories.GetAccountById(s.Constructor.AccountID)
|
| 75 |
+
if accountRepo.NoRecord {
|
| 76 |
+
s.Error = accountRepo.RowsError
|
| 77 |
+
s.Exception.DataNotFound = true
|
| 78 |
+
s.Exception.Message = "There is no account data with given credentials!"
|
| 79 |
+
return
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
fgPasswordRepo := repositories.GetForgotPasswordByToken(s.Constructor.Token)
|
| 83 |
+
s.Error = fgPasswordRepo.RowsError
|
| 84 |
+
if fgPasswordRepo.NoRecord {
|
| 85 |
+
s.Exception.DataNotFound = true
|
| 86 |
+
s.Exception.Message = "There is no forgot password data with given credentials!"
|
| 87 |
+
return
|
| 88 |
+
}
|
| 89 |
+
if fgPasswordRepo.Result.ExpiredAt.Before(time.Now()) {
|
| 90 |
+
s.Exception.Unauthorized = true
|
| 91 |
+
s.Exception.Message = "Token has expired!"
|
| 92 |
+
return
|
| 93 |
+
}
|
| 94 |
+
hashed_password, _ := HashPassword(newPassword)
|
| 95 |
+
accountRepo.Result.Password = hashed_password
|
| 96 |
+
changePassword := repositories.UpdateAccount(accountRepo.Result)
|
| 97 |
+
if changePassword.RowsError != nil {
|
| 98 |
+
s.Error = changePassword.RowsError
|
| 99 |
+
s.Exception.QueryError = true
|
| 100 |
+
s.Exception.Message = "Failed to update password!"
|
| 101 |
+
return
|
| 102 |
+
}
|
| 103 |
+
// fgPasswordRepo.Result.Token = 0
|
| 104 |
+
s.Result = fgPasswordRepo.Result
|
| 105 |
+
}
|
space/space/space/space/space/space/services/user_profile_service.go
CHANGED
|
@@ -69,6 +69,7 @@ func (s *UserProfileService) Retrieve() {
|
|
| 69 |
Account: repositories.GetAccountById(s.Constructor.AccountID).Result,
|
| 70 |
Details: userProfile.Result,
|
| 71 |
}
|
|
|
|
| 72 |
}
|
| 73 |
|
| 74 |
func (s *UserProfileService) Update() {
|
|
@@ -78,11 +79,14 @@ func (s *UserProfileService) Update() {
|
|
| 78 |
}
|
| 79 |
usersCount := repositories.GetAllAccount().RowsCount
|
| 80 |
var initialName string
|
| 81 |
-
if
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
|
|
|
|
|
|
| 85 |
}
|
|
|
|
| 86 |
initialName += strconv.Itoa(usersCount)
|
| 87 |
s.Constructor.InitialName = initialName
|
| 88 |
userProfile := repositories.UpdateAccountDetails(s.Constructor)
|
|
@@ -92,8 +96,19 @@ func (s *UserProfileService) Update() {
|
|
| 92 |
s.Exception.Message = "There is no account with given credentials!"
|
| 93 |
return
|
| 94 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 95 |
s.Result = models.UserProfileResponse{
|
| 96 |
-
Account:
|
| 97 |
Details: userProfile.Result,
|
| 98 |
}
|
| 99 |
s.Result.Account.Password = "SECRET"
|
|
|
|
| 69 |
Account: repositories.GetAccountById(s.Constructor.AccountID).Result,
|
| 70 |
Details: userProfile.Result,
|
| 71 |
}
|
| 72 |
+
s.Result.Account.Password = "SECRET"
|
| 73 |
}
|
| 74 |
|
| 75 |
func (s *UserProfileService) Update() {
|
|
|
|
| 79 |
}
|
| 80 |
usersCount := repositories.GetAllAccount().RowsCount
|
| 81 |
var initialName string
|
| 82 |
+
if s.Constructor.Gender != nil {
|
| 83 |
+
if *s.Constructor.Gender {
|
| 84 |
+
initialName = "IKH_"
|
| 85 |
+
} else {
|
| 86 |
+
initialName = "AKH_"
|
| 87 |
+
}
|
| 88 |
}
|
| 89 |
+
|
| 90 |
initialName += strconv.Itoa(usersCount)
|
| 91 |
s.Constructor.InitialName = initialName
|
| 92 |
userProfile := repositories.UpdateAccountDetails(s.Constructor)
|
|
|
|
| 96 |
s.Exception.Message = "There is no account with given credentials!"
|
| 97 |
return
|
| 98 |
}
|
| 99 |
+
account := repositories.GetAccountById(s.Constructor.AccountID)
|
| 100 |
+
account.Result.IsDetailCompleted = (userProfile.Result.InitialName != "" &&
|
| 101 |
+
userProfile.Result.FullName != nil &&
|
| 102 |
+
userProfile.Result.DateOfBirth != nil &&
|
| 103 |
+
userProfile.Result.PlaceOfBirth != nil &&
|
| 104 |
+
userProfile.Result.Domicile != nil &&
|
| 105 |
+
userProfile.Result.LastJob != nil &&
|
| 106 |
+
userProfile.Result.Gender != nil &&
|
| 107 |
+
userProfile.Result.LastEducation != nil &&
|
| 108 |
+
userProfile.Result.MaritalStatus != nil)
|
| 109 |
+
repositories.UpdateAccount(account.Result)
|
| 110 |
s.Result = models.UserProfileResponse{
|
| 111 |
+
Account: account.Result,
|
| 112 |
Details: userProfile.Result,
|
| 113 |
}
|
| 114 |
s.Result.Account.Password = "SECRET"
|
space/space/space/space/space/space/space/space/services/email_verification_service.go
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
package services
|
| 2 |
|
| 3 |
import (
|
| 4 |
-
"crypto/tls"
|
| 5 |
"fmt"
|
|
|
|
| 6 |
"math/rand/v2"
|
| 7 |
"net/smtp"
|
| 8 |
"time"
|
|
@@ -44,71 +44,22 @@ func (s *EmailVerificationService) Create() {
|
|
| 44 |
smtpHost := config.SMTP_HOST
|
| 45 |
smtpPort := config.SMTP_PORT
|
| 46 |
|
| 47 |
-
tlsconfig := &tls.Config{
|
| 48 |
-
InsecureSkipVerify: true,
|
| 49 |
-
ServerName: smtpHost,
|
| 50 |
-
}
|
| 51 |
-
|
| 52 |
-
conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", smtpHost, smtpPort), tlsconfig)
|
| 53 |
-
if err != nil {
|
| 54 |
-
panic(err)
|
| 55 |
-
}
|
| 56 |
-
|
| 57 |
-
client, err := smtp.NewClient(conn, smtpHost)
|
| 58 |
-
if err != nil {
|
| 59 |
-
panic(err)
|
| 60 |
-
}
|
| 61 |
-
|
| 62 |
-
// auth := smtp.PlainAuth("", from, password, smtpHost)
|
| 63 |
auth := smtp.PlainAuth("", from, password, smtpHost)
|
| 64 |
-
if err = client.Auth(auth); err != nil {
|
| 65 |
-
panic(err)
|
| 66 |
-
}
|
| 67 |
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
}
|
| 71 |
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
}
|
| 77 |
-
}
|
| 78 |
|
| 79 |
-
|
| 80 |
if err != nil {
|
| 81 |
-
|
|
|
|
|
|
|
| 82 |
}
|
| 83 |
-
|
| 84 |
-
msg := []byte("Subject: Test Email\r\n\r\nThis is the email body.")
|
| 85 |
-
_, err = wc.Write(msg)
|
| 86 |
-
if err != nil {
|
| 87 |
-
panic(err)
|
| 88 |
-
}
|
| 89 |
-
|
| 90 |
-
err = wc.Close()
|
| 91 |
-
if err != nil {
|
| 92 |
-
panic(err)
|
| 93 |
-
}
|
| 94 |
-
|
| 95 |
-
client.Quit()
|
| 96 |
-
fmt.Println("Email sent successfully!")
|
| 97 |
-
|
| 98 |
-
// subject := "Email Verification Token"
|
| 99 |
-
// body := fmt.Sprintf("Your verification token is: %06d\nPlease use it before it expires.", token)
|
| 100 |
-
|
| 101 |
-
// msg := []byte("To: " + toEmail + "\r\n" +
|
| 102 |
-
// "Subject: " + subject + "\r\n" +
|
| 103 |
-
// "\r\n" +
|
| 104 |
-
// body + "\r\n")
|
| 105 |
-
|
| 106 |
-
// err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{toEmail}, msg)
|
| 107 |
-
// if err != nil {
|
| 108 |
-
// s.Error = err
|
| 109 |
-
// log.Printf("Error sending verification email: %v", err)
|
| 110 |
-
// return
|
| 111 |
-
// }
|
| 112 |
}(accountRepo.Result.Email, token)
|
| 113 |
}
|
| 114 |
|
|
|
|
| 1 |
package services
|
| 2 |
|
| 3 |
import (
|
|
|
|
| 4 |
"fmt"
|
| 5 |
+
"log"
|
| 6 |
"math/rand/v2"
|
| 7 |
"net/smtp"
|
| 8 |
"time"
|
|
|
|
| 44 |
smtpHost := config.SMTP_HOST
|
| 45 |
smtpPort := config.SMTP_PORT
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
auth := smtp.PlainAuth("", from, password, smtpHost)
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
+
subject := "Email Verification Token"
|
| 50 |
+
body := fmt.Sprintf("Your verification token is: %06d\nPlease use it before it expires.", token)
|
|
|
|
| 51 |
|
| 52 |
+
msg := []byte("To: " + toEmail + "\r\n" +
|
| 53 |
+
"Subject: " + subject + "\r\n" +
|
| 54 |
+
"\r\n" +
|
| 55 |
+
body + "\r\n")
|
|
|
|
|
|
|
| 56 |
|
| 57 |
+
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{toEmail}, msg)
|
| 58 |
if err != nil {
|
| 59 |
+
s.Error = err
|
| 60 |
+
log.Printf("Error sending verification email: %v", err)
|
| 61 |
+
return
|
| 62 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
}(accountRepo.Result.Email, token)
|
| 64 |
}
|
| 65 |
|
space/space/space/space/space/space/space/space/space/space/services/email_verification_service.go
CHANGED
|
@@ -1,8 +1,8 @@
|
|
| 1 |
package services
|
| 2 |
|
| 3 |
import (
|
|
|
|
| 4 |
"fmt"
|
| 5 |
-
"log"
|
| 6 |
"math/rand/v2"
|
| 7 |
"net/smtp"
|
| 8 |
"time"
|
|
@@ -44,22 +44,71 @@ func (s *EmailVerificationService) Create() {
|
|
| 44 |
smtpHost := config.SMTP_HOST
|
| 45 |
smtpPort := config.SMTP_PORT
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
auth := smtp.PlainAuth("", from, password, smtpHost)
|
|
|
|
|
|
|
|
|
|
| 48 |
|
| 49 |
-
|
| 50 |
-
|
|
|
|
| 51 |
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
| 56 |
|
| 57 |
-
err :=
|
| 58 |
if err != nil {
|
| 59 |
-
|
| 60 |
-
log.Printf("Error sending verification email: %v", err)
|
| 61 |
-
return
|
| 62 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
}(accountRepo.Result.Email, token)
|
| 64 |
}
|
| 65 |
|
|
|
|
| 1 |
package services
|
| 2 |
|
| 3 |
import (
|
| 4 |
+
"crypto/tls"
|
| 5 |
"fmt"
|
|
|
|
| 6 |
"math/rand/v2"
|
| 7 |
"net/smtp"
|
| 8 |
"time"
|
|
|
|
| 44 |
smtpHost := config.SMTP_HOST
|
| 45 |
smtpPort := config.SMTP_PORT
|
| 46 |
|
| 47 |
+
tlsconfig := &tls.Config{
|
| 48 |
+
InsecureSkipVerify: true,
|
| 49 |
+
ServerName: smtpHost,
|
| 50 |
+
}
|
| 51 |
+
|
| 52 |
+
conn, err := tls.Dial("tcp", fmt.Sprintf("%s:%d", smtpHost, smtpPort), tlsconfig)
|
| 53 |
+
if err != nil {
|
| 54 |
+
panic(err)
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
client, err := smtp.NewClient(conn, smtpHost)
|
| 58 |
+
if err != nil {
|
| 59 |
+
panic(err)
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
// auth := smtp.PlainAuth("", from, password, smtpHost)
|
| 63 |
auth := smtp.PlainAuth("", from, password, smtpHost)
|
| 64 |
+
if err = client.Auth(auth); err != nil {
|
| 65 |
+
panic(err)
|
| 66 |
+
}
|
| 67 |
|
| 68 |
+
if err = client.Mail(from); err != nil {
|
| 69 |
+
panic(err)
|
| 70 |
+
}
|
| 71 |
|
| 72 |
+
to := []string{toEmail}
|
| 73 |
+
for _, addr := range to {
|
| 74 |
+
if err = client.Rcpt(addr); err != nil {
|
| 75 |
+
panic(err)
|
| 76 |
+
}
|
| 77 |
+
}
|
| 78 |
|
| 79 |
+
wc, err := client.Data()
|
| 80 |
if err != nil {
|
| 81 |
+
panic(err)
|
|
|
|
|
|
|
| 82 |
}
|
| 83 |
+
|
| 84 |
+
msg := []byte("Subject: Test Email\r\n\r\nThis is the email body.")
|
| 85 |
+
_, err = wc.Write(msg)
|
| 86 |
+
if err != nil {
|
| 87 |
+
panic(err)
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
err = wc.Close()
|
| 91 |
+
if err != nil {
|
| 92 |
+
panic(err)
|
| 93 |
+
}
|
| 94 |
+
|
| 95 |
+
client.Quit()
|
| 96 |
+
fmt.Println("Email sent successfully!")
|
| 97 |
+
|
| 98 |
+
// subject := "Email Verification Token"
|
| 99 |
+
// body := fmt.Sprintf("Your verification token is: %06d\nPlease use it before it expires.", token)
|
| 100 |
+
|
| 101 |
+
// msg := []byte("To: " + toEmail + "\r\n" +
|
| 102 |
+
// "Subject: " + subject + "\r\n" +
|
| 103 |
+
// "\r\n" +
|
| 104 |
+
// body + "\r\n")
|
| 105 |
+
|
| 106 |
+
// err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{toEmail}, msg)
|
| 107 |
+
// if err != nil {
|
| 108 |
+
// s.Error = err
|
| 109 |
+
// log.Printf("Error sending verification email: %v", err)
|
| 110 |
+
// return
|
| 111 |
+
// }
|
| 112 |
}(accountRepo.Result.Email, token)
|
| 113 |
}
|
| 114 |
|
space/space/space/space/space/space/space/space/space/space/space/space/models/request_model.go
CHANGED
|
@@ -30,6 +30,8 @@ type OptionsRequest struct {
|
|
| 30 |
}
|
| 31 |
|
| 32 |
type ExternalAuthRequest struct {
|
| 33 |
-
OauthID
|
| 34 |
-
OauthProvider
|
|
|
|
|
|
|
| 35 |
}
|
|
|
|
| 30 |
}
|
| 31 |
|
| 32 |
type ExternalAuthRequest struct {
|
| 33 |
+
OauthID string `json:"oauth_id" binding:"required"`
|
| 34 |
+
OauthProvider string `json:"oauth_provider" binding:"required"`
|
| 35 |
+
IsAgreeTerms bool `json:"is_agree_terms"`
|
| 36 |
+
IsSexualDisease bool `json:"is_sexual_disease"`
|
| 37 |
}
|
space/space/space/space/space/space/space/space/space/space/space/space/services/authentication_service.go
CHANGED
|
@@ -18,6 +18,7 @@ func (s *AuthenticationService) Authenticate() {
|
|
| 18 |
s.Exception.Message = "there is no account with given credentials!"
|
| 19 |
return
|
| 20 |
}
|
|
|
|
| 21 |
if VerifyPassword(accountData.Result.Password, s.Constructor.Password) != nil {
|
| 22 |
s.Exception.Unauthorized = true
|
| 23 |
s.Exception.Message = "incorrect password!"
|
|
@@ -28,6 +29,7 @@ func (s *AuthenticationService) Authenticate() {
|
|
| 28 |
|
| 29 |
if err_tok != nil {
|
| 30 |
s.Error = errors.Join(s.Error, err_tok)
|
|
|
|
| 31 |
}
|
| 32 |
|
| 33 |
accountData.Result.Password = "SECRET"
|
|
|
|
| 18 |
s.Exception.Message = "there is no account with given credentials!"
|
| 19 |
return
|
| 20 |
}
|
| 21 |
+
|
| 22 |
if VerifyPassword(accountData.Result.Password, s.Constructor.Password) != nil {
|
| 23 |
s.Exception.Unauthorized = true
|
| 24 |
s.Exception.Message = "incorrect password!"
|
|
|
|
| 29 |
|
| 30 |
if err_tok != nil {
|
| 31 |
s.Error = errors.Join(s.Error, err_tok)
|
| 32 |
+
return
|
| 33 |
}
|
| 34 |
|
| 35 |
accountData.Result.Password = "SECRET"
|
space/space/space/space/space/space/space/space/space/space/space/space/services/email_verification_service.go
CHANGED
|
@@ -56,7 +56,9 @@ func (s *EmailVerificationService) Create() {
|
|
| 56 |
|
| 57 |
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{toEmail}, msg)
|
| 58 |
if err != nil {
|
|
|
|
| 59 |
log.Printf("Error sending verification email: %v", err)
|
|
|
|
| 60 |
}
|
| 61 |
}(accountRepo.Result.Email, token)
|
| 62 |
}
|
|
@@ -75,9 +77,11 @@ func (s *EmailVerificationService) Validate() {
|
|
| 75 |
s.Exception.Unauthorized = true
|
| 76 |
s.Exception.Message = "Token has expired!"
|
| 77 |
repositories.UpdateExpiredEmailVerification(s.Constructor.UUID)
|
|
|
|
| 78 |
return
|
| 79 |
}
|
| 80 |
s.Result = repo.Result
|
|
|
|
| 81 |
}
|
| 82 |
|
| 83 |
func (s *EmailVerificationService) Delete() {
|
|
|
|
| 56 |
|
| 57 |
err := smtp.SendMail(smtpHost+":"+smtpPort, auth, from, []string{toEmail}, msg)
|
| 58 |
if err != nil {
|
| 59 |
+
s.Error = err
|
| 60 |
log.Printf("Error sending verification email: %v", err)
|
| 61 |
+
return
|
| 62 |
}
|
| 63 |
}(accountRepo.Result.Email, token)
|
| 64 |
}
|
|
|
|
| 77 |
s.Exception.Unauthorized = true
|
| 78 |
s.Exception.Message = "Token has expired!"
|
| 79 |
repositories.UpdateExpiredEmailVerification(s.Constructor.UUID)
|
| 80 |
+
s.Delete()
|
| 81 |
return
|
| 82 |
}
|
| 83 |
s.Result = repo.Result
|
| 84 |
+
s.Delete()
|
| 85 |
}
|
| 86 |
|
| 87 |
func (s *EmailVerificationService) Delete() {
|
space/space/space/space/space/space/space/space/space/space/space/space/services/user_profile_service.go
CHANGED
|
@@ -2,6 +2,7 @@ package services
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"regexp"
|
|
|
|
| 5 |
"strings"
|
| 6 |
|
| 7 |
"api.qobiltu.id/models"
|
|
@@ -71,8 +72,10 @@ func (s *UserProfileService) Retrieve() {
|
|
| 71 |
}
|
| 72 |
|
| 73 |
func (s *UserProfileService) Update() {
|
| 74 |
-
|
| 75 |
-
|
|
|
|
|
|
|
| 76 |
usersCount := repositories.GetAllAccount().RowsCount
|
| 77 |
var initialName string
|
| 78 |
if *s.Constructor.Gender {
|
|
@@ -80,7 +83,8 @@ func (s *UserProfileService) Update() {
|
|
| 80 |
} else {
|
| 81 |
initialName = "AKH_"
|
| 82 |
}
|
| 83 |
-
initialName +=
|
|
|
|
| 84 |
userProfile := repositories.UpdateAccountDetails(s.Constructor)
|
| 85 |
s.Error = userProfile.RowsError
|
| 86 |
if userProfile.NoRecord {
|
|
@@ -92,4 +96,5 @@ func (s *UserProfileService) Update() {
|
|
| 92 |
Account: repositories.GetAccountById(s.Constructor.AccountID).Result,
|
| 93 |
Details: userProfile.Result,
|
| 94 |
}
|
|
|
|
| 95 |
}
|
|
|
|
| 2 |
|
| 3 |
import (
|
| 4 |
"regexp"
|
| 5 |
+
"strconv"
|
| 6 |
"strings"
|
| 7 |
|
| 8 |
"api.qobiltu.id/models"
|
|
|
|
| 72 |
}
|
| 73 |
|
| 74 |
func (s *UserProfileService) Update() {
|
| 75 |
+
if s.Constructor.PhoneNumber != nil {
|
| 76 |
+
phoneNumber := *s.Constructor.PhoneNumber
|
| 77 |
+
*s.Constructor.PhoneNumber = SanitizePhoneNumber(phoneNumber)
|
| 78 |
+
}
|
| 79 |
usersCount := repositories.GetAllAccount().RowsCount
|
| 80 |
var initialName string
|
| 81 |
if *s.Constructor.Gender {
|
|
|
|
| 83 |
} else {
|
| 84 |
initialName = "AKH_"
|
| 85 |
}
|
| 86 |
+
initialName += strconv.Itoa(usersCount)
|
| 87 |
+
s.Constructor.InitialName = initialName
|
| 88 |
userProfile := repositories.UpdateAccountDetails(s.Constructor)
|
| 89 |
s.Error = userProfile.RowsError
|
| 90 |
if userProfile.NoRecord {
|
|
|
|
| 96 |
Account: repositories.GetAccountById(s.Constructor.AccountID).Result,
|
| 97 |
Details: userProfile.Result,
|
| 98 |
}
|
| 99 |
+
s.Result.Account.Password = "SECRET"
|
| 100 |
}
|
space/space/space/space/space/space/space/space/space/space/space/space/space/repositories/account_repository.go
CHANGED
|
@@ -15,6 +15,15 @@ func GetAccountbyEmail(email string) Repository[models.Account, models.Account]
|
|
| 15 |
return *repo
|
| 16 |
}
|
| 17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
func GetAccountById(accountId uint) Repository[models.Account, models.Account] {
|
| 19 |
repo := Construct[models.Account, models.Account](
|
| 20 |
models.Account{Id: accountId},
|
|
|
|
| 15 |
return *repo
|
| 16 |
}
|
| 17 |
|
| 18 |
+
func GetAllAccount() Repository[models.Account, []models.Account] {
|
| 19 |
+
repo := Construct[models.Account, []models.Account](
|
| 20 |
+
models.Account{},
|
| 21 |
+
)
|
| 22 |
+
repo.Transactions(
|
| 23 |
+
Find[models.Account, []models.Account],
|
| 24 |
+
)
|
| 25 |
+
return *repo
|
| 26 |
+
}
|
| 27 |
func GetAccountById(accountId uint) Repository[models.Account, models.Account] {
|
| 28 |
repo := Construct[models.Account, models.Account](
|
| 29 |
models.Account{Id: accountId},
|
space/space/space/space/space/space/space/space/space/space/space/space/space/services/external_authentication_service.go
CHANGED
|
@@ -33,7 +33,7 @@ func (s *GoogleAuthService) Authenticate() {
|
|
| 33 |
})
|
| 34 |
s.Constructor.AccountID = createAccount.Result.Id
|
| 35 |
createGoogleAuth := repositories.CreateExternalAuth(s.Constructor)
|
| 36 |
-
|
| 37 |
s.Error = createGoogleAuth.RowsError
|
| 38 |
s.Error = errors.Join(s.Error, createAccount.RowsError)
|
| 39 |
}
|
|
|
|
| 33 |
})
|
| 34 |
s.Constructor.AccountID = createAccount.Result.Id
|
| 35 |
createGoogleAuth := repositories.CreateExternalAuth(s.Constructor)
|
| 36 |
+
GoogleAuth.Result.AccountID = createGoogleAuth.Result.ID
|
| 37 |
s.Error = createGoogleAuth.RowsError
|
| 38 |
s.Error = errors.Join(s.Error, createAccount.RowsError)
|
| 39 |
}
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/services/user_profile_service.go
CHANGED
|
@@ -44,8 +44,6 @@ func SanitizePhoneNumber(input string) string {
|
|
| 44 |
return input
|
| 45 |
}
|
| 46 |
func (s *UserProfileService) Create() {
|
| 47 |
-
phoneNumber := *s.Constructor.PhoneNumber
|
| 48 |
-
*s.Constructor.PhoneNumber = SanitizePhoneNumber(phoneNumber)
|
| 49 |
userProfile := repositories.CreateAccountDetails(s.Constructor)
|
| 50 |
s.Error = userProfile.RowsError
|
| 51 |
if userProfile.NoRecord {
|
|
@@ -75,6 +73,14 @@ func (s *UserProfileService) Retrieve() {
|
|
| 75 |
func (s *UserProfileService) Update() {
|
| 76 |
phoneNumber := *s.Constructor.PhoneNumber
|
| 77 |
*s.Constructor.PhoneNumber = SanitizePhoneNumber(phoneNumber)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
userProfile := repositories.UpdateAccountDetails(s.Constructor)
|
| 79 |
s.Error = userProfile.RowsError
|
| 80 |
if userProfile.NoRecord {
|
|
|
|
| 44 |
return input
|
| 45 |
}
|
| 46 |
func (s *UserProfileService) Create() {
|
|
|
|
|
|
|
| 47 |
userProfile := repositories.CreateAccountDetails(s.Constructor)
|
| 48 |
s.Error = userProfile.RowsError
|
| 49 |
if userProfile.NoRecord {
|
|
|
|
| 73 |
func (s *UserProfileService) Update() {
|
| 74 |
phoneNumber := *s.Constructor.PhoneNumber
|
| 75 |
*s.Constructor.PhoneNumber = SanitizePhoneNumber(phoneNumber)
|
| 76 |
+
usersCount := repositories.GetAllAccount().RowsCount
|
| 77 |
+
var initialName string
|
| 78 |
+
if *s.Constructor.Gender {
|
| 79 |
+
initialName = "IKH_"
|
| 80 |
+
} else {
|
| 81 |
+
initialName = "AKH_"
|
| 82 |
+
}
|
| 83 |
+
initialName += string(usersCount)
|
| 84 |
userProfile := repositories.UpdateAccountDetails(s.Constructor)
|
| 85 |
s.Error = userProfile.RowsError
|
| 86 |
if userProfile.NoRecord {
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/docker-compose.yml
CHANGED
|
@@ -24,7 +24,7 @@ services:
|
|
| 24 |
ports:
|
| 25 |
- "5432:5432"
|
| 26 |
volumes:
|
| 27 |
-
-
|
| 28 |
restart: always
|
| 29 |
|
| 30 |
volumes:
|
|
|
|
| 24 |
ports:
|
| 25 |
- "5432:5432"
|
| 26 |
volumes:
|
| 27 |
+
- /home/qobiltu/postgres-data:/var/lib/postgresql/data
|
| 28 |
restart: always
|
| 29 |
|
| 30 |
volumes:
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/Dockerfile
CHANGED
|
@@ -28,6 +28,9 @@ WORKDIR /app
|
|
| 28 |
# Copy hasil build dari builder ke image runtime
|
| 29 |
COPY --from=builder /app/main .
|
| 30 |
|
|
|
|
|
|
|
|
|
|
| 31 |
# Copy file .env untuk konfigurasi environment
|
| 32 |
COPY .env .env
|
| 33 |
|
|
|
|
| 28 |
# Copy hasil build dari builder ke image runtime
|
| 29 |
COPY --from=builder /app/main .
|
| 30 |
|
| 31 |
+
# Copy folder utils (termasuk file seeder) dari builder ke runtime
|
| 32 |
+
COPY --from=builder /app/utils ./utils
|
| 33 |
+
|
| 34 |
# Copy file .env untuk konfigurasi environment
|
| 35 |
COPY .env .env
|
| 36 |
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/controller/user/user_profile_controller.go
CHANGED
|
@@ -9,7 +9,7 @@ import (
|
|
| 9 |
|
| 10 |
func Profile(c *gin.Context) {
|
| 11 |
userProfile := services.UserProfileService{}
|
| 12 |
-
userProfileController := controller.Controller[any, models.AccountDetails, models.
|
| 13 |
Service: &userProfile.Service,
|
| 14 |
}
|
| 15 |
userProfileController.HeaderParse(c, func() {
|
|
|
|
| 9 |
|
| 10 |
func Profile(c *gin.Context) {
|
| 11 |
userProfile := services.UserProfileService{}
|
| 12 |
+
userProfileController := controller.Controller[any, models.AccountDetails, models.UserProfileResponse]{
|
| 13 |
Service: &userProfile.Service,
|
| 14 |
}
|
| 15 |
userProfileController.HeaderParse(c, func() {
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/controller/user/user_update_profile_controller.go
CHANGED
|
@@ -1,8 +1,6 @@
|
|
| 1 |
package user
|
| 2 |
|
| 3 |
import (
|
| 4 |
-
"fmt"
|
| 5 |
-
|
| 6 |
"api.qobiltu.id/controller"
|
| 7 |
"api.qobiltu.id/models"
|
| 8 |
"api.qobiltu.id/services"
|
|
@@ -11,7 +9,7 @@ import (
|
|
| 11 |
|
| 12 |
func UpdateProfile(c *gin.Context) {
|
| 13 |
userProfile := services.UserProfileService{}
|
| 14 |
-
userUpdateProfileController := controller.Controller[models.AccountDetails, models.AccountDetails, models.
|
| 15 |
Service: &userProfile.Service,
|
| 16 |
}
|
| 17 |
|
|
@@ -19,7 +17,7 @@ func UpdateProfile(c *gin.Context) {
|
|
| 19 |
userUpdateProfileController.Service.Constructor = userUpdateProfileController.Request
|
| 20 |
userUpdateProfileController.HeaderParse(c, func() {
|
| 21 |
userUpdateProfileController.Service.Constructor.AccountID = uint(userUpdateProfileController.AccountData.UserID)
|
| 22 |
-
|
| 23 |
})
|
| 24 |
userProfile.Update()
|
| 25 |
},
|
|
|
|
| 1 |
package user
|
| 2 |
|
| 3 |
import (
|
|
|
|
|
|
|
| 4 |
"api.qobiltu.id/controller"
|
| 5 |
"api.qobiltu.id/models"
|
| 6 |
"api.qobiltu.id/services"
|
|
|
|
| 9 |
|
| 10 |
func UpdateProfile(c *gin.Context) {
|
| 11 |
userProfile := services.UserProfileService{}
|
| 12 |
+
userUpdateProfileController := controller.Controller[models.AccountDetails, models.AccountDetails, models.UserProfileResponse]{
|
| 13 |
Service: &userProfile.Service,
|
| 14 |
}
|
| 15 |
|
|
|
|
| 17 |
userUpdateProfileController.Service.Constructor = userUpdateProfileController.Request
|
| 18 |
userUpdateProfileController.HeaderParse(c, func() {
|
| 19 |
userUpdateProfileController.Service.Constructor.AccountID = uint(userUpdateProfileController.AccountData.UserID)
|
| 20 |
+
|
| 21 |
})
|
| 22 |
userProfile.Update()
|
| 23 |
},
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/logs/error_log.txt
CHANGED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/models/response_model.go
CHANGED
|
@@ -25,3 +25,8 @@ type Options struct {
|
|
| 25 |
type OptionsResponse struct {
|
| 26 |
Options []Options `json:"options"`
|
| 27 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 25 |
type OptionsResponse struct {
|
| 26 |
Options []Options `json:"options"`
|
| 27 |
}
|
| 28 |
+
|
| 29 |
+
type UserProfileResponse struct {
|
| 30 |
+
Account Account `json:"account"`
|
| 31 |
+
Details AccountDetails `json:"details"`
|
| 32 |
+
}
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/repositories/account_repository.go
CHANGED
|
@@ -1,8 +1,6 @@
|
|
| 1 |
package repositories
|
| 2 |
|
| 3 |
import (
|
| 4 |
-
"fmt"
|
| 5 |
-
|
| 6 |
"api.qobiltu.id/models"
|
| 7 |
)
|
| 8 |
|
|
@@ -64,8 +62,6 @@ func CreateAccountDetails(accountDetails models.AccountDetails) Repository[model
|
|
| 64 |
repo := Construct[models.AccountDetails, models.AccountDetails](
|
| 65 |
accountDetails,
|
| 66 |
)
|
| 67 |
-
fmt.Println(accountDetails)
|
| 68 |
-
fmt.Println("Account ID : ", accountDetails.AccountID)
|
| 69 |
Create(repo)
|
| 70 |
return *repo
|
| 71 |
}
|
|
|
|
| 1 |
package repositories
|
| 2 |
|
| 3 |
import (
|
|
|
|
|
|
|
| 4 |
"api.qobiltu.id/models"
|
| 5 |
)
|
| 6 |
|
|
|
|
| 62 |
repo := Construct[models.AccountDetails, models.AccountDetails](
|
| 63 |
accountDetails,
|
| 64 |
)
|
|
|
|
|
|
|
| 65 |
Create(repo)
|
| 66 |
return *repo
|
| 67 |
}
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/repositories/forgot_password_repository.go
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
package repositories
|
| 2 |
+
|
| 3 |
+
import "api.qobiltu.id/models"
|
| 4 |
+
|
| 5 |
+
func CreateForgotPassword(forgotPassword models.ForgotPassword) Repository[models.ForgotPassword, models.ForgotPassword] {
|
| 6 |
+
repo := Construct[models.ForgotPassword, models.ForgotPassword](
|
| 7 |
+
forgotPassword,
|
| 8 |
+
)
|
| 9 |
+
Create(repo)
|
| 10 |
+
return *repo
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
func GetForgotPasswordByToken(token uint) Repository[models.ForgotPassword, models.ForgotPassword] {
|
| 14 |
+
repo := Construct[models.ForgotPassword, models.ForgotPassword](
|
| 15 |
+
models.ForgotPassword{Token: token},
|
| 16 |
+
)
|
| 17 |
+
repo.Transactions(
|
| 18 |
+
WhereGivenConstructor[models.ForgotPassword, models.ForgotPassword],
|
| 19 |
+
Find[models.ForgotPassword, models.ForgotPassword],
|
| 20 |
+
)
|
| 21 |
+
return *repo
|
| 22 |
+
}
|
space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/space/router/router.go
CHANGED
|
@@ -1,6 +1,8 @@
|
|
| 1 |
package router
|
| 2 |
|
| 3 |
import (
|
|
|
|
|
|
|
| 4 |
"api.qobiltu.id/config"
|
| 5 |
"api.qobiltu.id/controller"
|
| 6 |
"github.com/gin-gonic/gin"
|
|
@@ -9,9 +11,14 @@ import (
|
|
| 9 |
func StartService() {
|
| 10 |
router := gin.Default()
|
| 11 |
router.GET("/", controller.HomeController)
|
|
|
|
| 12 |
AuthRoute(router)
|
| 13 |
UserRoute(router)
|
| 14 |
EmailRoute(router)
|
| 15 |
OptionsRoute(router)
|
| 16 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 17 |
}
|
|
|
|
| 1 |
package router
|
| 2 |
|
| 3 |
import (
|
| 4 |
+
"log"
|
| 5 |
+
|
| 6 |
"api.qobiltu.id/config"
|
| 7 |
"api.qobiltu.id/controller"
|
| 8 |
"github.com/gin-gonic/gin"
|
|
|
|
| 11 |
func StartService() {
|
| 12 |
router := gin.Default()
|
| 13 |
router.GET("/", controller.HomeController)
|
| 14 |
+
|
| 15 |
AuthRoute(router)
|
| 16 |
UserRoute(router)
|
| 17 |
EmailRoute(router)
|
| 18 |
OptionsRoute(router)
|
| 19 |
+
|
| 20 |
+
err := router.Run(config.TCP_ADDRESS)
|
| 21 |
+
if err != nil {
|
| 22 |
+
log.Fatalf("Failed to run server: %v", err)
|
| 23 |
+
}
|
| 24 |
}
|