Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ func GithubCallback(aS *services.AuthService, w http.ResponseWriter, r *http.Req
break
}

if err.Error() == "user_not_found" {
if err.Error() == "invalid_credentials" {
continue
}

Expand Down
2 changes: 1 addition & 1 deletion middleware/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func hasPermissionForRoute(path string, permissions []string, isAdmin bool) bool

routePermissions := map[string]string{
"/kal-api/auth/user": "read",
"/kal-api/auth/users": "read",
"/kal-api/auth/users": "all",
"/kal-api/auth/user/edit": "read",
"/kal-api/auth/jwt/revoke": "read",
"/kal-api/auth/jwt/validate": "read",
Expand Down
42 changes: 37 additions & 5 deletions services/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,22 @@ func (service *AuthService) GetUsers() ([]models.User, error) {
return nil, fmt.Errorf("failed_to_get_users")
}

for i := range users {
users[i].Password = ""
}

return users, nil
}

func (service *AuthService) CreateJWT(username, password string) (map[string]interface{}, error) {
var user models.User

if err := service.DB.Where("username = ?", username).First(&user).Error; err != nil {
return nil, fmt.Errorf("user_not_found")
return nil, fmt.Errorf("invalid_credentials")
}

if !utils.CheckPasswordHash(password, user.Password) {
return nil, fmt.Errorf("invalid_password")
return nil, fmt.Errorf("invalid_credentials")
}

tokenString, expiry, err := utils.GenerateJWTAccessToken(user.ID, user.Username, user.Email, user.Photo, user.Admin, user.Permissions)
Expand Down Expand Up @@ -117,7 +121,7 @@ func (service *AuthService) IsTokenAdmin(token string) bool {
}

func (service *AuthService) GetUserPermissions(token string) ([]string, error) {
user, err := service.GetUserFromToken(token)
user, err := service.getUserFromTokenInternal(token)
if err != nil {
return nil, err
}
Expand All @@ -131,7 +135,7 @@ func (service *AuthService) GetUserPermissions(token string) ([]string, error) {
return permissions, nil
}

func (service *AuthService) GetUserFromToken(token string) (models.User, error) {
func (service *AuthService) getUserFromTokenInternal(token string) (models.User, error) {
var tokenRecord models.Token

query := service.DB.Where("token = ?", token).First(&tokenRecord)
Expand All @@ -148,6 +152,17 @@ func (service *AuthService) GetUserFromToken(token string) (models.User, error)
return user, nil
}

func (service *AuthService) GetUserFromToken(token string) (models.User, error) {
user, err := service.getUserFromTokenInternal(token)
if err != nil {
return models.User{}, err
}

user.Password = ""

return user, nil
}

func (service *AuthService) CreateUser(username, email, password string, admin bool, permissions []string) error {
hashedPassword, err := utils.HashPassword(password)

Expand Down Expand Up @@ -202,6 +217,10 @@ func (service *AuthService) EditUser(id uint, username, email, password, photo s
}

user.Password = hashedPassword

if err := service.DB.Where("user_id = ?", id).Delete(&models.Token{}).Error; err != nil {
return fmt.Errorf("failed_to_invalidate_tokens")
}
}

if photo != "" {
Expand Down Expand Up @@ -245,7 +264,7 @@ func (service *AuthService) DeleteUser(username string) error {
return nil
}

func (service *AuthService) GetUser(id uint) (models.User, error) {
func (service *AuthService) getUserInternal(id uint) (models.User, error) {
var user models.User

if err := service.DB.Where("id = ?", id).First(&user).Error; err != nil {
Expand All @@ -255,6 +274,17 @@ func (service *AuthService) GetUser(id uint) (models.User, error) {
return user, nil
}

func (service *AuthService) GetUser(id uint) (models.User, error) {
user, err := service.getUserInternal(id)
if err != nil {
return models.User{}, err
}

user.Password = ""

return user, nil
}

func (service *AuthService) CreateJWTFromEmail(email string) (string, error) {
var user models.User

Expand Down Expand Up @@ -375,6 +405,8 @@ func (service *AuthService) FindUserByEmail(email string) (models.User, error) {
return models.User{}, fmt.Errorf("user_not_found")
}

user.Password = ""

return user, nil
}

Expand Down
8 changes: 4 additions & 4 deletions services/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,15 @@ func TestCreateJWT(t *testing.T) {

t.Run("Non-existent User", func(t *testing.T) {
_, err := TestAuthService.CreateJWT("nonexistent", "password")
if err == nil || err.Error() != "user_not_found" {
t.Errorf("Expected 'user_not_found' error, got %v", err)
if err == nil || err.Error() != "invalid_credentials" {
t.Errorf("Expected 'invalid_credentials' error, got %v", err)
}
})

t.Run("Incorrect Password", func(t *testing.T) {
_, err := TestAuthService.CreateJWT("admin", "wrongpassword")
if err == nil || err.Error() != "invalid_password" {
t.Errorf("Expected 'invalid_password' error, got %v", err)
if err == nil || err.Error() != "invalid_credentials" {
t.Errorf("Expected 'invalid_credentials' error, got %v", err)
}
})
}
Expand Down
3 changes: 1 addition & 2 deletions web/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@
"failed_to_create_user":"Benutzer konnte nicht erstellt werden",
"no_token_provided":"Kein Token bereitgestellt",
"invalid_token":"Ungültiges Token",
"user_not_found":"Benutzer nicht gefunden",
"failed_to_edit_user":"Benutzer konnte nicht bearbeitet werden",
"failed_to_delete_user":"Benutzer konnte nicht gelöscht werden",
"failed_to_get_users":"Benutzer konnten nicht abgerufen werden",
Expand All @@ -229,7 +228,7 @@
"failed_to_reset_file_pointer":"Dateizeiger konnte nicht zurückgesetzt werden",
"failed_to_upload_image":"Bild konnte nicht hochgeladen werden",
"photo_uploaded_successfully":"Foto erfolgreich hochgeladen",
"invalid_password":"Ungültiges Passwort",
"invalid_credentials":"Ungültige Anmeldeinformationen",
"failed_to_generate_jwt":"JWT konnte nicht generiert werden",
"invalid_or_expired_jwt":"Ungültiges oder abgelaufenes JWT",
"failed_to_convert_user_id_to_uint":"Benutzer-ID konnte nicht in UINT konvertiert werden",
Expand Down
3 changes: 1 addition & 2 deletions web/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@
"failed_to_create_user":"Failed to create user",
"no_token_provided":"No token provided",
"invalid_token":"Invalid token",
"user_not_found":"User not found",
"failed_to_edit_user":"Failed to edit user",
"failed_to_delete_user":"Failed to delete user",
"failed_to_get_users":"Failed to get users",
Expand All @@ -229,7 +228,7 @@
"failed_to_reset_file_pointer":"Failed to reset file pointer",
"failed_to_upload_image":"Failed to upload image",
"photo_uploaded_successfully":"Photo uploaded successfully",
"invalid_password":"Invalid password",
"invalid_credentials":"Invalid credentials",
"failed_to_generate_jwt":"Failed to generate JWT",
"invalid_or_expired_jwt":"Invalid or expired JWT",
"failed_to_convert_user_id_to_uint":"Failed to convert userId to uint",
Expand Down
3 changes: 1 addition & 2 deletions web/public/locales/zh/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@
"failed_to_create_user": "建立使用者失敗",
"no_token_provided": "未提供權杖",
"invalid_token": "無效的權杖",
"user_not_found": "找不到使用者",
"failed_to_edit_user": "編輯使用者失敗",
"failed_to_delete_user": "刪除使用者失敗",
"failed_to_get_users": "取得使用者失敗",
Expand All @@ -220,7 +219,7 @@
"failed_to_reset_file_pointer": "重設檔案指標失敗",
"failed_to_upload_image": "上傳圖片失敗",
"photo_uploaded_successfully": "照片上傳成功",
"invalid_password": "無效的密碼",
"invalid_credentials": "无效凭据",
"failed_to_generate_jwt": "產生 JWT 失敗",
"invalid_or_expired_jwt": "無效或過期的 JWT",
"failed_to_convert_user_id_to_uint": "使用者 ID 轉換為無符號整數失敗",
Expand Down
11 changes: 4 additions & 7 deletions web/src/hooks/useUserDetails.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Dispatch, SetStateAction, useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";

import { ApiResponse, getUsers } from "../api/Requests";
import { getUser } from "../api/Requests";
import { handleError } from "../utils/Common";

interface User {
Expand Down Expand Up @@ -32,16 +32,13 @@ export const useUserDetails = (
useEffect(() => {
const fetchUserDetails = async (user: User) => {
try {
const result = await getUsers();
const result = await getUser(parseInt(user.userId));

if (handleError(result, navigate, t)) return;

if (result.status === "success") {
const data = (result as ApiResponse).data;
const filterUser = data?.find(
(obj: UserDetails) => obj?.id.toString() === user?.userId,
);
setUserDetails(filterUser || null);
const userData = result.data as UserDetails;
setUserDetails(userData || null);
}
} catch (error) {
console.error("Error fetching user details:", error);
Expand Down
16 changes: 9 additions & 7 deletions web/src/protected/AdminAuth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import { Navigate, Outlet, useLocation, useNavigate } from "react-router-dom";

import { ApiResponse, getUsers } from "../api/Requests";
import { ApiResponse, getUser } from "../api/Requests";
import Loading from "../components/Loading/Loading";
import { UserPayload } from "../hooks/useUser";
import { User } from "../types/auth";
Expand All @@ -18,7 +18,7 @@ export default function AdminAuth() {

useEffect(() => {
const fetchData = async () => {
let user: UserPayload;
let user: UserPayload | undefined;

if (localStorage.getItem("accessToken")) {
const accessTokenString = localStorage.getItem("accessToken");
Expand All @@ -29,18 +29,20 @@ export default function AdminAuth() {
}
}

const response: ApiResponse = await getUsers();
if (!user) {
setIsLoading(false);
return;
}

const response: ApiResponse = await getUser(parseInt(user.userId));
if (handleError(response, navigate, t)) {
setIsLoading(false);
return;
}

const users = response.data as User[];
const foundUser = response.data as User;

if (response?.status === "success") {
const foundUser = users.find(
(obj: User) => obj.id === parseInt(user.userId),
);

if (foundUser && foundUser?.admin === true) {
setIsAdmin(true);
Expand Down