Skip to content

Releases: ddlin/vocareum-publisher

v1.3.7

Choose a tag to compare

@ddlin ddlin released this 08 Jul 15:20

Security

  • Directory scaffolding no longer writes .gitkeep through a symlink. The configured-directory scaffolding added in 1.3.6 (pull --content and orphan import) used an unguarded write, so a configured directory that was a symlink escaping the workspace (e.g. docs -> /outside) would get its .gitkeep written outside the repository. Scaffolding now skips — with a warning — any configured directory whose final path component is a symlink, matching the confinement the content read/restore paths already enforce (the part base is realpath-confined by the caller, so guarding the final segment closes the escape).

Full changelog: https://github.com/ddlin/vocareum-publisher/blob/v1.3.7/CHANGELOG.md

v1.3.6

Choose a tag to compare

@ddlin ddlin released this 08 Jul 07:26

Fixed

  • pull --content now restores an entirely-deleted assignment/part directory. When the whole part directory was gone, the per-file confinement check ran realpath() on the missing base, threw ENOENT, and returned "not confined" — so every remote file was mislabeled as an escaping symlink and skipped, and nothing was restored. Detection now recognizes a missing base (no local files or symlinks to read through) and treats every remote file as a fresh add; apply recreates the base and confines each individual write.

Added

  • pull --content scaffolds the part's configured directories after a content restore, matching a fresh import: any declared directory that is empty on the remote is recreated with a .gitkeep, while directories that received content are left untouched. Note: deleting an already-empty subdirectory is not restored, because it produces no content drift to trigger the pull.

Full changelog: https://github.com/ddlin/vocareum-publisher/blob/v1.3.6/CHANGELOG.md

v1.3.5

Choose a tag to compare

@ddlin ddlin released this 08 Jul 06:09

Fixed

  • pull --content can again restore a deleted directory in an assignment that also contains a symlink. Previously, a single remote file whose local path was (or resolved through) a symlink aborted the content drift check for the entire assignment — so a separately-deleted directory in that assignment was never detected or re-pulled, and the only recovery was to drop vocareum.yaml and re-init. This affected both symlinks escaping the part directory (e.g. docs/README.html → the shared course/lib/ tree) and in-part symlinks, which writeFileUnderBase refuses to overwrite regardless of target. vocgit now skips just the symlinked file (with a per-file warning) and still compares/restores the rest of the part.

Security

  • Hardened the content-drift scan and the stored remote-file map against symlinks. The remote-file map persisted for apply now excludes any file whose local path escapes the part directory or is itself a symlink, so a restore is never aborted by writeFileUnderBase rejecting the path. The deleted-file detector additionally skips any directory or nested entry whose path resolves outside the part directory, so apply's unlink can never follow a symlink and delete a file outside the workspace.

Full changelog: https://github.com/ddlin/vocareum-publisher/blob/v1.3.5/CHANGELOG.md

v1.3.4

Choose a tag to compare

@ddlin ddlin released this 08 Jul 04:06

Changed

  • Push settings-update fallbacks now log the Vocareum API's actual 400 message ([API: …]) when a part or assignment settings PUT is rejected and vocgit retries with a reduced payload. Previously the warning only said "rejected", hiding which field the API objected to (e.g. re-sending create-only lab fields like labtype / container_image / lab_interface on Databricks/cloud parts). Diagnostic only — the retry ladder's behavior is unchanged.

Full changelog: https://github.com/ddlin/vocareum-publisher/blob/v1.3.4/CHANGELOG.md

v1.3.3

Choose a tag to compare

@ddlin ddlin released this 02 Jul 16:12

Fixed

  • Orphan import no longer fails with a bogus symlink error: vocgit pull
    imports failed with Invalid path: "..." escapes base directory through a symlink for every orphaned assignment because the symlink-hardened write
    path treated a not-yet-created import directory as an escape (realpath on
    the missing base). writeFileUnderBase now creates the trusted base
    directory before running its confinement checks, restoring fresh imports
    while keeping all symlink-escape rejections intact.
  • lti_url classified as a non-setting: Vocareum returns a server-derived
    LTI launch URL on assignment reads. It is identity metadata (encodes the
    course/assignment IDs), not an instructor-configurable setting, so it is now
    dropped like part_url instead of being preserved under _unknown_settings
    and flagged in the end-of-run unsupported-fields report.

Security

  • The user-typed import directory name is now confined to the workspace with
    realpath-based validation (assertConfinedToWorkspace) before any directory
    creation. A lexical-only check was insufficient: a name beneath an
    in-workspace symlink that points outside the workspace would pass the lexical
    test and let the import write outside the working tree.
  • Removed an accidental self-dependency (vocareum-publisher listed in its own
    dependencies) that caused a nested copy of the package to be installed.

v1.3.2

Choose a tag to compare

@ddlin ddlin released this 29 Jun 21:00

CLI: vocareum-publisher@1.3.2 (npm) — Stage 1a internal service-layer refactor; no user-facing change (same CLI flags, output, exit codes, and API behavior). See CHANGELOG.md.

VS Code extension: the attached vocgit-1.1.0.vsix is the current extension build (the extension is versioned independently of the CLI). Install with code --install-extension vocgit-1.1.0.vsix — see vscode-extension/README.md.

v1.2.0

Choose a tag to compare

@ddlin ddlin released this 12 Jun 02:55

CLI: vocareum-publisher@1.2.0 (npm) — see CHANGELOG.md for details.

VS Code extension: the attached vocgit-1.1.0.vsix is the current extension build (extension versions move independently of the CLI). Install with code --install-extension vocgit-1.1.0.vsix — see vscode-extension/README.md for details.