Skip to content

Membase menu entry#1287

Merged
Oceania2018 merged 1 commit intoSciSharp:masterfrom
hchen2020:master
Feb 4, 2026
Merged

Membase menu entry#1287
Oceania2018 merged 1 commit intoSciSharp:masterfrom
hchen2020:master

Conversation

@hchen2020
Copy link
Contributor

@hchen2020 hchen2020 commented Feb 3, 2026

PR Type

Enhancement


Description

  • Add Membase integration to Knowledge Base plugin menu

  • Store Membase API credentials in plugin configuration

  • Embed Membase query editor in Relationships menu item

  • Add ProjectId setting to Membase configuration


Diagram Walkthrough

flowchart LR
  A["KnowledgeBasePlugin"] -->|reads config| B["Membase Settings"]
  B -->|ApiKey & ProjectId| C["AttachMenu"]
  C -->|creates| D["Relationships Menu Item"]
  D -->|embeds| E["Membase Query Editor"]
Loading

File Walkthrough

Relevant files
Enhancement
KnowledgeBasePlugin.cs
Add Membase credentials and embed query editor                     

src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs

  • Add private fields to store Membase API credentials and project ID
  • Load Membase configuration values in RegisterDI method
  • Update Relationships menu item with Membase query editor embedding
  • Configure EmbeddingInfo with iframe source and dynamic URL
+14/-1   
MembaseSettings.cs
Add ProjectId property to settings                                             

src/Plugins/BotSharp.Plugin.Membase/Settings/MembaseSettings.cs

  • Add ProjectId property to MembaseSettings class
  • Initialize ProjectId with empty string default value
+1/-0     

@qodo-code-review
Copy link

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🔴
Token in URL

Description: The Membase API key is embedded directly into an iframe URL as a token query parameter
(...{_membaseProjectId}?token={_membaseCredential}), which can leak via browser history,
server/access logs, referrer headers, and client-side inspection, enabling unauthorized
access if the token is captured.
KnowledgeBasePlugin.cs [32-52]

Referred Code
    _membaseCredential = config.GetValue<string>("Membase:ApiKey")!;
    _membaseProjectId = config.GetValue<string>("Membase:ProjectId")!;
}

public bool AttachMenu(List<PluginMenuDef> menu)
{
    var section = menu.First(x => x.Label == "Apps");
    menu.Add(new PluginMenuDef("Knowledge Base", icon: "bx bx-book-open", weight: section.Weight + 1)
    {
        Roles = new List<string> { UserRole.Root, UserRole.Admin, UserRole.Engineer },
        SubMenu = new List<PluginMenuDef>
        {
            new PluginMenuDef("Q & A", link: "page/knowledge-base/question-answer"),
            new PluginMenuDef("Relationships", link: "page/knowledge-base/relationships/membase")
            {
                EmbeddingInfo = new EmbeddingData
                {
                    Source = "membase",
                    HtmlTag = "iframe",
                    Url = $"http://console.membase.dev/query-editor/{_membaseProjectId}?token={_membaseCredential}"
                }
Insecure transport

Description: The iframe points to an http:// URL for the Membase console, allowing credential/token
exposure or content tampering via man-in-the-middle attacks if any traffic traverses an
untrusted network.
KnowledgeBasePlugin.cs [45-52]

Referred Code
new PluginMenuDef("Relationships", link: "page/knowledge-base/relationships/membase")
{
    EmbeddingInfo = new EmbeddingData
    {
        Source = "membase",
        HtmlTag = "iframe",
        Url = $"http://console.membase.dev/query-editor/{_membaseProjectId}?token={_membaseCredential}"
    }
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
🟢
Generic: Secure Error Handling

Objective: To prevent the leakage of sensitive system information through error messages while
providing sufficient detail for internal debugging.

Status: Passed

Learn more about managing compliance generic rules or creating your own custom rules

🔴
Generic: Robust Error Handling and Edge Case Management

Objective: Ensure comprehensive error handling that provides meaningful context and graceful
degradation

Status:
Missing config validation: The code forcefully reads Membase:ApiKey and Membase:ProjectId with null-forgiveness and
no validation/handling for missing or empty values, which can lead to runtime failures or
broken menu embedding.

Referred Code
    _membaseCredential = config.GetValue<string>("Membase:ApiKey")!;
    _membaseProjectId = config.GetValue<string>("Membase:ProjectId")!;
}

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Security-First Input Validation and Data Handling

Objective: Ensure all data inputs are validated, sanitized, and handled securely to prevent
vulnerabilities

Status:
API key exposure: The code transmits the Membase API key to the browser by placing it in an iframe URL (and
over http), exposing a secret to end-users and enabling leakage via URL sharing,
referrers, and network interception.

Referred Code
new PluginMenuDef("Relationships", link: "page/knowledge-base/relationships/membase")
{
    EmbeddingInfo = new EmbeddingData
    {
        Source = "membase",
        HtmlTag = "iframe",
        Url = $"http://console.membase.dev/query-editor/{_membaseProjectId}?token={_membaseCredential}"
    }

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Meaningful Naming and Self-Documenting Code

Objective: Ensure all identifiers clearly express their purpose and intent, making code
self-documenting

Status:
Ambiguous secret name: The new field name _membaseCredential is ambiguous and does not clearly communicate that
it stores an API key/token used for authentication.

Referred Code
private string _membaseCredential = string.Empty;
private string _membaseProjectId = string.Empty;

Learn more about managing compliance generic rules or creating your own custom rules

Generic: Secure Logging Practices

Objective: To ensure logs are useful for debugging and auditing without exposing sensitive
information like PII, PHI, or cardholder data.

Status:
Secret in URL: The API key is embedded into the iframe Url query string, which is likely to be captured
by client/server/proxy logs and referrers depending on surrounding infrastructure.

Referred Code
new PluginMenuDef("Relationships", link: "page/knowledge-base/relationships/membase")
{
    EmbeddingInfo = new EmbeddingData
    {
        Source = "membase",
        HtmlTag = "iframe",
        Url = $"http://console.membase.dev/query-editor/{_membaseProjectId}?token={_membaseCredential}"
    }

Learn more about managing compliance generic rules or creating your own custom rules

Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

@qodo-code-review
Copy link

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Security
Avoid exposing API key in client-side URL

To fix a critical security vulnerability, change the URL to use https and
implement a backend proxy to avoid exposing the API key in the client-side
iframe URL.

src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs [51]

-Url = $"http://console.membase.dev/query-editor/{_membaseProjectId}?token={_membaseCredential}"
+Url = $"https://console.membase.dev/query-editor/{_membaseProjectId}" 
+// TODO: The API key should be passed securely from a backend proxy, not in the URL.
+// For example, the iframe could point to a local endpoint like "/api/membase-proxy"
+// which handles authentication on the server-side.
  • Apply / Chat
Suggestion importance[1-10]: 10

__

Why: The suggestion correctly identifies a critical security vulnerability where an API key is exposed on the client-side and transmitted over an insecure http connection, proposing a robust architectural solution.

High
Possible issue
Fail fast on missing config

Add explicit null or empty checks for Membase:ApiKey and Membase:ProjectId from
the configuration, and throw a descriptive exception if they are missing.

src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs [32-33]

-_membaseCredential = config.GetValue<string>("Membase:ApiKey")!;
-_membaseProjectId = config.GetValue<string>("Membase:ProjectId")!;
+var apiKey = config.GetValue<string>("Membase:ApiKey");
+if (string.IsNullOrEmpty(apiKey))
+    throw new InvalidOperationException("Membase ApiKey configuration is missing.");
+_membaseCredential = apiKey;
+var projectId = config.GetValue<string>("Membase:ProjectId");
+if (string.IsNullOrEmpty(projectId))
+    throw new InvalidOperationException("Membase ProjectId configuration is missing.");
+_membaseProjectId = projectId;
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: The suggestion improves robustness by adding explicit validation for required configuration values, providing clearer error messages on misconfiguration instead of relying on the null-forgiving operator.

Low
Learned
best practice
Avoid throwing on missing items

Use FirstOrDefault (and handle null) so the plugin doesn't throw if the "Apps"
section is absent or renamed.

src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs [38]

-var section = menu.First(x => x.Label == "Apps");
+var section = menu.FirstOrDefault(x => x.Label == "Apps");
+if (section is null) return false;

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 6

__

Why:
Relevant best practice - Add explicit null/empty guards before indexing/enumerating to avoid throwing when expected items are missing.

Low
General
Use typed options binding

Refactor configuration loading to use the typed IOptions pattern instead of
manually calling IConfiguration.GetValue.

src/Plugins/BotSharp.Plugin.KnowledgeBase/KnowledgeBasePlugin.cs [32-33]

-_membaseCredential = config.GetValue<string>("Membase:ApiKey")!;
-_membaseProjectId = config.GetValue<string>("Membase:ProjectId")!;
+services.Configure<MembaseSettings>(config.GetSection("Membase"));
+...
+var membaseSettings = provider.GetRequiredService<IOptions<MembaseSettings>>().Value;
+_membaseCredential = membaseSettings.ApiKey;
+_membaseProjectId = membaseSettings.ProjectId;

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 5

__

Why: The suggestion proposes using the Options pattern for configuration, which is a good practice for consistency and testability, but it introduces a dependency on MembaseSettings in a different plugin.

Low
  • More

@Oceania2018 Oceania2018 merged commit 920f75d into SciSharp:master Feb 4, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants