Skip to content

feat: implement optional SMTP password support#91

Merged
utkarsh232005 merged 2 commits into
KDM-cli:mainfrom
utkarsh232005:fix/smtp-password-support
May 25, 2026
Merged

feat: implement optional SMTP password support#91
utkarsh232005 merged 2 commits into
KDM-cli:mainfrom
utkarsh232005:fix/smtp-password-support

Conversation

@utkarsh232005
Copy link
Copy Markdown
Member

@utkarsh232005 utkarsh232005 commented May 24, 2026

Closes #74

Description

This PR implements optional SMTP password support across the configuration schema, interactive setup flow, and user-facing text in src/utils/config.ts and src/commands/config.ts.

Changes

  • Configuration & Utils:
    • Added the optional email_password property to KDMConfig.
    • Updated clearNotificationCredentials() to delete email_password when resetting/switching provider credentials.
    • Updated getSMTPSettings() to prioritize process.env.KDM_SMTP_PASSWORD and fall back to email_password.
  • Command & UI:
    • Added an optional prompt for SMTP password during setup (can be skipped by pressing Enter).
    • Updated guides and list commands to clarify option to configure SMTP password in config or env var.
  • Tests:
    • Added tests to cover the new prompting and conditional saving flow in config.test.ts.
    • Added a new config-utils.test.ts to test clean retrieval logic.

Summary by CodeRabbit

  • New Features

    • Email setup now allows entering an optional SMTP password; env var still can be used.
  • Bug Fixes

    • Clearing notification credentials also removes any stored SMTP password.
    • SMTP password preference: environment variable takes precedence, otherwise stored password is used.
  • Tests

    • Expanded tests covering SMTP password saving, omission, validation, and env-var precedence.

Review Change Stack

Copilot AI review requested due to automatic review settings May 24, 2026 07:01
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 24, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 89327984-53e0-4d2c-9fe4-569aef934628

📥 Commits

Reviewing files that changed from the base of the PR and between 2187072 and aadcd6c.

📒 Files selected for processing (2)
  • src/__tests__/config-utils.test.ts
  • src/utils/config.ts

📝 Walkthrough

Walkthrough

This PR adds optional SMTP password storage to KDM's configuration system with environment-variable precedence. The interactive config setup flow prompts for an optional password, credential clearing and config types are updated, and tests cover precedence and persistence behavior.

Changes

SMTP Password Configuration Support

Layer / File(s) Summary
Config contract and credential management
src/utils/config.ts
KDMConfig adds optional email_password; clearNotificationCredentials() now deletes email_password alongside other notification credentials.
SMTP settings precedence logic
src/utils/config.ts
getSMTPSettings() resolves SMTP auth.pass by preferring process.env.KDM_SMTP_PASSWORD and falling back to config.get('email_password').
Interactive setup prompt and messaging
src/commands/config.ts
Email setup adds an optional SMTP Password prompt that conditionally persists email_password only when non-empty; config listing and guide text updated to state env-var precedence.
Integration tests for setup flow
src/__tests__/config.test.ts
Tests verify email setup with empty password (not persisted), non-empty password (persisted), and SMTP host/password prompt validation behavior.
Unit tests for config utilities
src/__tests__/config-utils.test.ts
Mock-based tests add a Map-backed conf mock; verify clearNotificationCredentials() deletes email_password and getSMTPSettings() honors env-var precedence and empty-string handling.

Sequence Diagram

sequenceDiagram
  participant User
  participant ConfigSetup as ConfigSetup
  participant ConfigStore as ConfigStore
  participant getSMTPSettings as getSMTPSettings()
  participant SMTPAuth as SMTPAuth

  User->>ConfigSetup: provide SMTP password (or leave empty)
  ConfigSetup->>ConfigStore: conditionally setConfig('email_password', pass)
  Note over ConfigStore: persists only if non-empty

  User->>getSMTPSettings: request SMTP credentials
  getSMTPSettings->>getSMTPSettings: check process.env.KDM_SMTP_PASSWORD
  alt env var defined
    getSMTPSettings->>SMTPAuth: use KDM_SMTP_PASSWORD
  else env var undefined
    getSMTPSettings->>ConfigStore: config.get('email_password')
    ConfigStore->>SMTPAuth: return stored password
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • KDM-cli/kdm-cli#23: Modifies the same config.ts and config.test.ts files for SMTP credential setup guidance and messaging.
  • KDM-cli/kdm-cli#14: Related earlier interactive notification setup changes that touch src/utils/config.ts and src/commands/config.ts.

Suggested reviewers

  • Rishiraj-Pathak-27

Poem

🔐 A prompt for secrets, gentle and neat,
Env vars first, config keeps the seat,
Empty left blank, non-empty preserved,
Tests confirm the order well observed. 🎯

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: implementing optional SMTP password support across config, setup flow, and utilities.
Linked Issues check ✅ Passed All coding requirements from issue #74 are met: optional SMTP password prompt during setup, environment variable fallback support, and conditional persistence of credentials.
Out of Scope Changes check ✅ Passed All changes are directly scoped to issue #74: SMTP password prompting, config storage, environment variable support, and corresponding test coverage.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📋 Issue Planner

Built with CodeRabbit's Coding Plans for faster development and fewer bugs.

View plan used: #74

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Implements optional SMTP password support in the CLI by extending the config schema, updating the interactive config setup flow, and adding tests to cover password precedence and persistence behavior.

Changes:

  • Add email_password to config, ensure it’s cleared with other notification credentials, and allow getSMTPSettings() to fall back to it when KDM_SMTP_PASSWORD is not set.
  • Prompt for an optional SMTP password during kdm config setup and update user-facing guidance text.
  • Add/extend Vitest coverage for setup prompting and SMTP password precedence.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/utils/config.ts Adds email_password to config and uses it as a fallback for SMTP auth.
src/commands/config.ts Prompts for optional SMTP password and updates CLI guide/list messaging.
src/tests/config.test.ts Extends setup flow tests to cover password being skipped or saved.
src/tests/config-utils.test.ts Adds tests for credential clearing and env-var vs config precedence.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/utils/config.ts
Comment on lines 32 to 40
@@ -34,7 +36,7 @@ export const getSMTPSettings = () => {
port: config.get('email_port') || 587,
auth: {
user: config.get('email_user'),
pass: process.env.KDM_SMTP_PASSWORD,
pass: process.env.KDM_SMTP_PASSWORD || config.get('email_password'),
},
Comment thread src/commands/config.ts
Comment on lines 126 to +130
});
}

console.log(chalk.gray('──────────────────────────────────────────────────'));
console.log(chalk.dim('\n Note: SMTP passwords must be set via KDM_SMTP_PASSWORD env var.\n'));
console.log(chalk.dim('\n Note: SMTP password can be set either in config or via the KDM_SMTP_PASSWORD environment variable, which takes precedence if both are set.\n'));
Copy link
Copy Markdown
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: 3

🤖 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 `@src/__tests__/config-utils.test.ts`:
- Around line 70-86: Add a third case to the getSMTPSettings() test to assert
strict environment-variable precedence when KDM_SMTP_PASSWORD is an empty
string: set process.env.KDM_SMTP_PASSWORD = '' (after setting mockConfigStore
email_password) then call getSMTPSettings() and expect settings.auth.pass to
equal '' (not the config value). Ensure you restore or delete the env var
between cases so the other two assertions still run; reference the test around
getSMTPSettings and mockConfigStore.set('email_password', ...) when adding this
assertion.

In `@src/utils/config.ts`:
- Line 10: The config field email_password should not be persisted in
plain-text; remove or stop writing email_password to the persistent conf storage
and instead read it from an environment variable or secure OS keychain at
runtime (reference the email_password property in src/utils/config.ts). If
persistence is absolutely required add an explicit opt-in flag (e.g.,
persistEmailPassword) and store only an encrypted blob or a protected reference,
and update documentation and any README to warn about the risk; ensure code
paths that previously read/write email_password now pull from process.env or the
keychain API and that any new opt-in is clearly gated and logged.
- Line 39: Replace the falsy-OR fallback for the SMTP password so an
intentionally set empty KDM_SMTP_PASSWORD is honored; instead of using
"process.env.KDM_SMTP_PASSWORD || config.get('email_password')" update the
assignment for the pass property to use an explicit undefined check (e.g.,
process.env.KDM_SMTP_PASSWORD !== undefined ? process.env.KDM_SMTP_PASSWORD :
config.get('email_password')) so env takes strict precedence even when empty.
🪄 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: ASSERTIVE

Plan: Pro Plus

Run ID: ef3ef831-f6bb-40d3-8abd-137c078791fe

📥 Commits

Reviewing files that changed from the base of the PR and between 82248c0 and 2187072.

📒 Files selected for processing (4)
  • src/__tests__/config-utils.test.ts
  • src/__tests__/config.test.ts
  • src/commands/config.ts
  • src/utils/config.ts

Comment thread src/__tests__/config-utils.test.ts
Comment thread src/utils/config.ts
email_port?: number;
email_user?: string;
email_to?: string;
email_password?: string;
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.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Avoid storing SMTP password in plain-text config storage.

Persisting email_password in conf creates a secret-at-rest risk. Prefer env-only or secure OS keychain storage; if persistence is required, gate it behind explicit opt-in and document the risk clearly.

As per coding guidelines "Verify that sensitive information is not stored in plain text if possible."

🤖 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 `@src/utils/config.ts` at line 10, The config field email_password should not
be persisted in plain-text; remove or stop writing email_password to the
persistent conf storage and instead read it from an environment variable or
secure OS keychain at runtime (reference the email_password property in
src/utils/config.ts). If persistence is absolutely required add an explicit
opt-in flag (e.g., persistEmailPassword) and store only an encrypted blob or a
protected reference, and update documentation and any README to warn about the
risk; ensure code paths that previously read/write email_password now pull from
process.env or the keychain API and that any new opt-in is clearly gated and
logged.

Comment thread src/utils/config.ts Outdated
@utkarsh232005 utkarsh232005 merged commit 2ec4428 into KDM-cli:main May 25, 2026
3 checks passed
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.

enhancement:kdm config setup smtp should have password input aswell

2 participants