feat: rebrand Hemmelig to paste.es for cloudhost.es
- Set Spanish as default language with ephemeral/encrypted privacy focus - Translate all user-facing strings and legal pages to Spanish - Replace Norwegian flag with Spanish flag in footer - Remove Hemmelig/terces.cloud links, add cloudhost.es sponsorship - Rewrite PrivacyPage: zero data collection, ephemeral design emphasis - Rewrite TermsPage: Spanish law, RGPD, paste.es/CloudHost.es references - Update PWA manifest, HTML meta tags, package.json branding - Rename webhook headers to X-Paste-Event / X-Paste-Signature - Update API docs title and contact to paste.es / cloudhost.es Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
124
tests/e2e/password-change.spec.ts
Normal file
124
tests/e2e/password-change.spec.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { expect, test } from '@playwright/test';
|
||||
import { TEST_USER } from './global-setup';
|
||||
|
||||
const WEAK_PASSWORD_USER = {
|
||||
email: 'weakpass@hemmelig.local',
|
||||
username: 'weakpassuser',
|
||||
password: 'pass',
|
||||
name: 'Weak Password User',
|
||||
};
|
||||
|
||||
const NEW_STRONG_PASSWORD = 'NewStrongPass123!';
|
||||
|
||||
/**
|
||||
* Helper: sign in via the better-auth API and return session cookies.
|
||||
*/
|
||||
async function signInViaAPI(
|
||||
baseURL: string,
|
||||
email: string,
|
||||
password: string
|
||||
): Promise<{ cookie: string }> {
|
||||
const res = await fetch(`${baseURL}/api/auth/sign-in/email`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Origin: baseURL,
|
||||
},
|
||||
body: JSON.stringify({ email, password }),
|
||||
redirect: 'manual',
|
||||
});
|
||||
|
||||
const setCookieHeaders = res.headers.getSetCookie();
|
||||
const cookie = setCookieHeaders
|
||||
.map((c) => c.split(';')[0])
|
||||
.filter(Boolean)
|
||||
.join('; ');
|
||||
|
||||
return { cookie };
|
||||
}
|
||||
|
||||
test.describe('Password Change', () => {
|
||||
test.beforeAll(async ({}, testInfo) => {
|
||||
const baseURL = testInfo.project.use.baseURL || 'http://localhost:5173';
|
||||
|
||||
// Sign in as admin to get session cookies
|
||||
const { cookie: adminCookie } = await signInViaAPI(
|
||||
baseURL,
|
||||
TEST_USER.email,
|
||||
TEST_USER.password
|
||||
);
|
||||
|
||||
// Use better-auth admin endpoint to create a user with a weak password.
|
||||
// This bypasses the sign-up hook (which only runs on /sign-up/email),
|
||||
// and since minPasswordLength is 1, better-auth accepts it.
|
||||
const createRes = await fetch(`${baseURL}/api/auth/admin/create-user`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Origin: baseURL,
|
||||
Cookie: adminCookie,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: WEAK_PASSWORD_USER.email,
|
||||
password: WEAK_PASSWORD_USER.password,
|
||||
name: WEAK_PASSWORD_USER.name,
|
||||
role: 'user',
|
||||
data: {
|
||||
username: WEAK_PASSWORD_USER.username,
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
if (!createRes.ok) {
|
||||
const body = await createRes.text();
|
||||
// Ignore if user already exists (e.g. from a previous test run)
|
||||
if (!body.includes('already') && !body.includes('exists')) {
|
||||
throw new Error(`Failed to create weak-password user: ${createRes.status} ${body}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('should allow a user with a weak password to change their password and log in with the new one', async ({
|
||||
page,
|
||||
}) => {
|
||||
// Log in as the weak-password user
|
||||
await page.goto('/login');
|
||||
await page.getByPlaceholder(/username/i).fill(WEAK_PASSWORD_USER.username);
|
||||
await page.getByPlaceholder(/password/i).fill(WEAK_PASSWORD_USER.password);
|
||||
await page.getByRole('button', { name: /sign in/i }).click();
|
||||
|
||||
// Wait for login to complete
|
||||
await page.waitForURL(/^\/$|\/dashboard/, { timeout: 10000 });
|
||||
|
||||
// Navigate to account settings
|
||||
await page.goto('/dashboard/account');
|
||||
|
||||
// Click on the Security tab
|
||||
await page.getByRole('button', { name: /security/i }).click();
|
||||
|
||||
// Fill in the password change form
|
||||
await page.getByPlaceholder(/enter current password/i).fill(WEAK_PASSWORD_USER.password);
|
||||
await page.getByPlaceholder(/enter new password/i).fill(NEW_STRONG_PASSWORD);
|
||||
await page.getByPlaceholder(/confirm new password/i).fill(NEW_STRONG_PASSWORD);
|
||||
|
||||
// Submit the password change
|
||||
await page.getByRole('button', { name: /change password/i }).click();
|
||||
|
||||
// Verify success message appears
|
||||
await expect(page.getByText(/password changed successfully/i)).toBeVisible({
|
||||
timeout: 10000,
|
||||
});
|
||||
|
||||
// Sign out by clearing cookies and navigating to login
|
||||
await page.context().clearCookies();
|
||||
await page.goto('/login');
|
||||
|
||||
// Log in with the new password
|
||||
await page.getByPlaceholder(/username/i).fill(WEAK_PASSWORD_USER.username);
|
||||
await page.getByPlaceholder(/password/i).fill(NEW_STRONG_PASSWORD);
|
||||
await page.getByRole('button', { name: /sign in/i }).click();
|
||||
|
||||
// Verify login succeeds
|
||||
await page.waitForURL(/^\/$|\/dashboard/, { timeout: 10000 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user