| 57 | } |
| 58 | |
| 59 | private pathFor(name: string): string { |
| 60 | // Guard against path traversal: caller-provided names (from config.toml |
| 61 | // or slash commands) must not escape the credentials dir. `basename` |
| 62 | // strips any `..` or `/` segments; if the sanitized value differs from |
| 63 | // the input we refuse the request entirely rather than silently |
| 64 | // writing to a different file than the caller asked for. |
| 65 | const safe = basename(name); |
| 66 | if (safe.length === 0 || safe !== name || safe.startsWith('.')) { |
| 67 | throw new Error(`Invalid token name: "${name}"`); |
| 68 | } |
| 69 | return join(this.dir, `${safe}.json`); |
| 70 | } |
| 71 | |
| 72 | async load(name: string): Promise<TokenInfo | undefined> { |
| 73 | const file = this.pathFor(name); |