Skip to content

fix(ipc): allow media in configured recordings directory#755

Open
RyderAsKing wants to merge 1 commit into
webadderallorg:mainfrom
RyderAsKing:fix/configured-recordings-media-access
Open

fix(ipc): allow media in configured recordings directory#755
RyderAsKing wants to merge 1 commit into
webadderallorg:mainfrom
RyderAsKing:fix/configured-recordings-media-access

Conversation

@RyderAsKing

@RyderAsKing RyderAsKing commented Jul 11, 2026

Copy link
Copy Markdown

Allow media in configured recordings directory

Description

Fixes Recordly blocking audio/media files stored in a user-configured recordings directory.

Motivation

The editor rejected recording audio files as “disallowed” when the recordings location was changed in settings. This prevented microphone and system audio tracks from loading.

Type of Change

  • Bug Fix

Related Issue(s)

N/A

Screenshots / Video

N/A, this is a backend media-path validation fix with no UI changes.

Testing Guide

  1. Set a custom recordings directory in Recordly settings.
  2. Create or open a recording with microphone/system audio.
  3. Confirm audio tracks load in the editor without Blocked disallowed path warnings.

Automated validation:

npm test -- electron/ipc/project/manager.test.ts
npx biome lint electron/ipc/project/manager.ts electron/ipc/project/manager.test.ts
npm run build:linux

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Summary by CodeRabbit

  • Bug Fixes
    • Media files stored in the configured recordings directory are now recognized and accessible correctly.
    • Improved handling of recordings directories when paths use symbolic links or other alternate path representations.

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Media-path authorization now allowlists files beneath the runtime-configured recordings directory using canonical paths, while retaining the existing local-read fallback. A Vitest case verifies approval for a configured recordings file.

Changes

Runtime recordings authorization

Layer / File(s) Summary
Configured recordings path allowlist
electron/ipc/project/manager.ts, electron/ipc/project/manager.test.ts
isAllowedLocalMediaPath compares canonical candidate and configured recordings paths, and tests approval for a recording file resolved through resolveApprovedLocalMediaPath.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested labels: Checked

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: allowing media in the configured recordings directory.
Description check ✅ Passed The description follows the template and includes purpose, motivation, change type, testing guide, and checklist items.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@electron/ipc/project/manager.ts`:
- Around line 103-112: Update the recordings-directory check in the
path-allowance flow to canonicalize candidatePath before evaluating
isPathInsideDirectory, ensuring symlinks resolve within the configured
recordings root rather than bypassing isAllowedLocalReadPath’s canonical guard.
Preserve the existing fallback behavior for unavailable real paths, and add a
regression test covering a symlink under the recordings directory targeting a
file outside it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0376398a-295a-4cb4-96ef-57e722021899

📥 Commits

Reviewing files that changed from the base of the PR and between 15ef10c and 4d694fd.

📒 Files selected for processing (2)
  • electron/ipc/project/manager.test.ts
  • electron/ipc/project/manager.ts

Comment on lines +103 to +112
// The recordings location can be changed in settings, so the compile-time
// default RECORDINGS_DIR alone is not sufficient for media created there.
// Canonicalize the configured root as well as the candidate to retain the
// symlink protection enforced by isAllowedLocalReadPath.
const recordingsDir = await getRecordingsDir();
const canonicalRecordingsDir = await fs
.realpath(recordingsDir)
.catch(() => normalizePath(recordingsDir));
if (isPathInsideDirectory(normalizedCandidatePath, canonicalRecordingsDir)) {
return true;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show relevant files and nearby context.
git ls-files 'electron/ipc/project/*' 'electron/**/*manager*' 'electron/**/*media*' | sed -n '1,120p'

printf '\n--- manager.ts outline ---\n'
ast-grep outline electron/ipc/project/manager.ts --view expanded || true

printf '\n--- manager.ts relevant lines ---\n'
sed -n '1,220p' electron/ipc/project/manager.ts

printf '\n--- search for helper definitions/usages ---\n'
rg -n "isAllowedLocalMediaPath|isAllowedLocalReadPath|resolveApprovedLocalMediaPath|getRecordingsDir|isPathInsideDirectory|normalizePath" electron -S

Repository: webadderallorg/Recordly

Length of output: 18310


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,220p' electron/ipc/project/manager.ts
printf '\n---\n'
rg -n "isAllowedLocalMediaPath|isAllowedLocalReadPath|resolveApprovedLocalMediaPath" electron -S

Repository: webadderallorg/Recordly

Length of output: 11154


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- manager.test.ts symlink-related cases ---'
sed -n '1,220p' electron/ipc/project/manager.test.ts

printf '\n%s\n' '--- filesystem probe for the fast-path behavior ---'
node - <<'JS'
const fs = require('node:fs');
const path = require('node:path');
const os = require('node:os');

function normalizePath(p) {
  return path.normalize(p);
}
function isPathInsideDirectory(candidatePath, directoryPath) {
  const normalizedCandidatePath = normalizePath(candidatePath);
  const normalizedDirectoryPath = normalizePath(directoryPath);
  return (
    normalizedCandidatePath === normalizedDirectoryPath ||
    normalizedCandidatePath.startsWith(`${normalizedDirectoryPath}${path.sep}`)
  );
}

const base = fs.mkdtempSync(path.join(os.tmpdir(), 'recordly-probe-'));
const recordings = path.join(base, 'recordings');
const outside = path.join(base, 'outside');
fs.mkdirSync(recordings);
fs.mkdirSync(outside);
const target = path.join(outside, 'track.wav');
fs.writeFileSync(target, 'x');
const symlink = path.join(recordings, 'track.wav');
fs.symlinkSync(target, symlink);

const canonicalRecordingsDir = fs.realpathSync(recordings);
const normalizedCandidatePath = normalizePath(symlink);
const candidateReal = fs.realpathSync(normalizedCandidatePath);

console.log(JSON.stringify({
  recordings,
  outside,
  symlink,
  target,
  canonicalRecordingsDir,
  normalizedCandidatePath,
  candidateReal,
  fastPathResult: isPathInsideDirectory(normalizedCandidatePath, canonicalRecordingsDir),
  realPathInsideRecordings: isPathInsideDirectory(candidateReal, canonicalRecordingsDir),
}, null, 2));
JS

Repository: webadderallorg/Recordly

Length of output: 8878


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the existing tests around media authorization and symlinks.
sed -n '1,220p' electron/ipc/project/manager.test.ts

Repository: webadderallorg/Recordly

Length of output: 8265


Canonicalize candidatePath before the recordings-dir fast path. A symlink inside the configured recordings directory can satisfy the lexical prefix check here while resolving outside the allowlist, so this bypasses isAllowedLocalReadPath’s canonical-path guard. Add a regression test for a symlink under the recordings directory that points to a file outside it.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@electron/ipc/project/manager.ts` around lines 103 - 112, Update the
recordings-directory check in the path-allowance flow to canonicalize
candidatePath before evaluating isPathInsideDirectory, ensuring symlinks resolve
within the configured recordings root rather than bypassing
isAllowedLocalReadPath’s canonical guard. Preserve the existing fallback
behavior for unavailable real paths, and add a regression test covering a
symlink under the recordings directory targeting a file outside it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant