Skip to content

feat(js): adds RSYNC module#6410

Merged
dwisiswant0 merged 10 commits intodevfrom
feat-6409-rsync-auth
Dec 31, 2025
Merged

feat(js): adds RSYNC module#6410
dwisiswant0 merged 10 commits intodevfrom
feat-6409-rsync-auth

Conversation

@Mzack9999
Copy link
Member

@Mzack9999 Mzack9999 commented Aug 21, 2025

Proposed changes

Close #6409

Checklist

  • Pull request is created against the dev branch
  • All checks passed (lint, unit/integration/regression tests etc.) with my changes
  • I have added tests that prove my fix is effective or that my feature works
  • I have added necessary documentation (if appropriate)

Summary by CodeRabbit

  • New Features

    • Added an RSYNC client API to browse servers: list available modules and list files within a module; responses include captured RSYNC driver output for inspection.
  • Tests

    • Added RSYNC-based JavaScript integration test (disabled on Windows/macOS) that starts a temporary RSYNC server, runs the test, and cleans up.
  • Chores

    • Updated project dependencies to support RSYNC functionality.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 21, 2025

Walkthrough

Adds an RSYNC client API (RsyncClient) with ListModules and ListFilesInModule, centralizes connection via a fast dialer, captures driver output in responses, suppresses plugin.Run errors in isRsync, introduces an rsync integration test and Docker resource, and updates go.mod with two dependencies.

Changes

Cohort / File(s) Summary
Dependencies (go.mod)
go.mod
Added a direct RSYNC dependency and an indirect buffer dependency.
RSYNC client feature & flow updates
pkg/js/libs/rsync/rsync.go
Added RsyncClient and RsyncListResponse; implemented ListModules and ListFilesInModule; added connectWithFastDialer and replaced direct dial usage in isRsync; captures driver logs into Output; isRsync now suppresses plugin.Run errors (returns nil on plugin.Run failure).
Integration tests: JS rsync testcase & docker resource
cmd/integration-test/javascript.go
Added javascriptRsyncTest and registered protocols/javascript/rsync-test.yaml; introduced rsyncResource Docker setup (Alpine rsync daemon) with lifecycle/expiration, retry logic in test execution, and resource purge handling.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor JS as JS Caller
  participant RC as RsyncClient
  participant Dial as FastDialer
  participant RS as rsynclib

  rect rgb(240,248,255)
    note over JS,RC: List modules
    JS->>RC: ListModules(ctx, host, port, user, pass)
    RC->>Dial: connectWithFastDialer(host:port)
    Dial-->>RC: net.Conn / error
    RC->>RS: rsynclib.ListModules(conn, creds)
    RS-->>RC: modules[], logs
    RC-->>JS: RsyncListResponse{Modules, Output}
  end

  rect rgb(245,255,240)
    note over JS,RC: List files in module
    JS->>RC: ListFilesInModule(ctx, host, port, user, pass, module)
    RC->>Dial: connectWithFastDialer(host:port)
    Dial-->>RC: net.Conn / error
    RC->>RS: SocketClient(conn, module, creds) -> List()
    RS-->>RC: files[], logs
    RC-->>JS: RsyncListResponse{Files, Output}
  end

  rect rgb(255,250,240)
    note over RC: isRsync path (plugin invocation)
    JS->>RC: isRsync(...)
    RC->>Dial: connectWithFastDialer(...)
    Dial-->>RC: conn / error
    RC->>RS: plugin.Run(...)
    RS-->>RC: error/logs
    note right of RC: plugin.Run errors are suppressed (isRsync returns nil on plugin.Run failure)
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Poem

I nibble bytes beneath the moon,
New modules hum a gentle tune,
I dial quick paths through net and log,
Gather lists from every bog,
Hoppity-hop — rsync, sing anew! 🐇

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR implements all coding requirements from #6409: authenticated RSYNC support with username/password, ListModules method, and ListFilesInModule method for listing shares.
Out of Scope Changes check ✅ Passed All changes are scoped to RSYNC authentication: adding dependencies, RsyncClient/RsyncListResponse types, authentication methods, and integration tests directly supporting the feature requirements.
Title check ✅ Passed The title 'feat(js): adds RSYNC module' accurately describes the main change in the pull request, which is adding a new RSYNC module to the JavaScript protocol implementation with public types, methods, and integration tests.
✨ Finishing touches
  • 📝 Generate docstrings

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 and usage tips.

@Mzack9999 Mzack9999 marked this pull request as ready for review August 25, 2025 17:56
@auto-assign auto-assign bot requested a review from dwisiswant0 August 25, 2025 17:56
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (8)
pkg/js/libs/rsync/rsync.go (8)

20-28: Docstring references gokrazy driver but the code imports a different fork

Comment says “Internally client uses https://github.com/gokrazy/rsync driver,” but imports point to github.com/Mzack9999/go-rsync/rsync. Please align the docs to avoid confusion (e.g., clarify it's a fork of gokrazy, if applicable).

- // Internally client uses https://github.com/gokrazy/rsync driver.
+ // Internally the client uses a forked rsync driver (github.com/Mzack9999/go-rsync),
+ // originally based on gokrazy/rsync.

42-54: Inconsistent naming in docs (“ListSharesResponse”, “ListShares”) vs actual API

The type is RsyncListResponse and the methods are ListModules / ListFilesInModule, but comments and examples mention “ListSharesResponse” and ListShares. Please fix wording to reflect the exported API.

- // ListSharesResponse is the response from the ListShares function.
- // this is returned by ListShares function.
+ // RsyncListResponse is returned by ListModules and ListFilesInModule.

57-63: Propagate context to the fast dialer instead of using context.Background()

Using context.Background() ignores caller cancellations/timeouts. Thread the ctx down for better control, especially inside scans.

-func connectWithFastDialer(executionId string, host string, port int) (net.Conn, error) {
+func connectWithFastDialer(ctx context.Context, executionId string, host string, port int) (net.Conn, error) {
   dialer := protocolstate.GetDialersWithId(executionId)
   if dialer == nil {
     return nil, fmt.Errorf("dialers not initialized for %s", executionId)
   }
-  return dialer.Fastdialer.Dial(context.Background(), "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
+  return dialer.Fastdialer.Dial(ctx, "tcp", net.JoinHostPort(host, strconv.Itoa(port)))
}

And in the only call site:

-conn, err := connectWithFastDialer(executionId, host, port)
+conn, err := connectWithFastDialer(context.Background(), executionId, host, port)

If feasible, also thread the original ctx from IsRsync into isRsync to respect upstream cancellations/timeouts.


93-94: Swallowing plugin errors alters semantics and hinders troubleshooting

Returning nil on rsyncPlugin.Run error makes it indistinguishable from “not rsync.” If intentional, add a debug log or metric so users can differentiate transport/plugin failures from clean negatives. Otherwise, consider returning a wrapped error.

-  if err != nil {
-    return resp, nil
-  }
+  if err != nil {
+    // Treat as negative but record reason for diagnostics.
+    // TODO: emit debug log/metric here if available.
+    return resp, nil
+  }

Would you like me to wire a debug logger here behind a global/debug flag?


148-152: Don’t send empty credentials; build options conditionally

Passing WithClientAuth("", "") may change server behavior (e.g., provoke auth or lockouts). Build options slice and only add auth when provided.

- sr, err := rsynclib.ListModules(address,
-   rsynclib.WithClientAuth(username, password),
-   rsynclib.WithLogger(logger),
-   rsynclib.WithFastDialer(fastDialer.Fastdialer),
- )
+ opts := []rsynclib.Option{rsynclib.WithFastDialer(fastDialer.Fastdialer)}
+ opts = append(opts, rsynclib.WithLogger(logger))
+ if username != "" || password != "" {
+   opts = append(opts, rsynclib.WithClientAuth(username, password))
+ }
+ sr, err := rsynclib.ListModules(address, opts...)

169-187: DRY: repeated logger construction

The bytes.Buffer + slog.TextHandler boilerplate is duplicated in both list functions. Consider a small helper that returns (logger *slog.Logger, getOutput func() string) to centralize redaction/capping as well.

I can provide a small newBufferedLogger() helper if you want me to push a patch.


188-193: Same as above: conditional auth, plus ensure client cleanup

Build options conditionally and ensure the client is closed if the driver exposes a Close/Disconnect method to avoid leaks.

- sr, err := rsynclib.SocketClient(nil, address, module, ".",
-   rsynclib.WithClientAuth(username, password),
-   rsynclib.WithLogger(logger),
-   rsynclib.WithFastDialer(fastDialer.Fastdialer),
- )
+ opts := []rsynclib.Option{rsynclib.WithFastDialer(fastDialer.Fastdialer), rsynclib.WithLogger(logger)}
+ if username != "" || password != "" {
+   opts = append(opts, rsynclib.WithClientAuth(username, password))
+ }
+ sr, err := rsynclib.SocketClient(nil, address, module, ".", opts...)
+ // If the client exposes Close(), ensure we don't leak the connection:
+ // defer sr.Close()

Please verify whether the returned client type has a Close() method and add a defer accordingly.


197-201: Error message may over-attribute failures to auth

sr.List() can fail for reasons beyond authentication (permissions, module path, network hiccups). Consider a more neutral message.

- return RsyncListResponse{}, fmt.Errorf("authentication failed: %v", err)
+ return RsyncListResponse{}, fmt.Errorf("list failed (auth/permissions/network): %v", err)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7b33c and 36e7701.

⛔ Files ignored due to path filters (4)
  • cmd/nuclei/rsync.yaml is excluded by !**/*.yaml
  • go.sum is excluded by !**/*.sum
  • pkg/js/generated/go/librsync/rsync.go is excluded by !**/generated/**
  • pkg/js/generated/ts/rsync.ts is excluded by !**/generated/**
📒 Files selected for processing (2)
  • go.mod (2 hunks)
  • pkg/js/libs/rsync/rsync.go (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
pkg/js/libs/rsync/rsync.go (2)
pkg/protocols/common/protocolstate/state.go (1)
  • GetDialersWithId (39-45)
pkg/js/generated/ts/rsync.ts (3)
  • RsyncClient (25-70)
  • ListModules (53-55)
  • ListFilesInModule (67-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Tests (macOS-latest)
  • GitHub Check: Tests (ubuntu-latest)
  • GitHub Check: Tests (windows-latest)
🔇 Additional comments (1)
go.mod (1)

247-247: No change needed for kubuffer require

Running go mod why -m github.com/kaiakz/ubuffer shows it is pulled in via github.com/Mzack9999/go-rsync (which your module imports) and thus isn’t pruned by go mod tidy. This explicit indirect requirement is required to pin the version for reproducible builds, so it should remain.

Comment on lines +50 to +54
RsyncListResponse struct {
Modules []string
Files []string
Output string
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

JS API mismatch: Go returns RsyncListResponse, TS definitions expect string[]

The generated TS in pkg/js/generated/ts/rsync.ts documents:

  • ListModules(...): string[] | null
  • ListFilesInModule(...): string[] | null

But Go returns RsyncListResponse with { Modules|Files, Output }. This will confuse users and may break typings.

Two options:

  • Update TS signatures and docs to return an object with { modules?: string[]; files?: string[]; output?: string }.
  • Or change Go to return []string and expose logs via a separate debug method/flag.

I can open a follow-up PR to update the TS definitions—let me know.

Comment on lines +111 to +114
func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
executionId := ctx.Value("executionId").(string)
return listModules(executionId, host, port, username, password)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid panic on missing executionId in context

Direct type assertion will panic if the key is absent or of the wrong type. Return a clean error instead.

-func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
-  executionId := ctx.Value("executionId").(string)
-  return listModules(executionId, host, port, username, password)
-}
+func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
+  executionId, ok := ctx.Value("executionId").(string)
+  if !ok || executionId == "" {
+    return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context")
+  }
+  return listModules(executionId, host, port, username, password)
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
executionId := ctx.Value("executionId").(string)
return listModules(executionId, host, port, username, password)
}
func (c *RsyncClient) ListModules(ctx context.Context, host string, port int, username string, password string) (RsyncListResponse, error) {
executionId, ok := ctx.Value("executionId").(string)
if !ok || executionId == "" {
return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context")
}
return listModules(executionId, host, port, username, password)
}
🤖 Prompt for AI Agents
In pkg/js/libs/rsync/rsync.go around lines 111 to 114, the function uses a
direct type assertion on ctx.Value("executionId").(string) which will panic if
the key is missing or not a string; change it to retrieve the value with the
comma-ok idiom (v, ok := ctx.Value("executionId").(string)) and return a clear
error (e.g. fmt.Errorf or errors.New) when ok is false instead of allowing a
panic; then pass the validated executionId to listModules.

Comment on lines +124 to +127
func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
executionId := ctx.Value("executionId").(string)
return listFilesInModule(executionId, host, port, username, password, module)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Same: guard against missing executionId to prevent panic

Repeat the safe-assertion pattern for ListFilesInModule.

-func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
-  executionId := ctx.Value("executionId").(string)
-  return listFilesInModule(executionId, host, port, username, password, module)
-}
+func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
+  executionId, ok := ctx.Value("executionId").(string)
+  if !ok || executionId == "" {
+    return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context")
+  }
+  return listFilesInModule(executionId, host, port, username, password, module)
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
executionId := ctx.Value("executionId").(string)
return listFilesInModule(executionId, host, port, username, password, module)
}
func (c *RsyncClient) ListFilesInModule(ctx context.Context, host string, port int, username string, password string, module string) (RsyncListResponse, error) {
executionId, ok := ctx.Value("executionId").(string)
if !ok || executionId == "" {
return RsyncListResponse{}, fmt.Errorf("rsync: missing executionId in context")
}
return listFilesInModule(executionId, host, port, username, password, module)
}
🤖 Prompt for AI Agents
In pkg/js/libs/rsync/rsync.go around lines 124 to 127, the code unconditionally
type-asserts ctx.Value("executionId").(string) which can panic if the value is
missing; update ListFilesInModule to safely retrieve the executionId using the
comma-ok form (val, ok := ctx.Value("executionId").(string)) and return a
descriptive error if ok is false (matching the safe-assertion pattern used in
the other method), then pass the validated executionId into listFilesInModule.

Comment on lines +137 to +147
// Create a bytes buffer for logging
var logBuffer bytes.Buffer

// Create a custom slog handler that writes to the buffer
logHandler := slog.NewTextHandler(&logBuffer, &slog.HandlerOptions{
Level: slog.LevelDebug,
})

// Create a logger that writes to our buffer
logger := slog.New(logHandler)

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Sensitive data risk: driver logs are surfaced verbatim via Output

You capture driver logs at debug level and return them to templates (RsyncListResponse.Output). Depending on the driver, logs may include credentials or server banners that we don’t want to leak downstream or to user logs.

Mitigations:

  • Only attach a logger when an explicit “debug”/“verbose” flag is enabled.
  • Redact credentials from the buffer before returning.
  • Cap output length to avoid memory blowups.

Minimal, localized change to redact obvious secrets:

-  result := RsyncListResponse{
-    Modules: make([]string, len(sr)),
-    Output:  logBuffer.String(),
-  }
+  result := RsyncListResponse{
+    Modules: make([]string, len(sr)),
+    Output:  sanitizeRsyncLogs(logBuffer.String(), username, password),
+  }

Add this helper (and strings import) elsewhere in the file:

// sanitizeRsyncLogs removes obvious secrets from log output.
// Best-effort: relies on the caller passing the same creds used for auth.
func sanitizeRsyncLogs(out, user, pass string) string {
  // Skip work quickly
  if out == "" {
    return out
  }
  // Redact password first to avoid accidental leaking
  if pass != "" {
    out = strings.ReplaceAll(out, pass, "******")
  }
  if user != "" {
    out = strings.ReplaceAll(out, user, "***")
  }
  // Optionally cap to N bytes
  const max = 8 << 10 // 8KiB
  if len(out) > max {
    out = out[:max] + "...[truncated]"
  }
  return out
}

If preferred, I can refactor to enable logging only under an explicit debug setting.

Also applies to: 157-161

Comment on lines +203 to +206
result := RsyncListResponse{
Files: make([]string, len(list)),
Output: logBuffer.String(),
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Apply the same redaction/capping to Output in files listing

Mirror the sanitizeRsyncLogs usage here to prevent leaking secrets and cap size.

-  result := RsyncListResponse{
-    Files:  make([]string, len(list)),
-    Output: logBuffer.String(),
-  }
+  result := RsyncListResponse{
+    Files:  make([]string, len(list)),
+    Output: sanitizeRsyncLogs(logBuffer.String(), username, password),
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
result := RsyncListResponse{
Files: make([]string, len(list)),
Output: logBuffer.String(),
}
result := RsyncListResponse{
Files: make([]string, len(list)),
Output: sanitizeRsyncLogs(logBuffer.String(), username, password),
}
🤖 Prompt for AI Agents
In pkg/js/libs/rsync/rsync.go around lines 203 to 206, the
RsyncListResponse.Output is assigned the raw logBuffer.String() which can leak
secrets and exceed size limits; apply the same sanitizeRsyncLogs redaction and
capping used elsewhere to the Output field (call
sanitizeRsyncLogs(logBuffer.String()) and assign that result, ensuring it honors
the existing max length/cap logic) so Output is redacted and size-limited before
being returned.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (4)
cmd/integration-test/javascript.go (4)

105-133: Remove ineffective pool.Retry wrapper; it never retries.

The closure always returns nil, so pool.Retry won’t retry. Either return the actual error from the closure or drop pool.Retry and call directly (you already have an outer retry loop).

Apply this minimal change:

-        _ = pool.Retry(func() error {
-            //let rsync server start
-            time.Sleep(3 * time.Second)
-            results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
-            return nil
-        })
-        if err != nil {
-            return err
-        }
+        // let rsync server start
+        time.Sleep(3 * time.Second)
+        results, err = testutils.RunNucleiTemplateAndGetResults(filePath, finalURL, debug)
+        if err != nil {
+            return err
+        }

111-111: Prefer 127.0.0.1 over localhost for stability.

Avoids IPv6/hosts-file surprises when the daemon only listens on IPv4.

-    finalURL := "localhost:" + tempPort
+    finalURL := "127.0.0.1:" + tempPort

205-205: Make config writing more portable and remove ambiguity in credentials.

  • Use printf instead of echo -e for reliability.
  • The OS user password (mysecret) differs from rsync secret (MySecret123). Consider aligning or dropping the OS password step since rsync auth uses the secrets file.
-  Cmd:        []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:mysecret' | chpasswd && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && echo -e '[data]\\n  path = /data\\n  comment = Local Rsync Share\\n  read only = false\\n  auth users = rsyncuser\\n  secrets file = /etc/rsyncd.secrets' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"},
+  Cmd:        []string{"sh", "-c", "apk add --no-cache rsync shadow && useradd -m rsyncuser && echo 'rsyncuser:MySecret123' > /etc/rsyncd.secrets && chmod 600 /etc/rsyncd.secrets && printf '[data]\\n  path = /data\\n  comment = Local Rsync Share\\n  read only = false\\n  auth users = rsyncuser\\n  secrets file = /etc/rsyncd.secrets\\n' > /etc/rsyncd.conf && mkdir -p /data && exec rsync --daemon --no-detach --config=/etc/rsyncd.conf"},

103-134: Optional: collapse result-count check into the retry loop.

You can return the assertion from inside the loop to avoid tracking an errors slice.

-    if err := expectResultsCount(results, 1); err == nil {
-        return nil
-    } else {
-        errs = append(errs, err)
-    }
+    if err := expectResultsCount(results, 1); err == nil {
+        return nil
+    } else {
+        errs = append(errs, err)
+    }

If you adopt the earlier suggestion to remove pool.Retry, consider returning on success and continuing on error, keeping logic concise.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 36e7701 and 47f45d3.

⛔ Files ignored due to path filters (2)
  • go.sum is excluded by !**/*.sum
  • integration_tests/protocols/javascript/rsync-test.yaml is excluded by !**/*.yaml
📒 Files selected for processing (2)
  • cmd/integration-test/javascript.go (3 hunks)
  • go.mod (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • go.mod
🧰 Additional context used
🧬 Code graph analysis (1)
cmd/integration-test/javascript.go (1)
pkg/testutils/integration.go (2)
  • TestCase (247-250)
  • RunNucleiTemplateAndGetResults (30-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint
🔇 Additional comments (2)
cmd/integration-test/javascript.go (2)

18-18: Rsync JS testcase entry looks good.

Disabled on Windows/macOS consistent with other dockerized tests. No issues.


24-24: Resource handle addition is appropriate.

rsyncResource mirrors existing Redis/SSH patterns.

@dwisiswant0 dwisiswant0 added this to the v3.7.0-alpha.1 milestone Dec 23, 2025
Copy link
Member

@ehsandeep ehsandeep left a comment

Choose a reason for hiding this comment

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

merge conflict

@Mzack9999 Mzack9999 requested a review from ehsandeep December 25, 2025 13:51
@dwisiswant0 dwisiswant0 changed the title Adding RSYNC auth feat(js): adds RSYNC module Dec 31, 2025
@dwisiswant0 dwisiswant0 merged commit 891dffb into dev Dec 31, 2025
19 checks passed
@dwisiswant0 dwisiswant0 deleted the feat-6409-rsync-auth branch December 31, 2025 19:02
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.

[FEATURE] Authentication support in Javascript RSYNC Protocol

3 participants