Skip to content

Commit 422cdac

Browse files
committed
Validate username
1 parent 1bba9db commit 422cdac

File tree

5 files changed

+39
-2
lines changed

5 files changed

+39
-2
lines changed

index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ const wpDeployer = async () => {
8181
console.error(chalk.red('Username is required.'))
8282
return EXIT_CONFIG
8383
}
84+
if (error === 'invalid_username') {
85+
console.error(chalk.red(errorMessage || 'Invalid username.'))
86+
return EXIT_CONFIG
87+
}
8488
if (error === 'theme_earlier_version_required') {
8589
console.error(chalk.red('For repoType theme, earlierVersion is required.'))
8690
return EXIT_CONFIG

lib/config.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function getDefaults (pkg) {
3838
/**
3939
* Resolve settings from package.json. Does not exit; returns an error key if validation fails.
4040
* @param {object} pkg - Parsed package.json (must have name, version)
41-
* @returns {{ settings: object, error: null | 'invalid_slug' | 'username_required' | 'theme_earlier_version_required' | 'invalid_config' | 'invalid_svn_url' | 'invalid_new_version' | 'invalid_earlier_version', errorMessage?: string }}
41+
* @returns {{ settings: object, error: null | 'invalid_slug' | 'username_required' | 'invalid_username' | 'theme_earlier_version_required' | 'invalid_config' | 'invalid_svn_url' | 'invalid_new_version' | 'invalid_earlier_version', errorMessage?: string }}
4242
*/
4343
export function resolveSettings (pkg) {
4444
const defaults = getDefaults(pkg)
@@ -92,6 +92,15 @@ export function resolveSettings (pkg) {
9292
}
9393
}
9494

95+
// Username is interpolated into shell commands; allow only safe chars (WordPress.org style)
96+
if (!/^[a-zA-Z0-9_-]+$/.test(settings.username)) {
97+
return {
98+
settings,
99+
error: 'invalid_username',
100+
errorMessage: 'username must contain only letters, numbers, hyphens, and underscores (typical WordPress.org username).'
101+
}
102+
}
103+
95104
if (
96105
settings.repoType === 'plugin' &&
97106
settings.deployTag === true &&

lib/preflight.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* Pre-deploy checks: required tools on PATH, build/assets directories.
33
*/
44

5-
import path from 'path'
5+
import path from 'node:path'
66
import { execSync } from 'child_process'
77
import { DeployError } from './deploy-error.js'
88
import { EXIT_CONFIG } from './exit-codes.js'

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@
2929
"url": "https://github.com/ernilambar/wp-deployer/issues"
3030
},
3131
"homepage": "https://github.com/ernilambar/wp-deployer#readme",
32+
"files": [
33+
"index.js",
34+
"lib",
35+
"README.md"
36+
],
3237
"dependencies": {
3338
"ajv": "^8.18.0",
3439
"chalk": "^5.6.2",

test/config.test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,25 @@ describe('resolveSettings', () => {
5757
assert.strictEqual(settings.username, 'jane')
5858
})
5959

60+
it('returns invalid_username when username contains disallowed characters', () => {
61+
const withSpace = resolveSettings({ ...basePkg, wpDeployer: { username: 'jane doe' } })
62+
assert.strictEqual(withSpace.error, 'invalid_username')
63+
assert.ok(withSpace.errorMessage && /letters, numbers, hyphens, and underscores/.test(withSpace.errorMessage))
64+
65+
const withQuote = resolveSettings({ ...basePkg, wpDeployer: { username: 'jane"doe' } })
66+
assert.strictEqual(withQuote.error, 'invalid_username')
67+
68+
const withSemicolon = resolveSettings({ ...basePkg, wpDeployer: { username: 'jane;rm' } })
69+
assert.strictEqual(withSemicolon.error, 'invalid_username')
70+
})
71+
72+
it('accepts username with only alphanumeric, hyphen, and underscore', () => {
73+
assert.strictEqual(resolveSettings({ ...basePkg, wpDeployer: { username: 'jane' } }).error, null)
74+
assert.strictEqual(resolveSettings({ ...basePkg, wpDeployer: { username: 'jane_doe' } }).error, null)
75+
assert.strictEqual(resolveSettings({ ...basePkg, wpDeployer: { username: 'jane-doe-99' } }).error, null)
76+
assert.strictEqual(resolveSettings({ ...basePkg, wpDeployer: { username: 'User123' } }).error, null)
77+
})
78+
6079
it('defaults url to plugins.svn.wordpress.org for plugin', () => {
6180
const pkg = { ...basePkg, wpDeployer: { username: 'jane' } }
6281
const { settings } = resolveSettings(pkg)

0 commit comments

Comments
 (0)