OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-note / lib / services / public-page-service.js

81 lines · javascript ref:
/**
 * PublicPageService — Data preparation for public-facing SSR pages.
 *
 * Consolidates the user/notebook/note lookups and permission checks
 * that were scattered across web.js public route handlers.
 */

export class PublicPageService {
  constructor ({ noteManager, authManager }) {
    this.noteManager = noteManager
    this.authManager = authManager
  }

  /**
   * Get a user's public profile with their public notebooks.
   *
   * @param {string} username
   * @returns {Promise<Object|null>} { user, notebooks } or null if user not found
   */
  async getUserProfile (username) {
    const user = await this.authManager.identityRegistry.getUserByUsername(username)
    if (!user) return null

    const allNotebooks = await this.noteManager.listNotebooks()
    const notebooks = allNotebooks.filter(nb =>
      nb.ownerId === user.userId && nb.visibility !== 'private' && !nb.encrypted
    )

    return { user, notebooks }
  }

  /**
   * Get a notebook's public view with note list.
   *
   * @param {string} username
   * @param {string} bookSlug
   * @returns {Promise<Object>} { user, notebook, notes } or throws
   */
  async getNotebookView (username, bookSlug) {
    const user = await this.authManager.identityRegistry.getUserByUsername(username)
    if (!user) return { error: 'user-not-found' }

    const notebook = await this.noteManager.getNotebook(bookSlug)
    if (!notebook || notebook.ownerId !== user.userId) return { error: 'notebook-not-found' }

    if (notebook.visibility === 'private' || notebook.encrypted) {
      return { error: 'private' }
    }

    const notes = await this.noteManager.listNotes(bookSlug)
    return { user, notebook, notes }
  }

  /**
   * Get a single note's public view.
   *
   * @param {string} username
   * @param {string} bookSlug
   * @param {string} noteId
   * @returns {Promise<Object>} { user, notebook, note } or { error }
   */
  async getNoteView (username, bookSlug, noteId) {
    const user = await this.authManager.identityRegistry.getUserByUsername(username)
    if (!user) return { error: 'user-not-found' }

    const notebook = await this.noteManager.getNotebook(bookSlug)
    if (!notebook || notebook.ownerId !== user.userId) return { error: 'notebook-not-found' }

    if (notebook.visibility === 'private' || notebook.encrypted) {
      return { error: 'private' }
    }

    try {
      const note = await this.noteManager.getNote(bookSlug, noteId)
      return { user, notebook, note }
    } catch {
      return { error: 'note-not-found' }
    }
  }
}