Compare commits

..

3 Commits

Author SHA1 Message Date
itsababseh
4f4d0d8ee9 fix(frontend): add AutoGPT to password reset email title 2025-08-20 02:28:19 +01:00
Abhimanyu Yadav
0c09b0c459 chore(api): remove launch darkly feature flags from api key endpoints (#10694)
Some API key endpoints have the Launch Darkly feature flag enabled,
while others don’t. To ensure consistency and remove the API key flag
from the Launch Darkly dashboard, I’m also removing it from the left
endpoints.

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  - [x] Everything is working fine locally
2025-08-19 17:10:43 +00:00
Abhimanyu Yadav
1105e6c0d2 tests(frontend): e2e tests for api key page (#10683)
I’ve added three tests for the API keys page:

- The test checks if the user is redirected to the login page when
they’re not authenticated.
- The test verifies that a new API key is created successfully.
- The test ensures that an existing API key can be revoked.

<img width="470" height="143" alt="Screenshot 2025-08-19 at 10 56 19 AM"
src="https://github.com/user-attachments/assets/d27bf736-61ec-435b-a6c4-820e4f3a5e2f"
/>

I’ve also removed the feature flag from the `delete_api_key` endpoint,
so we can use it on CI and in the local environment.

### Checklist 📋
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
  - [x] tests are working perfectly locally.

---------

Co-authored-by: Ubbe <hi@ubbe.dev>
2025-08-19 16:04:15 +00:00
4 changed files with 72 additions and 6 deletions

View File

@@ -1071,7 +1071,6 @@ async def get_api_key(
tags=["api-keys"],
dependencies=[Depends(auth_middleware)],
)
@feature_flag("api-keys-enabled")
async def delete_api_key(
key_id: str, user_id: Annotated[str, Depends(get_user_id)]
) -> Optional[APIKeyWithoutHash]:
@@ -1100,7 +1099,6 @@ async def delete_api_key(
tags=["api-keys"],
dependencies=[Depends(auth_middleware)],
)
@feature_flag("api-keys-enabled")
async def suspend_key(
key_id: str, user_id: Annotated[str, Depends(get_user_id)]
) -> Optional[APIKeyWithoutHash]:
@@ -1126,7 +1124,6 @@ async def suspend_key(
tags=["api-keys"],
dependencies=[Depends(auth_middleware)],
)
@feature_flag("api-keys-enabled")
async def update_permissions(
key_id: str,
request: UpdatePermissionsRequest,

View File

@@ -44,9 +44,9 @@ export function APIKeysSection() {
</TableHeader>
<TableBody>
{apiKeys.map((key) => (
<TableRow key={key.id}>
<TableRow key={key.id} data-testid="api-key-row">
<TableCell>{key.name}</TableCell>
<TableCell>
<TableCell data-testid="api-key-id">
<div className="rounded-md border p-1 px-2 text-xs">
{`${key.prefix}******************${key.postfix}`}
</div>
@@ -76,7 +76,11 @@ export function APIKeysSection() {
<TableCell>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size="sm">
<Button
data-testid="api-key-actions"
variant="ghost"
size="sm"
>
<MoreVertical className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>

View File

@@ -28,6 +28,7 @@ export async function sendResetEmail(email: string, turnstileToken: string) {
const { error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: `${origin}/api/auth/callback/reset-password`,
data: { title: "AutoGPT Reset Password" },
});
if (error) {

View File

@@ -0,0 +1,64 @@
import { expect, test } from "@playwright/test";
import { LoginPage } from "./pages/login.page";
import { TEST_CREDENTIALS } from "./credentials";
import { hasUrl } from "./utils/assertion";
import { getSelectors } from "./utils/selectors";
test.describe("API Keys Page", () => {
test.beforeEach(async ({ page }) => {
const loginPage = new LoginPage(page);
await page.goto("/login");
await loginPage.login(TEST_CREDENTIALS.email, TEST_CREDENTIALS.password);
await hasUrl(page, "/marketplace");
});
test("should redirect to login page when user is not authenticated", async ({
browser,
}) => {
const context = await browser.newContext();
const page = await context.newPage();
try {
await page.goto("/profile/api_keys");
await hasUrl(page, "/login");
} finally {
await page.close();
await context.close();
}
});
test("should create a new API key successfully", async ({ page }) => {
const { getButton, getField } = getSelectors(page);
await page.goto("/profile/api_keys");
await getButton("Create Key").click();
await getField("Name").fill("Test Key");
await getButton("Create").click();
await expect(
page.getByText("AutoGPT Platform API Key Created"),
).toBeVisible();
await getButton("Close").first().click();
await expect(page.getByText("Test Key").first()).toBeVisible();
});
test("should revoke an existing API key", async ({ page }) => {
const { getRole, getId } = getSelectors(page);
await page.goto("/profile/api_keys");
const apiKeyRow = getId("api-key-row").first();
const apiKeyContent = await apiKeyRow
.getByTestId("api-key-id")
.textContent();
const apiKeyActions = apiKeyRow.getByTestId("api-key-actions").first();
await apiKeyActions.click();
await getRole("menuitem", "Revoke").click();
await expect(
page.getByText("AutoGPT Platform API key revoked successfully"),
).toBeVisible();
await expect(page.getByText(apiKeyContent!)).not.toBeVisible();
});
});