MSSQL: loadEnvFile and MSSQL_URL parsing #320

Closed
opened 2026-11-10 08:19:35 +00:00 by david · 2 comments
Owner

Summary

Implement loadEnvFile() and MSSQL_URL parsing in extensions/mssql/env.ts.

Background

The extension reads connection info from .env in the working directory, as extensions/postgres/env.ts does (its loadEnvFile() uses dotenv and returns {} when .env is missing or unreadable, and its parseConnUrl uses new URL). The extension registers no tools when MSSQL_URL is absent. Blocked until the Stage 1 gate (#318) passes. TDD: write each test first. Never log the password or the full URL ([SECURITY RISK]); never hardcode credentials.

Depends on: #319

Implementation Details

In extensions/mssql/env.ts:

  • loadEnvFile(): Record<string,string> reads <process.cwd()>/.env with dotenv; missing or unreadable file returns {}.
  • A key lookup helper that matches env keys case-insensitively (as the postgres extension does for DATABASE_URL).
  • parseMssqlUrl(url: string): ConnInfo | null for mssql://user:pass@host:1433/db. ConnInfo = { host, port, database, user, password? }. Port defaults to 1433. Decode percent-encoded user/password (decodeURIComponent). Database is the path without the leading /. An invalid URL, wrong scheme (not mssql:), or missing host returns null. Password-less URLs give password: undefined.
  • Never include the password or the full URL in any returned error text or thrown message.

Acceptance Criteria

  • loadEnvFile() returns {} for a missing .env and the parsed values otherwise.
  • MSSQL_URL is found case-insensitively (mssql_url, Mssql_Url).
  • The default port is 1433 and an explicit port is honoured.
  • Percent-encoded credentials are decoded; a password-less URL gives undefined.
  • An invalid URL or wrong scheme returns null, and no output contains the password.

Test Plan

node --test extensions/mssql/env.test.ts: tests cover missing .env (temp dir with process.chdir), each key casing, default port, explicit port, encoded password (p%40ss), no password, garbage string, postgres:// scheme, and an assertion that the parser's failure output does not contain the password.

## Summary Implement `loadEnvFile()` and `MSSQL_URL` parsing in `extensions/mssql/env.ts`. ## Background The extension reads connection info from `.env` in the working directory, as `extensions/postgres/env.ts` does (its `loadEnvFile()` uses `dotenv` and returns `{}` when `.env` is missing or unreadable, and its `parseConnUrl` uses `new URL`). The extension registers no tools when `MSSQL_URL` is absent. **Blocked until the Stage 1 gate (#318) passes.** TDD: write each test first. Never log the password or the full URL ([SECURITY RISK]); never hardcode credentials. **Depends on:** #319 ## Implementation Details In `extensions/mssql/env.ts`: - `loadEnvFile(): Record<string,string>` reads `<process.cwd()>/.env` with `dotenv`; missing or unreadable file returns `{}`. - A key lookup helper that matches env keys case-insensitively (as the postgres extension does for `DATABASE_URL`). - `parseMssqlUrl(url: string): ConnInfo | null` for `mssql://user:pass@host:1433/db`. `ConnInfo = { host, port, database, user, password? }`. Port defaults to 1433. Decode percent-encoded user/password (`decodeURIComponent`). Database is the path without the leading `/`. An invalid URL, wrong scheme (not `mssql:`), or missing host returns `null`. Password-less URLs give `password: undefined`. - Never include the password or the full URL in any returned error text or thrown message. ## Acceptance Criteria - [ ] `loadEnvFile()` returns `{}` for a missing `.env` and the parsed values otherwise. - [ ] `MSSQL_URL` is found case-insensitively (`mssql_url`, `Mssql_Url`). - [ ] The default port is 1433 and an explicit port is honoured. - [ ] Percent-encoded credentials are decoded; a password-less URL gives `undefined`. - [ ] An invalid URL or wrong scheme returns `null`, and no output contains the password. ## Test Plan `node --test extensions/mssql/env.test.ts`: tests cover missing `.env` (temp dir with `process.chdir`), each key casing, default port, explicit port, encoded password (`p%40ss`), no password, garbage string, `postgres://` scheme, and an assertion that the parser's failure output does not contain the password.
Author
Owner

Update: the "Blocked until the Stage 1 gate (#318) passes" note is superseded. The gate resolved as STOP, and docs/adr/0002-mssql-read-only-credentials-with-minimal-guard.md replaced the parser design with read-only credentials, a minimal guard and a write-access warning. Stage 2 is unblocked. The scope of this issue is unchanged.

Update: the "Blocked until the Stage 1 gate (#318) passes" note is superseded. The gate resolved as STOP, and `docs/adr/0002-mssql-read-only-credentials-with-minimal-guard.md` replaced the parser design with read-only credentials, a minimal guard and a write-access warning. Stage 2 is unblocked. The scope of this issue is unchanged.
david closed this issue 2026-11-11 00:00:13 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #344

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/344
Sign in to join this conversation.
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
david/pi-extensions-and-skills#320
No description provided.