forked from cardosofelipe/fast-next-template
Include user information and token expiration in authentication responses
Updated the `Token` schema to include `user` data and `expires_in` field. Adjusted backend `auth_service.py` to populate these fields while generating tokens. Replaced `getCurrentUserInfo` with `getCurrentUserProfile` in the frontend and disabled ESLint for generated files to suppress warnings.
This commit is contained in:
2
backend/app/schemas/users.py
Normal file → Executable file
2
backend/app/schemas/users.py
Normal file → Executable file
@@ -86,6 +86,8 @@ class Token(BaseModel):
|
||||
access_token: str
|
||||
refresh_token: Optional[str] = None
|
||||
token_type: str = "bearer"
|
||||
user: "UserResponse" # Forward reference since UserResponse is defined above
|
||||
expires_in: Optional[int] = None # Token expiration in seconds
|
||||
|
||||
|
||||
class TokenPayload(BaseModel):
|
||||
|
||||
@@ -15,7 +15,7 @@ from app.core.auth import (
|
||||
TokenInvalidError
|
||||
)
|
||||
from app.models.user import User
|
||||
from app.schemas.users import Token, UserCreate
|
||||
from app.schemas.users import Token, UserCreate, UserResponse
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -118,7 +118,7 @@ class AuthService:
|
||||
user: User to create tokens for
|
||||
|
||||
Returns:
|
||||
Token object with access and refresh tokens
|
||||
Token object with access and refresh tokens and user info
|
||||
"""
|
||||
# Generate claims
|
||||
claims = {
|
||||
@@ -137,9 +137,14 @@ class AuthService:
|
||||
subject=str(user.id)
|
||||
)
|
||||
|
||||
# Convert User model to UserResponse schema
|
||||
user_response = UserResponse.model_validate(user)
|
||||
|
||||
return Token(
|
||||
access_token=access_token,
|
||||
refresh_token=refresh_token
|
||||
refresh_token=refresh_token,
|
||||
user=user_response,
|
||||
expires_in=86400 # 24 hours in seconds (matching ACCESS_TOKEN_EXPIRE_MINUTES)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"root": true,
|
||||
"ignorePatterns": ["*"],
|
||||
"rules": {}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import { type ClientOptions, type Config, createClient, createConfig } from './client';
|
||||
import type { ClientOptions as ClientOptions2 } from './types.gen';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
export type { Auth } from '../core/auth.gen';
|
||||
export type { QuerySerializerOptions } from '../core/bodySerializer.gen';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
export type AuthToken = string | undefined;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
type Slot = 'body' | 'headers' | 'path' | 'query';
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
interface SerializeOptions<T>
|
||||
extends SerializePrimitiveOptions,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
* JSON-friendly union that mirrors what Pinia Colada can hash.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import type { Auth, AuthToken } from './auth.gen';
|
||||
import type {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import type { BodySerializer, QuerySerializer } from './bodySerializer.gen';
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
export type * from './types.gen';
|
||||
export * from './sdk.gen';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
import { type Client, type Options as Options2, type TDataShape, urlSearchParamsBodySerializer } from './client';
|
||||
import { client } from './client.gen';
|
||||
import type { AdminActivateUserData, AdminActivateUserErrors, AdminActivateUserResponses, AdminAddOrganizationMemberData, AdminAddOrganizationMemberErrors, AdminAddOrganizationMemberResponses, AdminBulkUserActionData, AdminBulkUserActionErrors, AdminBulkUserActionResponses, AdminCreateOrganizationData, AdminCreateOrganizationErrors, AdminCreateOrganizationResponses, AdminCreateUserData, AdminCreateUserErrors, AdminCreateUserResponses, AdminDeactivateUserData, AdminDeactivateUserErrors, AdminDeactivateUserResponses, AdminDeleteOrganizationData, AdminDeleteOrganizationErrors, AdminDeleteOrganizationResponses, AdminDeleteUserData, AdminDeleteUserErrors, AdminDeleteUserResponses, AdminGetOrganizationData, AdminGetOrganizationErrors, AdminGetOrganizationResponses, AdminGetUserData, AdminGetUserErrors, AdminGetUserResponses, AdminListOrganizationMembersData, AdminListOrganizationMembersErrors, AdminListOrganizationMembersResponses, AdminListOrganizationsData, AdminListOrganizationsErrors, AdminListOrganizationsResponses, AdminListUsersData, AdminListUsersErrors, AdminListUsersResponses, AdminRemoveOrganizationMemberData, AdminRemoveOrganizationMemberErrors, AdminRemoveOrganizationMemberResponses, AdminUpdateOrganizationData, AdminUpdateOrganizationErrors, AdminUpdateOrganizationResponses, AdminUpdateUserData, AdminUpdateUserErrors, AdminUpdateUserResponses, ChangeCurrentUserPasswordData, ChangeCurrentUserPasswordErrors, ChangeCurrentUserPasswordResponses, CleanupExpiredSessionsData, CleanupExpiredSessionsResponses, ConfirmPasswordResetData, ConfirmPasswordResetErrors, ConfirmPasswordResetResponses, DeleteUserData, DeleteUserErrors, DeleteUserResponses, GetCurrentUserInfoData, GetCurrentUserInfoResponses, GetCurrentUserProfileData, GetCurrentUserProfileResponses, GetMyOrganizationsData, GetMyOrganizationsErrors, GetMyOrganizationsResponses, GetOrganizationData, GetOrganizationErrors, GetOrganizationMembersData, GetOrganizationMembersErrors, GetOrganizationMembersResponses, GetOrganizationResponses, GetUserByIdData, GetUserByIdErrors, GetUserByIdResponses, HealthCheckData, HealthCheckResponses, ListMySessionsData, ListMySessionsResponses, ListUsersData, ListUsersErrors, ListUsersResponses, LoginData, LoginErrors, LoginOauthData, LoginOauthErrors, LoginOauthResponses, LoginResponses, LogoutAllData, LogoutAllResponses, LogoutData, LogoutErrors, LogoutResponses, RefreshTokenData, RefreshTokenErrors, RefreshTokenResponses, RegisterData, RegisterErrors, RegisterResponses, RequestPasswordResetData, RequestPasswordResetErrors, RequestPasswordResetResponses, RevokeSessionData, RevokeSessionErrors, RevokeSessionResponses, RootGetData, RootGetResponses, UpdateCurrentUserData, UpdateCurrentUserErrors, UpdateCurrentUserResponses, UpdateOrganizationData, UpdateOrganizationErrors, UpdateOrganizationResponses, UpdateUserData, UpdateUserErrors, UpdateUserResponses } from './types.gen';
|
||||
import type { AdminActivateUserData, AdminActivateUserErrors, AdminActivateUserResponses, AdminAddOrganizationMemberData, AdminAddOrganizationMemberErrors, AdminAddOrganizationMemberResponses, AdminBulkUserActionData, AdminBulkUserActionErrors, AdminBulkUserActionResponses, AdminCreateOrganizationData, AdminCreateOrganizationErrors, AdminCreateOrganizationResponses, AdminCreateUserData, AdminCreateUserErrors, AdminCreateUserResponses, AdminDeactivateUserData, AdminDeactivateUserErrors, AdminDeactivateUserResponses, AdminDeleteOrganizationData, AdminDeleteOrganizationErrors, AdminDeleteOrganizationResponses, AdminDeleteUserData, AdminDeleteUserErrors, AdminDeleteUserResponses, AdminGetOrganizationData, AdminGetOrganizationErrors, AdminGetOrganizationResponses, AdminGetUserData, AdminGetUserErrors, AdminGetUserResponses, AdminListOrganizationMembersData, AdminListOrganizationMembersErrors, AdminListOrganizationMembersResponses, AdminListOrganizationsData, AdminListOrganizationsErrors, AdminListOrganizationsResponses, AdminListUsersData, AdminListUsersErrors, AdminListUsersResponses, AdminRemoveOrganizationMemberData, AdminRemoveOrganizationMemberErrors, AdminRemoveOrganizationMemberResponses, AdminUpdateOrganizationData, AdminUpdateOrganizationErrors, AdminUpdateOrganizationResponses, AdminUpdateUserData, AdminUpdateUserErrors, AdminUpdateUserResponses, ChangeCurrentUserPasswordData, ChangeCurrentUserPasswordErrors, ChangeCurrentUserPasswordResponses, CleanupExpiredSessionsData, CleanupExpiredSessionsResponses, ConfirmPasswordResetData, ConfirmPasswordResetErrors, ConfirmPasswordResetResponses, DeleteUserData, DeleteUserErrors, DeleteUserResponses, GetCurrentUserProfileData, GetCurrentUserProfileResponses, GetMyOrganizationsData, GetMyOrganizationsErrors, GetMyOrganizationsResponses, GetOrganizationData, GetOrganizationErrors, GetOrganizationMembersData, GetOrganizationMembersErrors, GetOrganizationMembersResponses, GetOrganizationResponses, GetUserByIdData, GetUserByIdErrors, GetUserByIdResponses, HealthCheckData, HealthCheckResponses, ListMySessionsData, ListMySessionsResponses, ListUsersData, ListUsersErrors, ListUsersResponses, LoginData, LoginErrors, LoginOauthData, LoginOauthErrors, LoginOauthResponses, LoginResponses, LogoutAllData, LogoutAllResponses, LogoutData, LogoutErrors, LogoutResponses, RefreshTokenData, RefreshTokenErrors, RefreshTokenResponses, RegisterData, RegisterErrors, RegisterResponses, RequestPasswordResetData, RequestPasswordResetErrors, RequestPasswordResetResponses, RevokeSessionData, RevokeSessionErrors, RevokeSessionResponses, RootGetData, RootGetResponses, UpdateCurrentUserData, UpdateCurrentUserErrors, UpdateCurrentUserResponses, UpdateOrganizationData, UpdateOrganizationErrors, UpdateOrganizationResponses, UpdateUserData, UpdateUserErrors, UpdateUserResponses } from './types.gen';
|
||||
|
||||
export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = Options2<TData, ThrowOnError> & {
|
||||
/**
|
||||
@@ -129,27 +130,6 @@ export const refreshToken = <ThrowOnError extends boolean = false>(options: Opti
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Current User Info
|
||||
*
|
||||
* Get current user information.
|
||||
*
|
||||
* Requires authentication.
|
||||
*/
|
||||
export const getCurrentUserInfo = <ThrowOnError extends boolean = false>(options?: Options<GetCurrentUserInfoData, ThrowOnError>) => {
|
||||
return (options?.client ?? client).get<GetCurrentUserInfoResponses, unknown, ThrowOnError>({
|
||||
responseType: 'json',
|
||||
security: [
|
||||
{
|
||||
scheme: 'bearer',
|
||||
type: 'http'
|
||||
}
|
||||
],
|
||||
url: '/api/v1/auth/me',
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Request Password Reset
|
||||
*
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
/* eslint-disable */
|
||||
|
||||
export type ClientOptions = {
|
||||
baseURL: `${string}://${string}` | (string & {});
|
||||
@@ -560,6 +561,11 @@ export type Token = {
|
||||
* Token Type
|
||||
*/
|
||||
token_type?: string;
|
||||
user: UserResponse;
|
||||
/**
|
||||
* Expires In
|
||||
*/
|
||||
expires_in?: number | null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -650,6 +656,10 @@ export type UserUpdate = {
|
||||
* Phone Number
|
||||
*/
|
||||
phone_number?: string | null;
|
||||
/**
|
||||
* Password
|
||||
*/
|
||||
password?: string | null;
|
||||
/**
|
||||
* Preferences
|
||||
*/
|
||||
@@ -660,6 +670,10 @@ export type UserUpdate = {
|
||||
* Is Active
|
||||
*/
|
||||
is_active?: boolean | null;
|
||||
/**
|
||||
* Is Superuser
|
||||
*/
|
||||
is_superuser?: boolean | null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -810,22 +824,6 @@ export type RefreshTokenResponses = {
|
||||
|
||||
export type RefreshTokenResponse = RefreshTokenResponses[keyof RefreshTokenResponses];
|
||||
|
||||
export type GetCurrentUserInfoData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: '/api/v1/auth/me';
|
||||
};
|
||||
|
||||
export type GetCurrentUserInfoResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: UserResponse;
|
||||
};
|
||||
|
||||
export type GetCurrentUserInfoResponse = GetCurrentUserInfoResponses[keyof GetCurrentUserInfoResponses];
|
||||
|
||||
export type RequestPasswordResetData = {
|
||||
body: PasswordResetRequest;
|
||||
path?: never;
|
||||
|
||||
4
frontend/src/lib/api/hooks/useAuth.ts
Normal file → Executable file
4
frontend/src/lib/api/hooks/useAuth.ts
Normal file → Executable file
@@ -15,7 +15,7 @@ import {
|
||||
register,
|
||||
logout,
|
||||
logoutAll,
|
||||
getCurrentUserInfo,
|
||||
getCurrentUserProfile,
|
||||
requestPasswordReset,
|
||||
confirmPasswordReset,
|
||||
changeCurrentUserPassword,
|
||||
@@ -55,7 +55,7 @@ export function useMe() {
|
||||
const query = useQuery({
|
||||
queryKey: authKeys.me,
|
||||
queryFn: async (): Promise<User> => {
|
||||
const response = await getCurrentUserInfo({
|
||||
const response = await getCurrentUserProfile({
|
||||
throwOnError: true,
|
||||
});
|
||||
return response.data as User;
|
||||
|
||||
Reference in New Issue
Block a user