Profile Management Service

⚠️ CRITICAL REQUIREMENTS

🔐 Authentication Required

ALL endpoints in this service require Bearer token authentication. No exceptions. Requests without valid authentication will receive a 401 Unauthorized response.

🚨 Username Change Token Invalidation

CRITICAL: When updating a username via /update-basic-info, the user's current access token becomes invalid immediately after the change. The frontend MUST:

  1. Redirect to login page after successful username change

  2. Clear all stored tokens (access token, refresh token)

  3. Force re-authentication with the new username

  4. Display appropriate message informing user of required re-login

🖼️ Profile Picture URL Restriction

IMPORTANT: The profilePictureUrls field ONLY accepts URLs generated from our File Upload Service endpoint (/api/v1/files/upload). External URLs or direct links are NOT permitted for security reasons.

Valid URL Format: http://localhost:9005/{bucket-name}/{object-key} Source: Must be uploaded through /api/v1/files/upload with directory=PROFILE


Service Overview

The Profile Management Service provides comprehensive user profile management capabilities including profile updates, security settings, verification, and account management.

Base URL

/api/v1/profile

Endpoints Overview

Method
Endpoint
Description

GET

/me

Get current user profile

PUT

/update-basic-info

Update basic profile information

PUT

/change-password

Change user password

GET

/validate-username/{username}

Validate username availability

POST

/request-email-verification

Request email verification

POST

/verify-email

Verify email with OTP

GET

/security-info

Get security information

POST

/enable-2fa

Enable two-factor authentication

POST

/disable-2fa

Disable two-factor authentication

DELETE

/deactivate

Deactivate user account


Get Current User Profile

Retrieves the complete profile information for the authenticated user.

Request

GET /api/v1/profile/me
Authorization: Bearer {access_token}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Profile retrieved successfully",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "userName": "john-doe123",
    "firstName": "John",
    "lastName": "Doe",
    "middleName": "Smith",
    "email": "john.doe@example.com",
    "phoneNumber": "+1234567890",
    "isVerified": true,
    "isEmailVerified": true,
    "isPhoneVerified": false,
    "isTwoFactorEnabled": false,
    "isAccountLocked": false,
    "createdAt": "2024-01-15T09:30:00",
    "editedAt": "2024-12-09T10:15:00",
    "roles": ["ROLE_NORMAL_USER"],
    "profilePictureUrls": [
      "http://localhost:9005/org-123e4567-e89b-12d3-a456-426614174000/profile/image1.jpg",
      "http://localhost:9005/org-123e4567-e89b-12d3-a456-426614174000/profile/image2.jpg"
    ],
    "securityStrength": {
      "score": 85,
      "level": "STRONG",
      "description": "Your account security is excellent",
      "recommendations": []
    }
  }
}

Error Responses

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Invalid token",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "User not found",
  "action_time": "2024-12-09T10:30:00"
}

Update Basic Profile Information

Updates basic user profile information including name, email, username, and profile pictures.

Request

PUT /api/v1/profile/update-basic-info
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "userName": "john-doe123",
  "firstName": "John",
  "lastName": "Doe", 
  "middleName": "Smith",
  "email": "john.doe@example.com",
  "phoneNumber": "+1234567890",
  "profilePictureUrls": [
    "http://localhost:9005/org-123e4567-e89b-12d3-a456-426614174000/profile/image1.jpg",
    "http://localhost:9005/org-123e4567-e89b-12d3-a456-426614174000/profile/image2.jpg"
  ]
}

Field Validation

  • userName: 3-30 characters, must start with letter, alphanumeric + underscore/hyphen only

  • firstName: 1-30 characters, required

  • lastName: 1-30 characters, required

  • middleName: Max 30 characters, optional

  • email: Valid email format

  • phoneNumber: International format (+1234567890)

  • profilePictureUrls:

    • Max 5 URLs

    • Each URL max 500 characters

    • MUST be URLs from File Upload Service only (/api/v1/files/upload-single with directory=PROFILE)

    • External URLs are rejected for security reasons

Response (Normal Update)

{
  "success": true,
  "httpStatus": "OK", 
  "message": "Profile updated successfully",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "userName": "john-doe123",
    "firstName": "John",
    "lastName": "Doe",
    "middleName": "Smith",
    "email": "john.doe@example.com",
    "phoneNumber": "+1234567890",
    "isVerified": true,
    "isEmailVerified": false,
    "isPhoneVerified": false,
    "isTwoFactorEnabled": false,
    "isAccountLocked": false,
    "createdAt": "2024-01-15T09:30:00",
    "editedAt": "2024-12-09T10:30:00",
    "roles": ["ROLE_NORMAL_USER"],
    "profilePictureUrls": [
      "http://localhost:9005/org-123e4567-e89b-12d3-a456-426614174000/profile/image1.jpg",
      "http://localhost:9005/org-123e4567-e89b-12d3-a456-426614174000/profile/image2.jpg"
    ],
    "securityStrength": {
      "score": 75,
      "level": "STRONG",
      "description": "Your account security is excellent",
      "recommendations": ["Verify your email address"]
    }
  }
}

⚠️ CRITICAL: Username Change Response

When the username is updated, the response includes a special message and the frontend MUST handle token invalidation:

{
  "success": true,
  "httpStatus": "OK",
  "message": "Username changed successfully! You will be logged out automatically. Please login again with your new username.",
  "action_time": "2024-12-09T10:30:00",
  "data": { /* updated profile data */ }
}

IMMEDIATE ACTION REQUIRED:

  1. Clear all stored tokens (access token, refresh token)

  2. Redirect user to login page

  3. Display the message to inform user of required re-authentication

  4. User must login again with their NEW username

Error Responses

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Username is already taken",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Invalid profile picture URL. Only URLs from File Upload Service are allowed.",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "userName": "Username must be between 3 and 30 characters",
    "email": "Email should be valid",
    "profilePictureUrls": "Only URLs from File Upload Service are allowed"
  }
}

Change Password

Changes the user's password with current password verification.

Request

PUT /api/v1/profile/change-password
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "currentPassword": "oldPassword123!",
  "newPassword": "newPassword456@",
  "confirmPassword": "newPassword456@"
}

Password Requirements

  • Minimum 8 characters

  • At least one uppercase letter

  • At least one lowercase letter

  • At least one digit

  • At least one special character (@$!%*?&#)

  • Must be different from current password

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Password changed successfully",
  "action_time": "2024-12-09T10:30:00"
}

Error Responses

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Current password is incorrect",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "BAD_REQUEST", 
  "message": "New password must be different from current password",
  "action_time": "2024-12-09T10:30:00"
}

Validate Username

Checks username availability and format validity with suggestions.

Request

GET /api/v1/profile/validate-username/{username}
Authorization: Bearer {access_token}

Response (Available)

{
  "success": true,
  "httpStatus": "OK",
  "message": "Username validation completed",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "available": true,
    "valid": true,
    "message": "Username is available",
    "suggestions": [],
    "details": {
      "correctLength": true,
      "validFormat": true,
      "notReserved": true,
      "notTaken": true,
      "formatRequirement": "Username must start with a letter and be 3-30 characters long"
    }
  }
}

Response (Not Available)

{
  "success": true,
  "httpStatus": "OK",
  "message": "Username validation completed", 
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "available": false,
    "valid": true,
    "message": "This username is already taken",
    "suggestions": [
      "johndoe1",
      "johndoe2", 
      "johndoeuser",
      "johndoepro",
      "johndoe5634"
    ],
    "details": {
      "correctLength": true,
      "validFormat": true,
      "notReserved": true,
      "notTaken": false,
      "formatRequirement": "Username must start with a letter and be 3-30 characters long"
    }
  }
}

Request Email Verification

Sends an OTP to the user's email for verification.

Request

POST /api/v1/profile/request-email-verification
Authorization: Bearer {access_token}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Email verification OTP sent successfully",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "tempToken": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWRlbnRpZmllciI6Im...",
    "message": "Verification email sent successfully",
    "expireAt": "2024-12-09T10:40:00",
    "email": "jo***@example.com"
  }
}

Error Responses

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Email is already verified",
  "action_time": "2024-12-09T10:30:00"
}

Verify Email

Verifies email address using the OTP code sent via email.

Request

POST /api/v1/profile/verify-email
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "tempToken": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VySWRlbnRpZmllciI6Im...",
  "otpCode": "123456"
}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Email verified successfully",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "userName": "john-doe123",
    "firstName": "John",
    "lastName": "Doe",
    "middleName": "Smith",
    "email": "john.doe@example.com",
    "phoneNumber": "+1234567890",
    "isVerified": true,
    "isEmailVerified": true,
    "isPhoneVerified": false,
    "isTwoFactorEnabled": false,
    "isAccountLocked": false,
    "createdAt": "2024-01-15T09:30:00",
    "editedAt": "2024-12-09T10:30:00",
    "roles": ["ROLE_NORMAL_USER"],
    "profilePictureUrls": [],
    "securityStrength": {
      "score": 85,
      "level": "STRONG", 
      "description": "Your account security is excellent",
      "recommendations": ["Verify your phone number"]
    }
  }
}

Error Responses

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Invalid OTP code",
  "action_time": "2024-12-09T10:30:00"
}

Get Security Information

Retrieves comprehensive security information and account strength analysis.

Request

GET /api/v1/profile/security-info
Authorization: Bearer {access_token}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Security information retrieved successfully",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "isEmailVerified": true,
    "isPhoneVerified": false,
    "isTwoFactorEnabled": false,
    "isAccountLocked": false,
    "lastPasswordChange": "2024-12-09T10:15:00",
    "accountCreatedAt": "2024-01-15T09:30:00",
    "roles": ["ROLE_NORMAL_USER"],
    "securityStrength": {
      "score": 75,
      "level": "STRONG",
      "description": "Your account security is good but can be improved",
      "recommendations": [
        "Verify your phone number",
        "Enable two-factor authentication"
      ]
    }
  }
}

Security Strength Scoring

  • Email Verification: 25 points

  • Phone Verification: 25 points

  • Two-Factor Authentication: 35 points

  • Recent Password Change (last 6 months): 15 points

Security Levels

  • 80-100: STRONG - "Your account security is excellent"

  • 60-79: MEDIUM - "Your account security is good but can be improved"

  • 40-59: WEAK - "Your account security needs improvement"

  • 0-39: VERY_WEAK - "Your account security is poor and needs immediate attention"


Enable Two-Factor Authentication

Enables two-factor authentication for the user account.

Request

POST /api/v1/profile/enable-2fa
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "password": "userPassword123!"
}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Two-factor authentication enabled successfully",
  "action_time": "2024-12-09T10:30:00"
}

Error Responses

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Password is incorrect",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Two-factor authentication is already enabled",
  "action_time": "2024-12-09T10:30:00"
}

Disable Two-Factor Authentication

Disables two-factor authentication for the user account.

Request

POST /api/v1/profile/disable-2fa
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "password": "userPassword123!"
}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Two-factor authentication disabled successfully",
  "action_time": "2024-12-09T10:30:00"
}

Error Responses

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Password is incorrect",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Two-factor authentication is not enabled",
  "action_time": "2024-12-09T10:30:00"
}

Deactivate Account

Deactivates (soft deletes) the user account by locking it.

Request

DELETE /api/v1/profile/deactivate
Authorization: Bearer {access_token}
Content-Type: application/json

Request Body

{
  "password": "userPassword123!",
  "reason": "No longer need the account"
}

Response

{
  "success": true,
  "httpStatus": "OK",
  "message": "Account deactivated successfully",
  "action_time": "2024-12-09T10:30:00"
}

Error Responses

{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Password is incorrect",
  "action_time": "2024-12-09T10:30:00"
}

Common Error Responses

Authentication Errors

ALL endpoints require valid Bearer token authentication:

{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Invalid token",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "UNAUTHORIZED", 
  "message": "Token expired",
  "action_time": "2024-12-09T10:30:00"
}
{
  "success": false,
  "httpStatus": "UNAUTHORIZED",
  "message": "Authorization header missing",
  "action_time": "2024-12-09T10:30:00"
}

Validation Errors

{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2024-12-09T10:30:00",
  "data": {
    "fieldName": "Error message for specific field"
  }
}

Rate Limiting Errors

{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Too many requests. Please wait before requesting again.",
  "action_time": "2024-12-09T10:30:00"
}

Security Features

Password Strength Analysis

The system analyzes password strength based on:

  • Length (minimum 8 characters)

  • Character diversity (uppercase, lowercase, numbers, special characters)

  • Common password patterns

Rate Limiting

  • OTP requests: Limited to prevent abuse

  • Failed attempts: Tracked and limited

  • Cooldown periods: Applied between requests

Email Notifications

  • Password changes trigger security notifications

  • Account deactivation confirmations

  • Verification code deliveries

Data Validation

  • Input sanitization for XSS prevention

  • URL validation for profile pictures

  • Phone number format validation

  • Email format validation

Profile Picture Security

  • Maximum 5 URLs per user

  • URL length limits (500 characters)

  • ONLY accepts URLs from File Upload Service (/api/v1/files/upload-single)

  • Format validation (image extensions only)

  • External URL blocking for security (SSRF protection)

  • Valid URL pattern: http://localhost:9005/{bucket-name}/{object-key}


Best Practices for Frontend Integration

⚠️ Critical Authentication Handling

  1. Token Validation: Always check token validity before making requests

  2. Token Storage: Store access tokens securely

  3. Username Change Flow:

    • Detect username change response message

    • Immediately clear all stored authentication data

    • Redirect to login page with appropriate message

    • Force user to re-authenticate with new username

  4. Token Refresh: Implement proper token refresh mechanisms

  5. Error Handling: Handle 401 errors by redirecting to login

Security Considerations

  1. Password Handling: Never log or persist passwords

  2. Form Validation: Implement client-side validation matching server rules

  3. Error Messages: Display user-friendly error messages without exposing sensitive information

  4. Loading States: Show appropriate loading indicators for async operations

  5. Session Management: Clear all user data on authentication failures

Username Change Implementation Requirements

When handling username update responses, the frontend must:

  1. Check Response Message: Look for the specific message "Username changed successfully! You will be logged out automatically..."

  2. Clear Authentication Data: Remove all stored tokens and user session data

  3. User Notification: Display the response message to inform user of required re-authentication

  4. Force Re-login: Redirect user to login page immediately

  5. Block Further API Calls: Prevent any additional authenticated requests until re-login

User Experience

  1. Progressive Disclosure: Show security strength indicators

  2. Real-time Validation: Validate usernames and emails as user types

  3. Clear Feedback: Provide immediate feedback for actions

  4. Confirmation Dialogs: Confirm destructive actions like account deactivation

  5. Auto-logout: Handle username changes by logging user out

Performance

  1. Debounced Validation: Debounce username validation requests

  2. Caching: Cache profile data appropriately

  3. Optimistic Updates: Update UI optimistically where safe

  4. Error Recovery: Implement retry mechanisms for failed requests

Profile Picture Handling

  1. File Upload First: Always upload images via File Upload Service before updating profile

  2. URL Validation: Only use URLs returned from /api/v1/files/upload-single

  3. Error Handling: Handle profile picture URL validation errors appropriately

  4. Preview: Show image previews before updating profile

Last updated