PhoenixKitProjects.ResourceLinks (PhoenixKitProjects v0.21.1)

Copy Markdown View Source

Makes projects and their tasks linkable and mentionable from anywhere.

Three jobs, all against the same two types (project, project_task):

Permissions are this module's problem, not core's

Core federates the question and never second-guesses the answer, which means a bug here is a leak. Both directions go through Authz, the same resolver the project pages use, rather than a private query:

  • search narrows to list_projects_for/2, so the typeahead cannot offer a project the searcher can't open — a picker that lists private titles has already leaked them, whatever the renderer does later;
  • visibility answers for the READER, who is usually not the author.

Tasks inherit their project's answer. A task is not independently visible, so asking about the task means asking about its project.

Summary

Functions

Titles and RAW deep-links for the given uuids.

Projects and tasks matching query, scoped to the SEARCHER.

The types this module owns, for the resource_links/0 callback.

Of uuids, the ones this viewer may see.

Functions

resolve_comment_resources(uuids)

@spec resolve_comment_resources([String.t()]) :: map()

Titles and RAW deep-links for the given uuids.

Raw because ResourceLinks applies the url prefix once at render — a pre-prefixed path double-prefixes under a non-root install.

Answers for BOTH types in one call: the caller groups by type, so a list of task uuids and a list of project uuids arrive separately, and a uuid that matches neither simply isn't in the result.

search_resources(query, opts)

@spec search_resources(
  String.t(),
  keyword()
) :: [map()]

Projects and tasks matching query, scoped to the SEARCHER.

Never offers something the searcher cannot open: the typeahead is the first place a leak would appear, and it is the easiest one to miss because the result looks correct to whoever is testing it.

types()

@spec types() :: %{required(String.t()) => module()}

The types this module owns, for the resource_links/0 callback.

visible_resource_uuids(uuids, opts)

@spec visible_resource_uuids(
  [String.t()],
  keyword()
) :: [String.t()]

Of uuids, the ones this viewer may see.

Called at render for someone who is usually not the author. Fails closed: an unresolvable viewer sees nothing rather than everything.