diff --git a/db/database.go b/db/database.go index 67047ae..f74a570 100644 --- a/db/database.go +++ b/db/database.go @@ -31,6 +31,7 @@ const ( type Database interface { IsUserRegistered(email string, username string) bool + IsEmailRegistered(email string) bool CreateUser(user *models.User) error GetUser(email string) (*models.User, error) @@ -149,6 +150,18 @@ func (db *mySQLdb) IsUserRegistered(email string, username string) bool { return true } +func (db *mySQLdb) IsEmailRegistered(email string) bool { + var data models.User + err := db.DB.Table("users").Where("email = ? ", email).First(&data).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return false + } + return true + } + return true +} + func (db *mySQLdb) CreateUser(user *models.User) error { err := db.DB.Create(user).Error if err != nil { @@ -240,6 +253,18 @@ func (db *postgresDB) IsUserRegistered(email string, username string) bool { return true } +func (db *postgresDB) IsEmailRegistered(email string) bool { + var data models.User + err := db.DB.Table("users").Where("email = $1 ", email).First(&data).Error + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return false + } + return true + } + return true +} + func (db *postgresDB) CreateUser(user *models.User) error { err := db.DB.Create(user).Error if err != nil { diff --git a/handler/auth/google/callback/callback.go b/handler/auth/google/callback/callback.go index cc937a9..b89e0fd 100644 --- a/handler/auth/google/callback/callback.go +++ b/handler/auth/google/callback/callback.go @@ -91,6 +91,11 @@ func GET(w http.ResponseWriter, r *http.Request) { delete(CsrfTokens, r.URL.Query().Get("state")) + if err := r.URL.Query().Get("error"); err != "" { + http.Redirect(w, r, fmt.Sprintf("/signin?error=%s", err), http.StatusFound) + return + } + formData := url.Values{ "grant_type": {"authorization_code"}, "code": {r.URL.Query().Get("code")}, @@ -98,6 +103,7 @@ func GET(w http.ResponseWriter, r *http.Request) { "client_secret": {utils.Getenv("GOOGLE_CLIENT_SECRET")}, "redirect_uri": {utils.Getenv("GOOGLE_CALLBACK")}, } + resp, err := http.Post("https://oauth2.googleapis.com/token", "application/x-www-form-urlencoded", bytes.NewBufferString(formData.Encode())) if err != nil { log.Error("Error:", err) @@ -135,11 +141,15 @@ func GET(w http.ResponseWriter, r *http.Request) { response, err := http.Post("https://oauth2.googleapis.com/revoke", "application/json", bytes.NewBuffer(requestBody)) if err != nil { log.Error("Error revoking access token: ", err) + http.Error(w, "Failed to revoke access token", http.StatusInternalServerError) + return } defer response.Body.Close() if response.StatusCode != http.StatusOK { log.Error("Error revoking access token: ", response.StatusCode) + http.Error(w, "Failed to revoke access token", http.StatusInternalServerError) + return } var oauthUser OauthUser @@ -149,7 +159,13 @@ func GET(w http.ResponseWriter, r *http.Request) { return } - if !db.DB.IsUserRegistered(oauthUser.Email, "ll") { + if oauthUser.Email == "" { + log.Error("Error reading user info response body: email not found") + http.Error(w, "Invalid email is given", http.StatusInternalServerError) + return + } + + if !db.DB.IsEmailRegistered(oauthUser.Email) { code := utils.GenerateRandomString(64) googleOauthSetupHandler.SetupUser[code] = &googleOauthSetupHandler.UnregisteredUser{ Code: code, @@ -167,6 +183,7 @@ func GET(w http.ResponseWriter, r *http.Request) { log.Error(err.Error()) return } + storeSession := session.Create() storeSession.Values["user"] = types.User{ UserID: user.UserID, diff --git a/handler/signin/signin.go b/handler/signin/signin.go index fbdc88b..d81c9d2 100644 --- a/handler/signin/signin.go +++ b/handler/signin/signin.go @@ -2,6 +2,7 @@ package signinHandler import ( "errors" + "github.com/a-h/templ" "github.com/fossyy/filekeeper/cache" "net/http" "strings" @@ -14,16 +15,49 @@ import ( ) var log *logger.AggregatedLogger +var errorMessages = make(map[string]string) func init() { + errorMessages = map[string]string{ + "redirect_uri_mismatch": "The redirect URI provided does not match the one registered with our service. Please contact the administrator for assistance.", + "invalid_request": "The request is missing required parameters or has invalid values. Please try again or contact support for assistance.", + "access_denied": "Access was denied. You may have declined the request for permission. Please try again if you wish to grant access.", + "unauthorized_client": "You are not authorized to make this request. Please contact support for further assistance.", + "unsupported_response_type": "The requested response type is not supported. Please try again with a supported response type.", + "invalid_scope": "The requested scope is invalid or unknown. Please try again or contact support for assistance.", + "server_error": "Our server encountered an unexpected error. Please try again later or contact support for assistance.", + "temporarily_unavailable": "Our server is currently undergoing maintenance. Please try again later.", + "invalid_grant": "The authorization code or refresh token provided is invalid. Please try again or contact support for assistance.", + "invalid_client": "The client identifier provided is invalid. Please check your credentials and try again.", + "invalid_token": "The access token provided is invalid. Please try again or contact support for assistance.", + "insufficient_scope": "You do not have sufficient privileges to perform this action. Please contact support for assistance.", + "interaction_required": "Interaction with the authorization server is required. Please try again.", + "login_required": "You need to log in again to proceed. Please try logging in again.", + "account_selection_required": "Please select an account to proceed with the request.", + "consent_required": "Consent is required to proceed. Please provide consent to continue.", + } log = logger.Logger() } func GET(w http.ResponseWriter, r *http.Request) { - component := signinView.Main("Sign in Page", types.Message{ - Code: 3, - Message: "", - }) + var component templ.Component + if err := r.URL.Query().Get("error"); err != "" { + message, ok := errorMessages[err] + if !ok { + message = "Unknown error occurred. Please contact support at bagas@fossy.my.id for assistance." + } + + component = signinView.Main("Sign in Page", types.Message{ + Code: 0, + Message: message, + }) + } else { + component = signinView.Main("Sign in Page", types.Message{ + Code: 3, + Message: "", + }) + } + err := component.Render(r.Context(), w) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/view/auth/auth.templ b/view/auth/auth.templ index e1626c7..804944b 100644 --- a/view/auth/auth.templ +++ b/view/auth/auth.templ @@ -16,11 +16,11 @@ templ form(err types.Message, title string) { switch err.Code { case 0: