Feature: Init wizard should store credentials in .env file #23

Open
opened 2025-11-05 12:17:32 +00:00 by PhilflowIO · 0 comments
PhilflowIO commented 2025-11-05 12:17:32 +00:00 (Migrated from github.com)

Feature: Init wizard should store credentials in .env file

Problem

Currently, the init command creates a configuration file with credentials stored in plaintext:

{
  "source": {
    "credentials": {
      "username": "my-username",
      "password": "my-secret-password"
    }
  }
}

Issues with this approach:

  • Passwords visible in plaintext JSON files
  • Risk of accidentally committing credentials to version control
  • Not following industry best practices
  • Poor DX when sharing configs across teams

Proposed Solution

The init wizard should automatically create two files:

1. .env file (contains actual credentials)

SOURCE_USERNAME=my-username
SOURCE_PASSWORD=my-secret-password
TARGET_USERNAME=target-user
TARGET_PASSWORD=target-password

2. Config JSON (contains references)

{
  "source": {
    "credentials": {
      "username": "env:SOURCE_USERNAME",
      "password": "env:SOURCE_PASSWORD"
    }
  }
}

Implementation Details

Changes to init.ts:

  1. Collect credentials during wizard

    • Use inquirer with type: 'password' for hidden input
  2. Write to .env file

    const envContent = `
    # Source Provider Credentials
    SOURCE_USERNAME=${sourceUsername}
    SOURCE_PASSWORD=${sourcePassword}
    
    # Target Provider Credentials
    TARGET_USERNAME=${targetUsername}
    TARGET_PASSWORD=${targetPassword}
    `.trim();
    
    fs.writeFileSync('.env', envContent);
    
  3. Generate config with env references

    const config = {
      source: {
        credentials: {
          username: 'env:SOURCE_USERNAME',
          password: 'env:SOURCE_PASSWORD'
        }
      }
    };
    
  4. Update .gitignore

    • Add .env if not already present
    • Show warning to user
  5. Create .env.template

    # Copy this to .env and fill in your credentials
    SOURCE_USERNAME=
    SOURCE_PASSWORD=
    TARGET_USERNAME=
    TARGET_PASSWORD=
    

User Feedback:

✓ Configuration saved to: my-migration.json
✓ Credentials saved to: .env

⚠️  Important: Never commit .env to version control!
    The .env file has been added to .gitignore.

💡 Tip: Share .env.template with your team (without credentials)

Benefits

Security: Credentials never stored in JSON config
Git-safe: .env automatically ignored
Industry standard: Follows practices used by Next.js, Prisma, Supabase
Team-friendly: Each developer has their own .env
DX improvement: One-time credential entry

Examples from Other Tools

Next.js:

npx create-next-app
# Creates: .env.local

Prisma:

prisma init
# Creates: .env with DATABASE_URL

Supabase:

supabase init
# Creates: .env with API keys

Alternative Considered

Keep current behavior but add a --use-env flag:

dav-migrate init --use-env

However, this makes the secure approach opt-in rather than default, which is less ideal.

Suggested Labels

  • enhancement
  • security
  • cli
  • good first issue
# Feature: Init wizard should store credentials in .env file ## Problem Currently, the `init` command creates a configuration file with credentials stored in **plaintext**: ```json { "source": { "credentials": { "username": "my-username", "password": "my-secret-password" } } } ``` **Issues with this approach:** - ❌ Passwords visible in plaintext JSON files - ❌ Risk of accidentally committing credentials to version control - ❌ Not following industry best practices - ❌ Poor DX when sharing configs across teams ## Proposed Solution The `init` wizard should automatically create **two files**: ### 1. `.env` file (contains actual credentials) ```env SOURCE_USERNAME=my-username SOURCE_PASSWORD=my-secret-password TARGET_USERNAME=target-user TARGET_PASSWORD=target-password ``` ### 2. Config JSON (contains references) ```json { "source": { "credentials": { "username": "env:SOURCE_USERNAME", "password": "env:SOURCE_PASSWORD" } } } ``` ## Implementation Details ### Changes to `init.ts`: 1. **Collect credentials during wizard** - Use `inquirer` with `type: 'password'` for hidden input 2. **Write to `.env` file** ```typescript const envContent = ` # Source Provider Credentials SOURCE_USERNAME=${sourceUsername} SOURCE_PASSWORD=${sourcePassword} # Target Provider Credentials TARGET_USERNAME=${targetUsername} TARGET_PASSWORD=${targetPassword} `.trim(); fs.writeFileSync('.env', envContent); ``` 3. **Generate config with env references** ```typescript const config = { source: { credentials: { username: 'env:SOURCE_USERNAME', password: 'env:SOURCE_PASSWORD' } } }; ``` 4. **Update `.gitignore`** - Add `.env` if not already present - Show warning to user 5. **Create `.env.template`** ```env # Copy this to .env and fill in your credentials SOURCE_USERNAME= SOURCE_PASSWORD= TARGET_USERNAME= TARGET_PASSWORD= ``` ### User Feedback: ``` ✓ Configuration saved to: my-migration.json ✓ Credentials saved to: .env ⚠️ Important: Never commit .env to version control! The .env file has been added to .gitignore. 💡 Tip: Share .env.template with your team (without credentials) ``` ## Benefits ✅ **Security:** Credentials never stored in JSON config ✅ **Git-safe:** `.env` automatically ignored ✅ **Industry standard:** Follows practices used by Next.js, Prisma, Supabase ✅ **Team-friendly:** Each developer has their own `.env` ✅ **DX improvement:** One-time credential entry ## Examples from Other Tools **Next.js:** ```bash npx create-next-app # Creates: .env.local ``` **Prisma:** ```bash prisma init # Creates: .env with DATABASE_URL ``` **Supabase:** ```bash supabase init # Creates: .env with API keys ``` ## Alternative Considered Keep current behavior but add a `--use-env` flag: ```bash dav-migrate init --use-env ``` However, this makes the secure approach opt-in rather than default, which is less ideal. ## Suggested Labels - `enhancement` - `security` - `cli` - `good first issue`
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Phil/tsdav#23
No description provided.