Skip to content

Devel#1873

Merged
JoshuaSBrown merged 3 commits intostagingfrom
devel
Feb 24, 2026
Merged

Devel#1873
JoshuaSBrown merged 3 commits intostagingfrom
devel

Conversation

@JoshuaSBrown
Copy link
Collaborator

@JoshuaSBrown JoshuaSBrown commented Feb 24, 2026

Ticket

Description

How Has This Been Tested?

Artifacts (if appropriate):

Tasks

  • - A description of the PR has been provided, and a diagram included if it is a new feature.
  • - Formatter has been run
  • - CHANGELOG comment has been added
  • - Labels have been assigned to the pr
  • - A reviwer has been added
  • - A user has been assigned to work on the pr
  • - If new feature a unit test has been added

Summary by Sourcery

Improve path consistency validation, repository resolution, and API version handling, and enrich transfer tasks with detailed token metadata.

Bug Fixes:

  • Correct record path consistency checks to compare against computed repository paths and provide clearer error messages.
  • Fix API version and release metadata checks to use updated version field names and align web server expectations with core replies.
  • Prevent invalid POSIX file paths and mismatched repository IDs from being authorized by normalizing and validating paths against known repositories.

Enhancements:

  • Refine record path construction to work directly from owner UIDs and improve error reporting when UIDs are unsupported.
  • Add repository resolution by file path and POSIX path normalization utilities to centralize and harden path handling.
  • Ensure protobuf responses from the core are converted to plain objects with defaults before being passed to handlers.
  • Include token type and scopes in transfer task parameters and derive access tokens via the UserToken model instead of the legacy helper.

Tests:

  • Adjust record tests to align with updated repository identifiers used in the new path consistency logic.

#1861)

* fix: prevent defaults being set to undefined, and interpret numbers and enums as strings.

* chore: Auto-format JavaScript files with Prettier
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Feb 24, 2026

Reviewer's Guide

Refactors record path handling and validation, tightens repository/path resolution, updates version/APIs for the web server, ensures protobuf replies are converted to plain objects, and changes transfer tasks to use structured user tokens with additional metadata.

Sequence diagram for protobuf reply handling and plain-object conversion

sequenceDiagram
    participant CoreServer
    participant WebSocket as g_core_sock
    participant MessageHandler as onMessageHandler
    participant MsgRegistry as g_msg_by_id

    CoreServer->>WebSocket: send envelope frame
    WebSocket-->>onMessageHandler: message event(reply, msg_type)
    onMessageHandler->>MsgRegistry: lookup msg_info by msg_type
    MsgRegistry-->>onMessageHandler: msg_info(type, field_name, field_id)

    alt handler exists
        onMessageHandler->>onMessageHandler: determine which_field
        onMessageHandler->>MsgRegistry: resolve actual_entry by which_field
        MsgRegistry-->>onMessageHandler: actual_entry(type)
        onMessageHandler->>onMessageHandler: resolve_type = actual_entry.type or msg_info.type
        onMessageHandler->>onMessageHandler: msg = resolve_type.toObject(msg, defaults=true, longs=String, enums=String)
        onMessageHandler->>MessageHandler: f(msg)
    else no handler
        onMessageHandler->>onMessageHandler: ignore or log
    end
Loading

Class diagram for updated Record and Repo path handling

classDiagram
    class Record {
        -string #key
        -object #loc
        -object #repo
        -number #error
        -string #err_msg
        -boolean #alloc
        _pathToRecord(uid string, basePath string) string
        isPathConsistent(a_path string) boolean
    }

    class Repo {
        +Repo(id string)
        +resolveFromPath(file_path string) Repo
        +pathType(file_path string) PathType
        +id() string
        -string path
    }

    class PathType {
        <<enumeration>>
        UNKNOWN
        /* other members not shown */
    }

    class PosixPathUtil {
        +normalizePOSIXPath(a_posix_path string) string
        +splitPOSIXPath(a_posix_path string) string[]
    }

    Record ..> Repo : validates
    Repo ..> PosixPathUtil : uses
    Repo --> PathType : returns
Loading

File-Level Changes

Change Details Files
Refine record path construction and consistency checks for repository-backed records.
  • Change _pathToRecord to accept a uid string instead of a location object and simplify error messaging without logging undefined variables.
  • Normalize input paths in isPathConsistent, distinguish between in-flight and stable records, and compare constructed paths directly instead of using _comparePaths.
  • Improve error reporting when allocations or repositories are missing, or when record paths do not match expected locations.
core/database/foxx/api/record.js
Align web server versioning fields and core API compatibility checks with updated version schema and protobuf field names, and normalize inbound messages.
  • Switch global release and API version variables to use new version constant names (RELEASE_YEAR/MONTH/DAY/HOUR/MINUTE and MAJOR/MINOR/PATCH).
  • Update compatibility checks and logging to use camelCase reply fields (apiMajor/apiMinor/apiPatch and releaseYear/.../releaseMinute).
  • Convert protobufjs messages from the core socket into plain objects with defaults, stringified longs, and string enums before invoking callbacks.
web/datafed-ws.js
Add repository resolution from a file path and enforce that authz requests use consistent file and repo values.
  • Introduce Repo.resolveFromPath to canonicalize a POSIX path, ensure it contains no invalid sequences, and find the best-matching repository based on configured repo paths, throwing if none match.
  • Update the authz router to resolve the repo from the provided file path and verify it matches the repo id in the request before further path checks.
core/database/foxx/api/repo.js
core/database/foxx/api/authz_router.js
Enhance POSIX path utilities to validate and normalize incoming paths.
  • Add normalizePOSIXPath helper that validates input type and uses path.posix.normalize, throwing ERR_INVALID_PARAM for invalid inputs.
core/database/foxx/api/posix_path.js
Update transfer-related tasks to use structured user tokens with additional metadata for transfers.
  • Replace g_lib.getAccessToken usage in transfer and owner-change tasks with UserToken instances that fetch a token document and format it for transfer tasks.
  • Augment transfer params with token_type and scopes from formatted user tokens so downstream components receive richer token metadata.
core/database/foxx/api/tasks.js
Adjust record tests to reflect updated fixture data.
  • Change the test repository id from repo/orange-at-com to repo/orange-at-org to match current test data.
core/database/foxx/tests/record.test.js

Possibly linked issues

  • #N/A: PR refactors and secures Foxx authz path handling and related components, directly addressing the authz refactor issue.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In Record.isPathConsistent you removed _comparePaths and now rely on strict string equality; consider whether this loses any intended normalization behavior (e.g., trailing slashes, case, repo.path leading slash) and either restore a dedicated path comparison helper or extend the current logic to cover those cases explicitly.
  • The new Repo.resolveFromPath does a full scan of g_db.repo on each call and treats any path that normalizes differently as invalid; if this endpoint is on a hot path, consider caching repo paths and/or being more precise about which normalization patterns you want to reject instead of blanket canonical !== file_path.
  • In tasks.js the new usage of UserToken (including UserToken.formatUserTokenForTransferTask and formatUserToken) assumes this class is available in the module; double-check that it is required/imported correctly and that get_token() failure modes are compatible with the prior g_lib.getAccessToken behavior for these task flows.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Record.isPathConsistent` you removed `_comparePaths` and now rely on strict string equality; consider whether this loses any intended normalization behavior (e.g., trailing slashes, case, repo.path leading slash) and either restore a dedicated path comparison helper or extend the current logic to cover those cases explicitly.
- The new `Repo.resolveFromPath` does a full scan of `g_db.repo` on each call and treats any path that normalizes differently as invalid; if this endpoint is on a hot path, consider caching repo paths and/or being more precise about which normalization patterns you want to reject instead of blanket `canonical !== file_path`.
- In `tasks.js` the new usage of `UserToken` (including `UserToken.formatUserTokenForTransferTask` and `formatUserToken`) assumes this class is available in the module; double-check that it is required/imported correctly and that `get_token()` failure modes are compatible with the prior `g_lib.getAccessToken` behavior for these task flows.

## Individual Comments

### Comment 1
<location path="core/database/foxx/api/record.js" line_range="75-78" />
<code_context>
+     * @returns {string|null} - the path to the record or null if error
      */
-    _pathToRecord(loc, basePath) {
+    _pathToRecord(uid, basePath) {
         const path = basePath.endsWith("/") ? basePath : basePath + "/";
-        if (loc.uid.charAt(0) == "u") {
-            return path + "user/" + loc.uid.substr(2) + "/" + this.#key;
-        } else if (loc.uid.charAt(0) == "p") {
-            return path + "project/" + loc.uid.substr(2) + "/" + this.#key;
+        if (uid.charAt(0) === "u") {
+            return path + "user/" + uid.substr(2) + "/" + this.#key;
+        } else if (uid.charAt(0) === "p") {
</code_context>
<issue_to_address>
**suggestion:** Avoid deprecated `substr` and prefer `slice` for uid extraction.

This still calls `uid.substr(2)` for both user and project prefixes. Since `substr` is deprecated, please switch to `uid.slice(2)` to use the modern equivalent without changing behavior.

```suggestion
        if (uid.charAt(0) === "u") {
            return path + "user/" + uid.slice(2) + "/" + this.#key;
        } else if (uid.charAt(0) === "p") {
            return path + "project/" + uid.slice(2) + "/" + this.#key;
```
</issue_to_address>

### Comment 2
<location path="core/database/foxx/api/record.js" line_range="201-202" />
<code_context>
-            this.#repo = g_db._document(this.#loc.new_repo);
-
-            if (!this.#repo) {
+            const new_repo = g_db._document(this.#loc.new_repo);
+            if (!new_repo) {
                 this.#error = error.ERR_INTERNAL_FAULT;
                 this.#err_msg =
</code_context>
<issue_to_address>
**issue (bug_risk):** In the in-flight branch, `this.#repo` is no longer updated, which may break callers relying on it after `isPathConsistent`.

`new_repo` is now local and `this.#repo` is only updated in the non–in-flight branch, so callers that expect `isPathConsistent` to leave `this.#repo` pointing at the resolved repo may now see stale state. Please update `this.#repo` to `new_repo` after a successful resolution to preserve the previous behavior.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +75 to +78
if (uid.charAt(0) === "u") {
return path + "user/" + uid.substr(2) + "/" + this.#key;
} else if (uid.charAt(0) === "p") {
return path + "project/" + uid.substr(2) + "/" + this.#key;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Avoid deprecated substr and prefer slice for uid extraction.

This still calls uid.substr(2) for both user and project prefixes. Since substr is deprecated, please switch to uid.slice(2) to use the modern equivalent without changing behavior.

Suggested change
if (uid.charAt(0) === "u") {
return path + "user/" + uid.substr(2) + "/" + this.#key;
} else if (uid.charAt(0) === "p") {
return path + "project/" + uid.substr(2) + "/" + this.#key;
if (uid.charAt(0) === "u") {
return path + "user/" + uid.slice(2) + "/" + this.#key;
} else if (uid.charAt(0) === "p") {
return path + "project/" + uid.slice(2) + "/" + this.#key;

@JoshuaSBrown JoshuaSBrown merged commit 0fae43e into staging Feb 24, 2026
14 checks passed
@JoshuaSBrown JoshuaSBrown self-assigned this Feb 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant