Skip to content

Commit d8b9d2e

Browse files
fix[faustwp-cli]: (#1850) detect HTTP Basic Auth and show accurate error (#2316)
* fix[faustwp-cli]: (#1850) detect HTTP Basic Auth and show accurate error When a WordPress site is protected with HTTP Basic Authentication, the secret key validation request returns 401 from the web server, not from FaustWP. The health check assumed any 401 meant the secret key was wrong, showing a misleading error message. Check the WWW-Authenticate response header for "Basic" to distinguish HTTP Basic Auth (web server) from a secret key mismatch (plugin). Show a specific error message telling the user their site has Basic Auth protection. Closes #1850 * fix[faustwp-cli]: move Basic Auth test inside describe block and format --------- Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
1 parent de53f5c commit d8b9d2e

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@faustwp/cli": patch
3+
---
4+
5+
fix[faustwp-cli]: detect HTTP Basic Auth on 401 response and show accurate error message instead of misleading secret key mismatch

packages/faustwp-cli/src/healthCheck/validateFaustEnvVars.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,19 @@ export const validateFaustEnvVars = async () => {
5858
method: 'POST',
5959
});
6060
if (response.status === 401) {
61-
// Unauthorized: User receives a 401 status code AND the message below
62-
errorLog(
63-
'Ensure your FAUST_SECRET_KEY environment variable matches your Secret Key in the Faust WordPress plugin settings',
64-
);
61+
const wwwAuth = response.headers.get('www-authenticate') || '';
62+
if (wwwAuth.toLowerCase().includes('basic')) {
63+
errorLog(
64+
'Your WordPress site appears to be protected with HTTP Basic Authentication.',
65+
);
66+
errorLog(
67+
'Faust cannot validate the secret key until Basic Auth credentials are provided or the protection is removed.',
68+
);
69+
} else {
70+
errorLog(
71+
'Ensure your FAUST_SECRET_KEY environment variable matches your Secret Key in the Faust WordPress plugin settings',
72+
);
73+
}
6574
process.exit(1);
6675
}
6776
await validateNextWordPressUrl();

packages/faustwp-cli/tests/healthCheck/validateFaustEnvVars.test.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,40 @@ describe('healthCheck/validateFaustEnvVars', () => {
7171
`Ensure your FAUST_SECRET_KEY environment variable matches your Secret Key in the Faust WordPress plugin settings`,
7272
);
7373
});
74+
75+
it('logs a Basic Auth error when the site returns 401 with WWW-Authenticate: Basic', async () => {
76+
// @ts-ignore
77+
const mockExit = jest.spyOn(process, 'exit').mockImplementation((code) => {
78+
if (code && code !== 0) {
79+
throw new Error(`Exit code: ${code}`);
80+
}
81+
});
82+
const mockLog = jest.spyOn(console, 'log').mockImplementation(() => {});
83+
84+
process.env.NEXT_PUBLIC_WORDPRESS_URL = 'https://basicauth.local';
85+
process.env.FAUST_SECRET_KEY = 'valid-secret-key';
86+
87+
fetchMock.post(
88+
'https://basicauth.local/?rest_route=/faustwp/v1/validate_secret_key',
89+
{
90+
status: 401,
91+
headers: { 'WWW-Authenticate': 'Basic realm="Restricted"' },
92+
},
93+
);
94+
95+
try {
96+
await validateFaustEnvVars();
97+
} catch (err) {
98+
// Expected exit
99+
}
100+
101+
expect(mockExit).toHaveBeenCalledWith(1);
102+
expect(mockLog).toHaveBeenCalledWith(
103+
expect.stringContaining('HTTP Basic Authentication'),
104+
);
105+
106+
mockLog.mockRestore();
107+
});
74108
});
75109

76110
describe('isWPEngineComTLD', () => {

0 commit comments

Comments
 (0)