OverviewFilesCommitsIssuesDocsReleasesPeers

pear-git-v3 / lib / auth / user-resolver.js

38 lines · javascript ref:
/**
 * resolveUserId — translate a free-form identifier (userId, identity-hex,
 * or username) into a canonical userId.
 *
 * Returns null if the input does not resolve to any active user. Caller
 * decides how to surface that (404 to API caller, skip in migrations).
 *
 * The lookup order is intentional:
 *   1. Direct userId — if the input is already a stored userId, this
 *      short-circuits without touching identity / username indexes.
 *   2. Identity pubkey — 64-hex root or device pubkey linked to a user.
 *   3. Username — the indexed `username` field (set via SET_USERNAME).
 *
 * Each step is wrapped in `.catch(() => null)` so a missing-index miss
 * never throws — the function only "throws" by returning null. Callers
 * that need to differentiate "no match" from "registry crashed" can
 * call the underlying registry methods directly.
 */
export async function resolveUserId (registry, input) {
  if (!registry || typeof input !== 'string') return null
  const trimmed = input.trim()
  if (!trimmed) return null

  // 1. Direct userId
  const byId = await registry.getUser(trimmed).catch(() => null)
  if (byId && byId.userId) return byId.userId

  // 2. Identity pubkey (root or device)
  const byIdentity = await registry.getUserByIdentity(trimmed).catch(() => null)
  if (byIdentity && byIdentity.userId) return byIdentity.userId

  // 3. Username
  const byUsername = await registry.getUserByUsername(trimmed).catch(() => null)
  if (byUsername && byUsername.userId) return byUsername.userId

  return null
}