summaryrefslogtreecommitdiff
path: root/shrine/services/auth.go
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-03-07 08:52:35 +0530
committerBobby <[email protected]>2026-03-07 08:52:35 +0530
commit82409d6b83de1baab69c166af8f04c6e9fe9069f (patch)
tree678b3ee2242b20da49c8cf1ff0ec509d0c8ef1e1 /shrine/services/auth.go
parenta97d1ad37463107b462958d92f596ebb80254b77 (diff)
downloadpagoda-82409d6b83de1baab69c166af8f04c6e9fe9069f.tar.xz
pagoda-82409d6b83de1baab69c166af8f04c6e9fe9069f.zip
feat: Implement letter service with CRUD operations and message handling
- Added letter service to manage letters, including listing, creating, and editing letters and messages. - Implemented functionality for sending and receiving messages within letters. - Introduced pagination for letter listings and message retrieval. - Added attachment upload capabilities for letters. - Created detailed responses for letter and message retrieval. feat: Introduce stats service for user statistics - Added a service to retrieve user statistics, including newest and online citizens. feat: Create ticket service for user support tickets - Implemented ticket management service with functionalities to create, reply, and update tickets. - Added support for ticket categories and their management. feat: Add verification service for user account verification - Implemented functionality to send verification emails for account activation. feat: Develop warning service for user warnings - Added service to issue warnings to users, deactivate warnings, and list user warnings. feat: Create email templates for account status notifications - Added HTML templates for account ban and disable notifications. feat: Define request and response types for account, ticket, letter, and warning services - Created structured request and response types for various services to ensure consistent data handling. feat: Implement utility functions for authentication and sanitization - Added functions for validating user hierarchy and sanitizing HTML input. - Implemented token generation and hashing utilities for secure operations.
Diffstat (limited to 'shrine/services/auth.go')
-rw-r--r--shrine/services/auth.go108
1 files changed, 108 insertions, 0 deletions
diff --git a/shrine/services/auth.go b/shrine/services/auth.go
new file mode 100644
index 0000000..28e63c4
--- /dev/null
+++ b/shrine/services/auth.go
@@ -0,0 +1,108 @@
+package services
+
+import (
+ "shrine/enums"
+ "shrine/messages"
+ "shrine/models"
+ "shrine/repositories"
+ "shrine/types/account"
+ "shrine/types/common"
+ "shrine/types/hypertext"
+ "shrine/utils/crypto"
+)
+
+func Register(request account.RegisterRequest) (*common.MessageResponse, *hypertext.ServiceError) {
+ citizen := models.User{
+ Username: request.Username,
+ Email: request.Email,
+ DisplayName: request.DisplayName,
+ }
+
+ if err := citizen.SetPassword(request.Password); err != nil {
+ return nil, fail(enums.BadRequest, err.Error())
+ }
+
+ if err := repositories.CreateUser(&citizen); err != nil {
+ return nil, mapRegistrationError(err)
+ }
+
+ if serviceErr := SendVerification(&citizen, enums.Activation); serviceErr != nil {
+ return nil, serviceErr
+ }
+
+ return &common.MessageResponse{Message: messages.AccountCreated}, nil
+}
+
+func Authenticate(request account.LoginRequest) (*models.User, *hypertext.ServiceError) {
+ citizen, err := repositories.FindUserByUsername(request.Username)
+ if err != nil {
+ return nil, fail(enums.Unauthorized, messages.InvalidUsernameOrPassword)
+ }
+
+ if citizen.ClearExpiredDisable() {
+ repositories.UpdateUser(citizen)
+ }
+
+ if !citizen.CanAuthenticate() {
+ return nil, fail(enums.Forbidden, messages.AccountBannedOrDisabled)
+ }
+
+ if !citizen.CheckPassword(request.Password) {
+ return nil, fail(enums.Unauthorized, messages.InvalidUsernameOrPassword)
+ }
+
+ if !citizen.IsVerified() {
+ return nil, fail(enums.Forbidden, messages.EmailNotVerified)
+ }
+
+ return citizen, nil
+}
+
+func VerifyAccount(request account.VerifyRequest) (*common.MessageResponse, *hypertext.ServiceError) {
+ if request.Token == "" {
+ return nil, fail(enums.BadRequest, messages.VerificationTokenRequired)
+ }
+
+ verificationType := enums.VerificationType(request.Type)
+ citizen, err := repositories.FindUserByVerification(crypto.HashToken(request.Token), verificationType)
+ if err != nil {
+ return nil, fail(enums.BadRequest, messages.VerificationLinkInvalid)
+ }
+
+ switch verificationType {
+ case enums.Activation:
+ citizen.VerifyEmail()
+ default:
+ return nil, fail(enums.BadRequest, messages.InvalidVerificationType)
+ }
+
+ if err := repositories.UpdateUser(citizen); err != nil {
+ return nil, fail(enums.Internal, messages.FailedVerifyAccount)
+ }
+
+ return &common.MessageResponse{Message: messages.EmailVerified}, nil
+}
+
+func ResendActivation(request account.ResendActivationRequest) (*common.MessageResponse, *hypertext.ServiceError) {
+ citizen, err := repositories.FindUserByEmail(request.Email)
+ if err != nil {
+ return nil, fail(enums.BadRequest, messages.NoAccountWithEmail)
+ }
+
+ if citizen.IsVerified() {
+ return nil, fail(enums.BadRequest, messages.AccountAlreadyVerified)
+ }
+
+ if serviceErr := SendVerification(citizen, enums.Activation); serviceErr != nil {
+ return nil, serviceErr
+ }
+
+ return &common.MessageResponse{Message: messages.VerificationEmailSent}, nil
+}
+
+func RevokeToken(tokenHash string) (*common.MessageResponse, *hypertext.ServiceError) {
+ if err := repositories.DeleteToken(tokenHash); err != nil {
+ return nil, fail(enums.Internal, messages.FailedEndSession)
+ }
+ return &common.MessageResponse{Message: messages.LoggedOut}, nil
+} \ No newline at end of file