From 6a70ba8895f4b061c16fc423644c7f452cd0f2d4 Mon Sep 17 00:00:00 2001 From: Princi Vershwal Date: Thu, 28 Nov 2024 17:43:59 +0530 Subject: [PATCH] Moved staff2fa flag to BETA_FEATURES (#21749) Closes https://linear.app/ghost/issue/ENG-1800/move-staff2fa-to-beta-features-and-disable-developer-experiments Currently we have this flag in ALPHA_FEATURES. We want to enable 2fa for selected sites but we would want to disable developer experiments for them, so they don't see the UI and enable random things. --- .../settings/advanced/labs/AlphaFeatures.tsx | 4 -- ghost/core/core/shared/labs.js | 6 +-- ghost/core/test/e2e-browser/admin/2fa.spec.js | 43 ++++++++++++++----- .../test/e2e-browser/portal/invites.spec.js | 31 +++++++------ 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/apps/admin-x-settings/src/components/settings/advanced/labs/AlphaFeatures.tsx b/apps/admin-x-settings/src/components/settings/advanced/labs/AlphaFeatures.tsx index e640d587b5..fc43043012 100644 --- a/apps/admin-x-settings/src/components/settings/advanced/labs/AlphaFeatures.tsx +++ b/apps/admin-x-settings/src/components/settings/advanced/labs/AlphaFeatures.tsx @@ -59,10 +59,6 @@ const features = [{ title: 'Comment Improvements', description: 'Enables new comment features', flag: 'commentImprovements' -}, { - title: 'Staff 2FA', - description: 'Enables email verification for staff logins', - flag: 'staff2fa' }]; const AlphaFeatures: React.FC = () => { diff --git a/ghost/core/core/shared/labs.js b/ghost/core/core/shared/labs.js index c25f7c0115..a4d350e3c0 100644 --- a/ghost/core/core/shared/labs.js +++ b/ghost/core/core/shared/labs.js @@ -32,7 +32,8 @@ const BETA_FEATURES = [ 'editorExcerpt', 'ActivityPub', 'importMemberTier', - 'customFonts' + 'customFonts', + 'staff2fa' ]; const ALPHA_FEATURES = [ @@ -45,8 +46,7 @@ const ALPHA_FEATURES = [ 'lexicalIndicators', 'adminXDemo', 'contentVisibility', - 'commentImprovements', - 'staff2fa' + 'commentImprovements' ]; module.exports.GA_KEYS = [...GA_FEATURES]; diff --git a/ghost/core/test/e2e-browser/admin/2fa.spec.js b/ghost/core/test/e2e-browser/admin/2fa.spec.js index f474051e8f..e422249597 100644 --- a/ghost/core/test/e2e-browser/admin/2fa.spec.js +++ b/ghost/core/test/e2e-browser/admin/2fa.spec.js @@ -8,22 +8,43 @@ test.describe('2FA', () => { await sharedPage.goto('/ghost'); await sharedPage.locator('.gh-nav a[href="#/settings/"]').click(); - const section = sharedPage.getByTestId('labs'); - await section.getByRole('button', {name: 'Open'}).click(); + // Make an API call to get settings + const adminUrl = new URL(sharedPage.url()).origin + '/ghost'; + const settingsResponse = await sharedPage.request.get(`${adminUrl}/api/admin/settings/`); + const settingsData = await settingsResponse.json(); + // Add staff2fa flag to labs settings + const settings = settingsData.settings; + const labsSetting = settings.find(s => s.key === 'labs'); + const labsValue = JSON.parse(labsSetting.value); + labsValue.staff2fa = true; + labsSetting.value = JSON.stringify(labsValue); - await section.getByRole('tab', {name: 'Alpha features'}).click(); - await section.getByLabel('Staff 2FA').click(); + // Update settings + await sharedPage.request.put(`${adminUrl}/api/admin/settings/`, { + data: { + settings + } + }); }); test.afterAll(async ({sharedPage}) => { - await sharedPage.goto('/ghost'); - await sharedPage.locator('.gh-nav a[href="#/settings/"]').click(); + // Make an API call to get settings + const adminUrl = new URL(sharedPage.url()).origin + '/ghost'; + const settingsResponse = await sharedPage.request.get(`${adminUrl}/api/admin/settings/`); + const settingsData = await settingsResponse.json(); + // Remove staff2fa flag from labs settings + const settings = settingsData.settings; + const labsSetting = settings.find(s => s.key === 'labs'); + const labsValue = JSON.parse(labsSetting.value); + delete labsValue.staff2fa; + labsSetting.value = JSON.stringify(labsValue); - const section = sharedPage.getByTestId('labs'); - await section.getByRole('button', {name: 'Open'}).click(); - - await section.getByRole('tab', {name: 'Alpha features'}).click(); - await section.getByLabel('Staff 2FA').click(); + // Update settings + await sharedPage.request.put(`${adminUrl}/api/admin/settings/`, { + data: { + settings + } + }); }); test('Logging in with 2FA works', async ({page, verificationToken}) => { diff --git a/ghost/core/test/e2e-browser/portal/invites.spec.js b/ghost/core/test/e2e-browser/portal/invites.spec.js index 8375044d1f..b2fb20ebf8 100644 --- a/ghost/core/test/e2e-browser/portal/invites.spec.js +++ b/ghost/core/test/e2e-browser/portal/invites.spec.js @@ -69,24 +69,30 @@ test.describe('Portal', () => { }); test.describe('2FA invite test', () => { - test.beforeEach(async ({sharedPage}) => { - // Enable 2FA - await sharedPage.goto('/ghost'); - await sharedPage.locator('[data-test-nav="settings"]').click(); - - const section = sharedPage.getByTestId('labs'); - await section.getByRole('button', {name: 'Open'}).click(); - - await section.getByRole('tab', {name: 'Alpha features'}).click(); - await section.getByLabel('Staff 2FA').click(); - }); - test('New staff member can signup using an invite link with 2FA enabled', async ({sharedPage}) => { // Navigate to settings await sharedPage.goto('/ghost'); await sharedPage.locator('[data-test-nav="settings"]').click(); await sharedPage.waitForLoadState('networkidle'); + // Make an API call to get settings + const adminUrl = new URL(sharedPage.url()).origin + '/ghost'; + const settingsResponse = await sharedPage.request.get(`${adminUrl}/api/admin/settings/`); + const settingsData = await settingsResponse.json(); + // Add staff2fa flag to labs settings + const settings = settingsData.settings; + const labsSetting = settings.find(s => s.key === 'labs'); + const labsValue = JSON.parse(labsSetting.value); + labsValue.staff2fa = true; + labsSetting.value = JSON.stringify(labsValue); + + // Update settings + await sharedPage.request.put(`${adminUrl}/api/admin/settings/`, { + data: { + settings + } + }); + const testEmail = 'test@gmail.com'; // Send the invitation @@ -115,7 +121,6 @@ test.describe('Portal', () => { const token = invite.get('token'); // Construct the invite URL - const adminUrl = new URL(sharedPage.url()).origin + '/ghost'; const encodedToken = security.url.encodeBase64(token); const inviteUrl = `${adminUrl}/signup/${encodedToken}/`; const context = await sharedPage.context();