Source: account.js

import express from 'express';
import { getFollowers } from '../lib/account.js';

/**
 * Express.js router for handling user profile-related routes.
 *
 * @typedef {Object} UserProfileRouter
 * @property {Function} getProfile - Route handler for retrieving a user profile by name.
 * @property {Function} getFollowers - Route handler for retrieving followers of a user profile by name.
 *
 * @example
 * // Example usage:
 * const userProfileRouter = express.Router();
 * userProfileRouter.get('/:name', userProfileHandlers.getProfile);
 * userProfileRouter.get('/:name/followers', userProfileHandlers.getFollowers);
 * app.use('/profiles', userProfileRouter);
 */
export const router = express.Router();

/**
 * Handle GET requests for a user profile by name.
 *
 * @function
 * @param {Object} req - Express.js request object.
 * @param {Object} res - Express.js response object.
 * @returns {void} Responds with a user profile or redirects based on the request.
 *
 * @throws {Error} Responds with a 400 Bad Request if the 'name' parameter is missing.
 * @throws {Error} Responds with a 404 Not Found if no record is found for the provided 'name'.
 *
 * @example
 * // Example route:
 * // GET /profiles/:name
 * router.get('/:name', function (req, res) {
 *   // ... (route handler implementation)
 * });
 */
router.get('/:name', (req, res) => {
  // Extract the 'name' parameter from the request
  let name = req.params.name;

  // Handle missing 'name' parameter with a 400 Bad Request response
  if (!name) {
    return res.status(400).send('Bad request.');
  } else {
    // Obtain the domain from the app settings
    const domain = req.app.get('domain');

    // Append the user profile URL path to the domain
    name = `https://${domain}/u/${name}`;

    // Check if the provided 'name' matches the stored user profile ID
    if (name !== req.app.get('account').actor.id) {
      // Respond with a 404 Not Found if no record is found for the provided 'name'
      return res.status(404).send(`No record found for ${name}.`);
    } else {
      // Check the 'Accept' header for JSON-LD format and respond accordingly
      if (req.headers.accept?.includes('application/ld+json')) {
        // Respond with the user profile in JSON-LD format
        res.json(req.app.get('account').actor);
      } else {
        // Redirect to the user profile URL or the default domain
        res.redirect(req.app.get('account').actor.url || `https://${domain}/`);
      }
    }
  }
});

/**
 * Handle GET requests for the followers of a user profile by name.
 *
 * @function
 * @param {Object} req - Express.js request object.
 * @param {Object} res - Express.js response object.
 * @returns {void} Responds with a collection of followers or an error message based on the request.
 *
 * @throws {Error} Responds with a 400 Bad Request if the 'name' parameter is missing.
 * @throws {Error} Responds with a 404 Not Found if no record is found for the provided 'name'.
 *
 * @example
 * // Example route:
 * // GET /profiles/:name/followers
 * router.get('/:name/followers', function (req, res) {
 *   // ... (route handler implementation)
 * });
 */
router.get('/:name/followers', (req, res) => {
  // Extract the 'name' parameter from the request
  let name = req.params.name;

  // Handle missing 'name' parameter with a 400 Bad Request response
  if (!name) {
    return res.status(400).send('Bad request.');
  } else {
    // Obtain the domain from the app settings
    const domain = req.app.get('domain');

    // Append the user profile URL path to the domain
    name = `https://${domain}/u/${name}`;

    // Check if the provided 'name' matches the stored user profile ID
    if (name !== req.app.get('account').actor.id) {
      // Respond with a 404 Not Found if no record is found for the provided 'name'
      return res.status(404).send(`No record found for ${name}.`);
    } else {
      // Retrieve followers for the user profile
      const followers = getFollowers();

      // Assemble the followers collection in ActivityStreams format
      const followersCollection = {
        type: 'OrderedCollection',
        totalItems: followers.length,
        id: `https://${domain}/u/${name}/followers`,
        first: {
          type: 'OrderedCollectionPage',
          totalItems: followers.length,
          partOf: `https://${domain}/u/${name}/followers`,
          orderedItems: followers,
          id: `https://${domain}/u/${name}/followers?page=1`
        },
        '@context': ['https://www.w3.org/ns/activitystreams']
      };
      // Respond with the followers collection in JSON format
      res.json(followersCollection);
    }
  }
});