Response from token generation Unauthorized

Renee Llup17 days ago

Hi Ma'am/Sir,

I need help:

import { type NextRequest, NextResponse } from "next/server";

const generateLoginToken = async (origin: string, serverUrl: string, username: string, password: string) => {
  try {
    const date = new Date();
    date.setMonth(date.getMonth() + 6);
    const expiration = date.toISOString();
    console.log("Generating token with expiration:", expiration);
    const response = await fetch(`${origin}/api/proxy/api/session/token?target=${serverUrl}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
      },
      body: new URLSearchParams(`email=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&expiration=${encodeURIComponent(expiration)}`),
    });
    console.log("Response from token generation:", response);
    if (response.ok) {
      return await response.text();
    }
  } catch (error) {
    console.error("Error generating token:", error);
  }
  return '';
};
// new URLSearchParams(`email=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`)
export async function POST(request: NextRequest) {
  try {
    const { serverUrl, username, password, token: existingToken } = await request.json();

    // If a token is provided, try to use it first
    if (existingToken) {
      try {
        // Test if the token is valid by fetching user info
        const userResponse = await fetch(`${request.nextUrl.origin}/api/proxy/api/session?target=${serverUrl}`, {
          headers: {
            'Authorization': `Bearer ${existingToken}`
          }
        });
        
        if (userResponse.ok) {
          const session = await userResponse.json();
          
          // Fetch devices and positions using the token
          const devicesResponse = await fetch(
            `${request.nextUrl.origin}/api/proxy/api/devices?target=${encodeURIComponent(serverUrl)}`, 
            { headers: { 'Authorization': `Bearer ${existingToken}` } }
          );
          
          const positionsResponse = await fetch(
            `${request.nextUrl.origin}/api/proxy/api/positions?target=${encodeURIComponent(serverUrl)}`, 
            { headers: { 'Authorization': `Bearer ${existingToken}` } }
          );
          
          if (devicesResponse.ok && positionsResponse.ok) {
            return NextResponse.json({
              session,
              devices: await devicesResponse.json(),
              positions: await positionsResponse.json(),
              token: existingToken
            });
          }
        }
        // If token validation fails, proceed with username/password auth
      } catch (error) {
        console.log("Token validation failed, proceeding with credentials");
      }
    }

    // Authenticate with username/password if no token or token validation failed
    if (!serverUrl || !username || !password) {
      return NextResponse.json({ error: "Missing required parameters" }, { status: 400 });
    }

    const sessionResponse = await fetch(`${request.nextUrl.origin}/api/proxy/api/session?target=${serverUrl}`, {
      method: 'POST',
      body: new URLSearchParams(`email=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`),
    });

    console.log("Session response:", sessionResponse);
    if (!sessionResponse.ok) {
      throw new Error("Failed to authenticate with Traccar server");
    }
    
    const session = await sessionResponse.json();
    
    // Generate a long-lived token for future auto-login
    const loginToken = await generateLoginToken(request.nextUrl.origin, serverUrl, username, password);

    // Create base64 token for current request
    const base64Token = Buffer.from(`${username}:${password}`).toString("base64");

    // Use the proxy middleware to fetch devices
    const devicesResponse = await fetch(
      `${request.nextUrl.origin}/api/proxy/api/devices?target=${encodeURIComponent(serverUrl)}&token=${base64Token}&authType=basic`
    );

    if (!devicesResponse.ok) {
      throw new Error(`Failed to fetch devices: ${devicesResponse.statusText}`);
    }

    const devices = await devicesResponse.json();

    // Use the proxy middleware to fetch positions
    const positionsResponse = await fetch(
      `${request.nextUrl.origin}/api/proxy/api/positions?target=${encodeURIComponent(serverUrl)}&token=${base64Token}&authType=basic`
    );

    if (!positionsResponse.ok) {
      throw new Error(`Failed to fetch positions: ${positionsResponse.statusText}`);
    }

    const positions = await positionsResponse.json();

    return NextResponse.json({
      session,
      devices,
      positions,
      token: loginToken // Return the generated token
    });
  } catch (error) {
    console.error("Error connecting to Traccar:", error);
    return NextResponse.json(
      { error: error instanceof Error ? error.message : "Failed to connect to Traccar server" },
      { status: 500 }
    );
  }
}

The response..

Response from token generation: Response {
  status: 401,
  statusText: 'Unauthorized',
  headers: Headers {
    accept: 'application/json',
    'x-middleware-rewrite': 'http://5.189.134.169:8082/api/session/token',
    date: 'Wed, 09 Apr 2025 06:51:23 GMT',
    connection: 'close',
    'set-cookie': 'JSESSIONID=node017o70bug05tpb03en5jq49q017250.node0; Path=/',
    expires: 'Thu, 01 Jan 1970 00:00:00 GMT',
    'content-type': 'application/json',
    'access-control-allow-headers': 'origin, content-type, accept, authorization',
    'access-control-allow-credentials': 'true',
    'access-control-allow-methods': 'GET, POST, PUT, DELETE, OPTIONS',
    'access-control-allow-origin': '*',
    'content-length': '107',
    server: 'Jetty(11.0.21)',
    vary: 'Accept-Encoding'
  },
  body: ReadableStream { locked: false, state: 'readable', supportsBYOB: true },
  bodyUsed: false,
  ok: false,
  redirected: false,
  type: 'basic',
  url: 'http://localhost:3000/api/proxy/api/session/token?target=http://5.189.134.169:8082'
}

I have no problem when i test it in postman.