Skip to main content
GET
/
auth
/
me
Get User Profile
curl --request GET \
  --url https://auth.nullpass.xyz/api/auth/me \
  --header 'Authorization: Bearer <token>'
{
  "id": "<string>",
  "email": "jsmith@example.com",
  "username": "<string>",
  "displayName": "<string>",
  "avatar": "<string>",
  "twoFactorEnabled": true,
  "createdAt": "2023-11-07T05:31:56Z",
  "serviceAccess": [
    {
      "id": "<string>",
      "userId": "<string>",
      "service": "DROP",
      "tier": "premium",
      "isPremium": true,
      "accessFlags": {},
      "metadata": {},
      "customStorageLimit": 123,
      "customApiKeyLimit": 123,
      "createdAt": "2023-11-07T05:31:56Z",
      "updatedAt": "2023-11-07T05:31:56Z"
    }
  ]
}

Endpoints

GET /api/auth/me
PATCH /api/auth/me

GET /api/auth/me

Retrieves the authenticated user’s profile including service access information.

Request

Requires authentication via Bearer token.

Response

user
object
User profile object

PATCH /api/auth/me

Updates user profile information. Only provided fields are updated.

Request

displayName
string
New display name (1-100 characters). Optional.
avatar
string
Avatar URL or empty string to remove avatar. Must be valid URL if provided. Optional.
At least one field must be provided. Empty string for avatar removes the avatar.

Response

user
object
Updated user object (same structure as GET response)

Implementation Details

Code Reference

export async function GET(request: NextRequest) {
  const corsResponse = handleCors(request)
  if (corsResponse) return corsResponse

  const blocked = await protectRoute(request)
  if (blocked) return blocked

  const auth = await requireAuth(request)
  if ('error' in auth) return auth.error

  try {
    const user = await prisma.user.findUnique({
      where: { id: auth.userId },
      select: {
        id: true,
        email: true,
        avatar: true,
        displayName: true,
        twoFactorEnabled: true,
        createdAt: true,
        updatedAt: true,
        serviceAccess: true,
      },
    })

    if (!user) {
      return errorResponse('User not found', 404, request.headers.get('origin'))
    }

    return jsonResponse({ user }, 200, request.headers.get('origin'))
  } catch (error) {
    logger.error('Get user error:', error)
    return errorResponse('Internal server error', 500, request.headers.get('origin'))
  }
}

export async function PATCH(request: NextRequest) {
  const corsResponse = handleCors(request)
  if (corsResponse) return corsResponse

  const blocked = await protectRoute(request)
  if (blocked) return blocked

  const auth = await requireAuth(request)
  if ('error' in auth) return auth.error

  try {
    const body = await request.json()
    const validated = updateProfileSchema.parse(body)

    const updateData: {
      displayName?: string
      avatar?: string | null
    } = {}

    if (validated.displayName !== undefined) {
      updateData.displayName = validated.displayName
    }

    if (validated.avatar !== undefined) {
      updateData.avatar = validated.avatar === '' ? null : validated.avatar
    }

    if (Object.keys(updateData).length === 0) {
      return errorResponse('No fields to update', 400, request.headers.get('origin'))
    }

    const user = await prisma.user.update({
      where: { id: auth.userId },
      data: updateData,
      select: {
        id: true,
        email: true,
        avatar: true,
        displayName: true,
        twoFactorEnabled: true,
        createdAt: true,
        updatedAt: true,
      },
    })

    await createAuditLog(auth.userId, 'USER_UPDATE', {
      fields: Object.keys(updateData),
    })

    return jsonResponse({ user }, 200, request.headers.get('origin'))
  } catch (error: any) {
    if (error.name === 'ZodError') {
      logger.warn('Profile update validation error:', error.errors)
      return errorResponse(error.errors[0].message, 400, request.headers.get('origin'))
    }
    logger.error('Update profile error:', error)
    return errorResponse('Internal server error', 500, request.headers.get('origin'))
  }
}

Status Codes

200
OK
Success
400
Bad Request
Validation error or no fields to update (PATCH only)
401
Unauthorized
Missing or invalid authentication token
404
Not Found
User not found (GET only)

Example Requests

GET Profile

curl -X GET https://auth.nullpass.xyz/api/auth/me \
  -H "Authorization: Bearer YOUR_TOKEN"

PATCH Profile

curl -X PATCH https://auth.nullpass.xyz/api/auth/me \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Jane Doe",
    "avatar": "https://example.com/avatar.jpg"
  }'

Remove Avatar

curl -X PATCH https://auth.nullpass.xyz/api/auth/me \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "avatar": ""
  }'

Audit Events

  • USER_UPDATE: Profile updated (includes list of updated fields)

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Response

User profile

id
string
email
string<email>
username
string | null
displayName
string | null
avatar
string | null
twoFactorEnabled
boolean
createdAt
string<date-time>
serviceAccess
object[]