Skip to main content
POST
/
connect
/
disconnect
Disconnect Service
curl --request POST \
  --url https://auth.nullpass.xyz/api/connect/disconnect \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "service": "DROP"
}
'

Endpoint

POST /api/connect/disconnect

Overview

Disconnects the authenticated user from a service by setting the connected flag to false. The service entitlement remains but is marked as disconnected.

Request

service
ServiceIdentifier
required
Service identifier: DROP, MAILS, VAULT, or DB

Response

connected
boolean
Always false on success
service
string
Service identifier
tier
string
Access tier
isPremium
boolean
Premium access flag
message
string
“Successfully disconnected from service”

Implementation Details

Code Reference

export async function POST(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 = disconnectSchema.parse(body)

    logger.ups('Service disconnect request:', auth.userId, validated.service)

    const existingEntitlement = await prisma.userServiceEntitlement.findUnique({
      where: {
        userId_service: {
          userId: auth.userId,
          service: validated.service,
        },
      },
    })

    if (!existingEntitlement) {
      return errorResponse(
        'Service entitlement not found. Please ensure you have access to this service.',
        404,
        request.headers.get('origin')
      )
    }

    if (!(existingEntitlement as any).connected) {
      return jsonResponse(
        {
          connected: false,
          service: validated.service,
          message: 'Already disconnected from this service',
        },
        200,
        request.headers.get('origin')
      )
    }

    const entitlement = await prisma.userServiceEntitlement.update({
      where: {
        userId_service: {
          userId: auth.userId,
          service: validated.service,
        },
      },
      data: {
        connected: false,
        updatedAt: new Date(),
      } as any,
    })

    await createAuditLog(auth.userId, 'SERVICE_ENTITLEMENT_DISCONNECT', {
      service: validated.service,
    })

    logger.info('Service disconnected:', auth.userId, validated.service)

    return jsonResponse(
      {
        connected: false,
        service: entitlement.service,
        tier: entitlement.tier,
        isPremium: entitlement.isPremium,
        message: 'Successfully disconnected from service',
      },
      200,
      request.headers.get('origin')
    )
  } catch (error: any) {
    if (error.name === 'ZodError') {
      logger.warn('Disconnect service validation error:', error.errors)
      return errorResponse(error.errors[0].message, 400, request.headers.get('origin'))
    }
    logger.error('Disconnect service error:', error)
    return errorResponse('Internal server error', 500, request.headers.get('origin'))
  }
}

Status Codes

200
OK
Successfully disconnected or already disconnected
400
Bad Request
Validation error
401
Unauthorized
Missing or invalid authentication token
404
Not Found
Service entitlement not found

Example Request

curl -X POST https://auth.nullpass.xyz/api/connect/disconnect \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "service": "DROP"
  }'

Example Response

{
  "connected": false,
  "service": "DROP",
  "tier": "premium",
  "isPremium": true,
  "message": "Successfully disconnected from service"
}

Audit Events

  • SERVICE_ENTITLEMENT_DISCONNECT: Service disconnected successfully

Authorizations

Authorization
string
header
required

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

Body

application/json
service
enum<string>
required
Available options:
DROP,
MAILS,
VAULT,
DB

Response

200

Service disconnected