Merge pull request #16517 from mozilla/fxa-8467

fix(delete): Update delete account route
This commit is contained in:
Vijay Budhram 2024-03-12 15:40:43 -04:00 коммит произвёл GitHub
Родитель 21bc82e14a 4f98baa026
Коммит 91020fa9f4
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
26 изменённых файлов: 307 добавлений и 223 удалений

Просмотреть файл

@ -1,5 +1,5 @@
import { Browser, test as base, expect, firefox } from '@playwright/test'; import { Browser, expect, firefox, test as base } from '@playwright/test';
import { TargetName, ServerTarget, create, Credentials } from '../targets'; import { create, Credentials, ServerTarget, TargetName } from '../targets';
import { EmailClient } from '../email'; import { EmailClient } from '../email';
import { create as createPages } from '../../pages'; import { create as createPages } from '../../pages';
import { BaseTarget } from '../targets/base'; import { BaseTarget } from '../targets/base';
@ -36,45 +36,60 @@ export const test = base.extend<TestOptions, WorkerOptions>({
const password = 'passwordzxcv'; const password = 'passwordzxcv';
await target.email.clear(email); await target.email.clear(email);
let credentials: Credentials; let credentials: Credentials;
try { try {
credentials = await target.createAccount(email, password); credentials = await target.createAccount(email, password);
} catch (e) { } catch (e) {
await target.auth.accountDestroy(email, password); const newCreds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(
email,
password,
{},
newCreds.sessionToken
);
credentials = await target.createAccount(email, password); credentials = await target.createAccount(email, password);
} }
await use(credentials); await use(credentials);
//teardown //teardown
await target.email.clear(credentials.email); await target.email.clear(email);
try { try {
await target.auth.accountDestroy(credentials.email, credentials.password); // we don't know if the original session still exists
} catch (error: any) { // the test may have called signOut()
if (error.message === 'Unconfirmed session') { const { sessionToken } = await target.auth.signIn(
// If totp was enabled we'll need a verified session to destroy the account email,
if (credentials.secret) { credentials.password
// we don't know if the original session still exists );
// the test may have called signOut()
const { sessionToken } = await target.auth.signIn( if (credentials.secret) {
credentials.email, credentials.sessionToken = sessionToken;
credentials.password await target.auth.verifyTotpCode(
); sessionToken,
credentials.sessionToken = sessionToken; await getCode(credentials.secret)
await target.auth.verifyTotpCode( );
sessionToken, }
await getCode(credentials.secret)
); await target.auth.accountDestroy(
await target.auth.accountDestroy( email,
credentials.email, credentials.password,
credentials.password, {},
{}, sessionToken
sessionToken );
); } catch (err) {
} else { if (
throw error; err.message ===
} 'Sign in with this email type is not currently supported'
} else if (error.message !== 'Unknown account') { ) {
throw error; // The user changed their primary email, the test case must manually destroy the account
} else if (
err.message === 'The request was blocked for security reasons'
) {
// Some accounts are always prompted to unblock their account, ie emails starting
// `blocked.`. These accounts need to be destroyed in the test case
} else if (err.message !== 'Unknown account') {
throw err;
} }
//s'ok //s'ok
} }

Просмотреть файл

@ -116,6 +116,9 @@ export abstract class BaseLayout {
* index page has been converted to React and our event handling moved. * index page has been converted to React and our event handling moved.
*/ */
async sendWebChannelMessage(customEventDetail: CustomEventDetail) { async sendWebChannelMessage(customEventDetail: CustomEventDetail) {
// Using waitForTimeout is naturally flaky, I'm not sure of other options
// to ensure that browser has had time send all web channel messages.
await this.page.waitForTimeout(2000);
await this.page.evaluate( await this.page.evaluate(
({ customEventDetail }) => { ({ customEventDetail }) => {
window.dispatchEvent( window.dispatchEvent(

Просмотреть файл

@ -10,7 +10,7 @@ const CI = !!process.env.CI;
// see .vscode/launch.json // see .vscode/launch.json
const DEBUG = !!process.env.DEBUG; const DEBUG = !!process.env.DEBUG;
const SLOWMO = parseInt(process.env.PLAYWRIGHT_SLOWMO || '0'); const SLOWMO = parseInt(process.env.PLAYWRIGHT_SLOWMO || '0');
const NUM_WORKERS = parseInt(process.env.PLAYWRIGHT_WORKERS || '2'); const NUM_WORKERS = parseInt(process.env.PLAYWRIGHT_WORKERS || '16');
let retries = 0, let retries = 0,
workers = NUM_WORKERS || 2, workers = NUM_WORKERS || 2,

Просмотреть файл

@ -21,9 +21,10 @@ function getClient(url: string, version: SaltVersion) {
test.describe('auth-client-tests', () => { test.describe('auth-client-tests', () => {
let email = ''; let email = '';
let password = ''; let password = '';
let credentials: any;
async function signUp(client: AuthClient) { async function signUp(client: AuthClient) {
const credentials = await client.signUp(email, password, { credentials = await client.signUp(email, password, {
keys: true, keys: true,
preVerified: 'true', preVerified: 'true',
}); });
@ -49,7 +50,8 @@ test.describe('auth-client-tests', () => {
}); });
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
await curClient?.accountDestroy(email, password); const newCreds = await curClient?.signIn(email, password, { keys: true });
await curClient?.accountDestroy(email, password, {}, newCreds.sessionToken);
}); });
test('it creates with v1 and signs in', async ({ target }) => { test('it creates with v1 and signs in', async ({ target }) => {

Просмотреть файл

@ -23,7 +23,13 @@ test.describe('severity-1 #smoke', () => {
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { if (email) {
// Cleanup any accounts created during the test // Cleanup any accounts created during the test
await target.auth.accountDestroy(email, password); const credentials = await target.auth.signIn(email, password);
await target.auth.accountDestroy(
email,
password,
{},
credentials.sessionToken
);
} }
}); });

Просмотреть файл

@ -90,7 +90,7 @@ test.describe('severity-1 #smoke', () => {
target, target,
pages: { relier, login }, pages: { relier, login },
}) => { }) => {
await target.auth.signUp(email, password, { const creds = await target.auth.signUp(email, password, {
lang: 'en', lang: 'en',
preVerified: 'true', preVerified: 'true',
}); });
@ -101,7 +101,7 @@ test.describe('severity-1 #smoke', () => {
//Verify logged in on Settings page //Verify logged in on Settings page
expect(await login.isUserLoggedIn()).toBe(true); expect(await login.isUserLoggedIn()).toBe(true);
await target.auth.accountDestroy(email, password); await target.auth.accountDestroy(email, password, {}, creds.sessionToken);
const query = new URLSearchParams({ const query = new URLSearchParams({
login_hint: email, login_hint: email,
@ -160,10 +160,9 @@ test.describe('severity-1 #smoke', () => {
}); });
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { // Cleanup any accounts created during the test
// Cleanup any accounts created during the test const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(email, password); await target.auth.accountDestroy(email, password, {}, creds.sessionToken);
}
}); });
test('fails if login_hint is different to logged in user', async ({ test('fails if login_hint is different to logged in user', async ({

Просмотреть файл

@ -27,9 +27,17 @@ test.describe('severity-1 #smoke', () => {
}); });
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { // Cleanup any accounts created during the test
// Cleanup any accounts created during the test try {
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(
email,
password,
{},
creds.sessionToken
);
} catch (e) {
// ignore
} }
}); });

Просмотреть файл

@ -19,6 +19,8 @@ test.describe('severity-2 #smoke', () => {
/* Password for fake account */ /* Password for fake account */
const password = 'passwordzxcv'; const password = 'passwordzxcv';
let emailUserCreds;
/* eslint-disable camelcase */ /* eslint-disable camelcase */
const queryParameters = { const queryParameters = {
client_id: '7f368c6886429f19', client_id: '7f368c6886429f19',
@ -37,17 +39,20 @@ test.describe('severity-2 #smoke', () => {
test.beforeEach(async ({ target }, { project }) => { test.beforeEach(async ({ target }, { project }) => {
// The `sync` prefix is needed to force confirmation. // The `sync` prefix is needed to force confirmation.
email = `sync${Math.random()}@restmail.net`; email = `sync${Math.random()}@restmail.net`;
await target.createAccount(email, password); emailUserCreds = await target.createAccount(email, password);
}); });
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { // Cleanup any accounts created during the test
// Cleanup any accounts created during the test try {
try { await target.auth.accountDestroy(
await target.auth.accountDestroy(email, password); email,
} catch (e) { password,
// ignore {},
} emailUserCreds.sessionToken
);
} catch (e) {
// ignore
} }
}); });

Просмотреть файл

@ -16,11 +16,13 @@ test.describe('severity-1 #smoke', () => {
test.describe('signin with OAuth after Sync', () => { test.describe('signin with OAuth after Sync', () => {
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { if (email) {
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(email, password, {}, creds.sessionToken);
email = ''; email = '';
} }
if (email2) { if (email2) {
await target.auth.accountDestroy(email2, password); const creds = await target.auth.signIn(email2, password);
await target.auth.accountDestroy(email2, password, {}, creds.sessionToken);
email2 = ''; email2 = '';
} }
}); });
@ -78,7 +80,8 @@ test.describe('severity-1 #smoke', () => {
test.describe('signin to Sync after OAuth', () => { test.describe('signin to Sync after OAuth', () => {
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { if (email) {
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(email, password, {}, creds.sessionToken);
email = ''; email = '';
} }
}); });

Просмотреть файл

@ -41,6 +41,7 @@ test.describe('severity-1 #smoke', () => {
await page.getByText('Two-step authentication disabled').waitFor(); await page.getByText('Two-step authentication disabled').waitFor();
const status = await settings.totp.statusText(); const status = await settings.totp.statusText();
expect(status).toEqual('Not Set'); expect(status).toEqual('Not Set');
credentials.secret = null;
await relier.goto(); await relier.goto();
await relier.clickEmailFirst(); await relier.clickEmailFirst();

Просмотреть файл

@ -6,13 +6,14 @@ import { test, expect } from '../../lib/fixtures/standard';
let email; let email;
const password = 'password'; const password = 'password';
const newPassword = 'new_password'; const newPassword = 'new_password';
let emailUserCreds;
test.describe('severity-2 #smoke', () => { test.describe('severity-2 #smoke', () => {
test.describe('post verify - force password change', () => { test.describe('post verify - force password change', () => {
test.beforeEach(async ({ target, pages: { login } }) => { test.beforeEach(async ({ target, pages: { login } }) => {
test.slow(); test.slow();
email = login.createEmail('forcepwdchange{id}'); email = login.createEmail('forcepwdchange{id}');
await target.auth.signUp(email, password, { emailUserCreds = await target.auth.signUp(email, password, {
lang: 'en', lang: 'en',
preVerified: 'true', preVerified: 'true',
}); });
@ -20,9 +21,16 @@ test.describe('severity-2 #smoke', () => {
}); });
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { // Cleanup any accounts created during the test
// Cleanup any accounts created during the test try {
await target.auth.accountDestroy(email, newPassword); await target.auth.accountDestroy(
email,
newPassword,
{},
emailUserCreds.sessionToken
);
} catch (e) {
// ignore
} }
}); });

Просмотреть файл

@ -20,7 +20,8 @@ test.describe('severity-2 #smoke', () => {
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { if (email) {
// Cleanup any accounts created during the test // Cleanup any accounts created during the test
await target.auth.accountDestroy(email, newPassword); const creds = await target.auth.signIn(email, newPassword);
await target.auth.accountDestroy(email, newPassword, {}, creds.sessionToken);
} }
}); });

Просмотреть файл

@ -34,12 +34,15 @@ test.beforeEach(async ({ pages: { configPage, login } }) => {
}); });
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { // Cleanup any accounts created during the test
// Cleanup any accounts created during the test try {
const accountStatus = await target.auth.accountStatusByEmail(email); if (!email) {
if (accountStatus.exists) { return;
await target.auth.accountDestroy(email, PASSWORD);
} }
const creds = await target.auth.signIn(email, PASSWORD);
await target.auth.accountDestroy(email, PASSWORD, {}, creds.sessionToken);
} catch (e) {
// ignore
} }
}); });
@ -110,7 +113,6 @@ test.describe('severity-1 #smoke', () => {
test('signup oauth webchannel - sync mobile or FF desktop 123+', async ({ test('signup oauth webchannel - sync mobile or FF desktop 123+', async ({
syncBrowserPages: { page, signupReact, login }, syncBrowserPages: { page, signupReact, login },
}) => { }) => {
test.fixme(true, 'FXA-9096');
const customEventDetail = createCustomEventDetail( const customEventDetail = createCustomEventDetail(
FirefoxCommand.FxAStatus, FirefoxCommand.FxAStatus,
{ {

Просмотреть файл

@ -19,6 +19,23 @@ test.describe('severity-1 #smoke', () => {
} }
); );
test.afterEach(async ({ credentials, target }) => {
try {
const newCreds = await target.auth.signIn(
newEmail,
credentials.password
);
await target.auth.accountDestroy(
newEmail,
credentials.password,
{},
newCreds.sessionToken
);
} catch (err) {
// ignore
}
});
test('change primary email and login', async ({ test('change primary email and login', async ({
credentials, credentials,
page, page,
@ -130,14 +147,13 @@ test.describe('severity-1 #smoke', () => {
}); });
test.describe('change primary - unblock', () => { test.describe('change primary - unblock', () => {
let newEmail;
test.beforeEach( test.beforeEach(
async ({ credentials, pages: { settings, secondaryEmail } }) => { async ({ credentials, pages: { settings, secondaryEmail } }) => {
test.slow(); test.slow();
await settings.goto(); await settings.goto();
await settings.secondaryEmail.clickAdd(); await settings.secondaryEmail.clickAdd();
const newEmail = `blocked${Math.floor( newEmail = `blocked${Math.floor(Math.random() * 100000)}@restmail.net`;
Math.random() * 100000
)}@restmail.net`;
await secondaryEmail.addAndVerify(newEmail); await secondaryEmail.addAndVerify(newEmail);
await settings.secondaryEmail.clickMakePrimary(); await settings.secondaryEmail.clickMakePrimary();
credentials.email = newEmail; credentials.email = newEmail;
@ -145,6 +161,23 @@ test.describe('severity-1 #smoke', () => {
} }
); );
test.afterEach(async ({ credentials, target }) => {
try {
const newCreds = await target.auth.signIn(
newEmail,
credentials.password
);
await target.auth.accountDestroy(
newEmail,
credentials.password,
{},
newCreds.sessionToken
);
} catch (err) {
// ignore
}
});
test('change primary email, get blocked with invalid password, redirect enter password page', async ({ test('change primary email, get blocked with invalid password, redirect enter password page', async ({
credentials, credentials,
pages: { login }, pages: { login },

Просмотреть файл

@ -43,8 +43,10 @@ test.describe('fxa_status web channel message in Settings', () => {
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (!skipTest) { if (!skipTest) {
// Cleanup any accounts created during the test // Cleanup any accounts created during the test
await target.auth.accountDestroy(browserEmail, password); const credsBrowser = await target.auth.signIn(browserEmail, password);
await target.auth.accountDestroy(otherEmail, password); const credsEmail = await target.auth.signIn(otherEmail, password);
await target.auth.accountDestroy(browserEmail, password, {}, credsBrowser.sessionToken);
await target.auth.accountDestroy(otherEmail, password, {}, credsEmail.sessionToken);
} }
}); });

Просмотреть файл

@ -32,6 +32,7 @@ test.describe('severity-1 #smoke', () => {
await page.getByText('Two-step authentication disabled').waitFor(); await page.getByText('Two-step authentication disabled').waitFor();
status = await settings.totp.statusText(); status = await settings.totp.statusText();
expect(status).toEqual('Not Set'); expect(status).toEqual('Not Set');
credentials.secret = null;
// Login to verify no prompt for code // Login to verify no prompt for code
await settings.signOut(); await settings.signOut();

Просмотреть файл

@ -19,7 +19,12 @@ test.describe('severity-2 #smoke', () => {
signupReact, signupReact,
} = await newPagesForSync(target); } = await newPagesForSync(target);
const config = await configPage.getConfig(); const config = await configPage.getConfig();
await target.auth.accountDestroy(credentials.email, credentials.password); await target.auth.accountDestroy(
credentials.email,
credentials.password,
{},
credentials.sessionToken
);
await page.goto( await page.goto(
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`, `${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email`,

Просмотреть файл

@ -114,7 +114,7 @@ test.describe('severity-2 #smoke', () => {
); );
const email = login.createEmail('sync{id}'); const email = login.createEmail('sync{id}');
const password = 'password123'; const password = 'password123';
await target.createAccount(email, password); const creds = await target.createAccount(email, password);
await page.goto( await page.goto(
`${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&` `${target.contentServerUrl}?context=fx_desktop_v3&service=sync&action=email&`
); );
@ -122,7 +122,7 @@ test.describe('severity-2 #smoke', () => {
// Verify the header after login // Verify the header after login
expect(login.signInCodeHeader()).toBeVisible(); expect(login.signInCodeHeader()).toBeVisible();
await target.auth.accountDestroy(email, password); await target.auth.accountDestroy(email, password, {}, creds.sessionToken);
await page.waitForURL(/signin_bounced/); await page.waitForURL(/signin_bounced/);
//Verify sign in bounced header //Verify sign in bounced header

Просмотреть файл

@ -38,7 +38,13 @@ test.describe('severity-2 #smoke', () => {
for (const email of emails) { for (const email of emails) {
if (email) { if (email) {
try { try {
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(
email,
password,
{},
creds.sessionToken
);
} catch (e) { } catch (e) {
// Handle any errors if needed // Handle any errors if needed
} }

Просмотреть файл

@ -27,11 +27,13 @@ test.describe('severity-2 #smoke', () => {
test.slow(); //The cleanup was timing out and exceeding 3000ms test.slow(); //The cleanup was timing out and exceeding 3000ms
if (email) { if (email) {
// Cleanup any accounts created during the test // Cleanup any accounts created during the test
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(email, password, {}, creds.sessionToken);
} }
if (email2) { if (email2) {
// Cleanup any accounts created during the test // Cleanup any accounts created during the test
await target.auth.accountDestroy(email2, password); const creds = await target.auth.signIn(email2, password);
await target.auth.accountDestroy(email2, password, {}, creds.sessionToken);
} }
}); });

Просмотреть файл

@ -32,7 +32,13 @@ test.describe('severity-2 #smoke', () => {
for (const email of emails) { for (const email of emails) {
if (email) { if (email) {
// Cleanup any accounts created during the test // Cleanup any accounts created during the test
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(
email,
password,
{},
creds.sessionToken
);
} }
} }
}); });

Просмотреть файл

@ -46,7 +46,13 @@ test.describe('severity-2 #smoke', () => {
test.afterEach(async ({ target }) => { test.afterEach(async ({ target }) => {
if (email) { if (email) {
await target.auth.accountDestroy(email, secondPassword); const creds = await target.auth.signIn(email, secondPassword);
await target.auth.accountDestroy(
email,
secondPassword,
{},
creds.sessionToken
);
} }
}); });

Просмотреть файл

@ -30,7 +30,13 @@ test.describe('severity-2 #smoke', () => {
for (const email of emails) { for (const email of emails) {
if (email) { if (email) {
try { try {
await target.auth.accountDestroy(email, password); const creds = await target.auth.signIn(email, password);
await target.auth.accountDestroy(
email,
password,
{},
creds.sessionToken
);
} catch (e) { } catch (e) {
// Handle any errors if needed // Handle any errors if needed
} }

Просмотреть файл

@ -888,7 +888,7 @@ export default class AuthClient {
options: { options: {
skipCaseError?: boolean; skipCaseError?: boolean;
} = {}, } = {},
sessionToken?: hexstring sessionToken: hexstring
): Promise<any> { ): Promise<any> {
const credentials = await crypto.getCredentials(email, password); const credentials = await crypto.getCredentials(email, password);
const payload = { const payload = {
@ -896,15 +896,7 @@ export default class AuthClient {
authPW: credentials.authPW, authPW: credentials.authPW,
}; };
try { try {
if (sessionToken) { return await this.sessionPost('/account/destroy', sessionToken, payload);
return await this.sessionPost(
'/account/destroy',
sessionToken,
payload
);
} else {
return await this.request('POST', '/account/destroy', payload);
}
} catch (error: any) { } catch (error: any) {
if ( if (
error && error &&

Просмотреть файл

@ -2367,8 +2367,8 @@ export const accountRoutes = (
options: { options: {
...ACCOUNT_DOCS.ACCOUNT_DESTROY_POST, ...ACCOUNT_DOCS.ACCOUNT_DESTROY_POST,
auth: { auth: {
mode: 'optional',
strategy: 'sessionToken', strategy: 'sessionToken',
payload: 'required',
}, },
validate: { validate: {
payload: isA.object({ payload: isA.object({

Просмотреть файл

@ -11,140 +11,112 @@ const Client = require('../client')();
const config = require('../../config').default.getProperties(); const config = require('../../config').default.getProperties();
// Note, intentionally not indenting for code review. // Note, intentionally not indenting for code review.
[{version:""},{version:"V2"}].forEach((testOptions) => { [{ version: '' }, { version: 'V2' }].forEach((testOptions) => {
describe(`#integration${testOptions.version} - remote account destroy`, function () {
this.timeout(15000);
let server;
describe(`#integration${testOptions.version} - remote account destroy`, function () { before(() => {
this.timeout(15000); return TestServer.start(config).then((s) => {
let server; server = s;
});
});
before(() => { it('account destroy', () => {
return TestServer.start(config).then((s) => { const email = server.uniqueEmail();
server = s; const password = 'allyourbasearebelongtous';
let client = null;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
return client.sessionStatus();
})
.then((status) => {
return client.destroyAccount();
})
.then(() => {
return client.keys();
})
.then(
(keys) => {
assert(false, 'account not destroyed');
},
(err) => {
assert.equal(err.message, 'Unknown account', 'account destroyed');
}
);
});
it('invalid authPW on account destroy', () => {
const email = server.uniqueEmail();
const password = 'ok';
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((c) => {
c.authPW = Buffer.from(
'0000000000000000000000000000000000000000000000000000000000000000',
'hex'
);
c.authPWVersion2 = Buffer.from(
'0000000000000000000000000000000000000000000000000000000000000000',
'hex'
);
return c.destroyAccount();
})
.then(
(r) => {
assert(false);
},
(err) => {
assert.equal(err.errno, 103);
}
);
});
it('should fail to delete account with TOTP with unverified session', () => {
const email = server.uniqueEmail();
const password = 'ok';
let client;
return Client.createAndVerifyAndTOTP(
config.publicUrl,
email,
password,
server.mailbox,
{
...testOptions,
keys: true,
}
)
.then(() => {
// Create a new unverified session
return Client.login(config.publicUrl, email, password, testOptions);
})
.then((response) => {
client = response;
return client.emailStatus();
})
.then((res) =>
assert.equal(res.sessionVerified, false, 'session not verified')
)
.then(() => client.destroyAccount())
.then(assert.fail, (err) => {
assert.equal(err.errno, 138, 'unverified session');
});
});
after(() => {
return TestServer.stop(server);
}); });
}); });
it('account destroy', () => {
const email = server.uniqueEmail();
const password = 'allyourbasearebelongtous';
let client = null;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
return client.sessionStatus();
})
.then((status) => {
return client.destroyAccount();
})
.then(() => {
return client.keys();
})
.then(
(keys) => {
assert(false, 'account not destroyed');
},
(err) => {
assert.equal(err.message, 'Unknown account', 'account destroyed');
}
);
});
it('invalid authPW on account destroy', () => {
const email = server.uniqueEmail();
const password = 'ok';
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((c) => {
c.authPW = Buffer.from(
'0000000000000000000000000000000000000000000000000000000000000000',
'hex'
);
c.authPWVersion2 = Buffer.from(
'0000000000000000000000000000000000000000000000000000000000000000',
'hex'
);
return c.destroyAccount();
})
.then(
(r) => {
assert(false);
},
(err) => {
assert.equal(err.errno, 103);
}
);
});
it('should fail to delete account with TOTP without passing sessionToken', () => {
const email = server.uniqueEmail();
const password = 'ok';
let client;
return Client.createAndVerifyAndTOTP(
config.publicUrl,
email,
password,
server.mailbox,
{
...testOptions,
keys: true
}
)
.then((res) => {
client = res;
// Doesn't specify a sessionToken to use
delete client.sessionToken;
return client.destroyAccount();
})
.then(assert.fail, (err) => {
assert.equal(err.errno, 138, 'unverified session');
});
});
it('should fail to delete account with TOTP with unverified session', () => {
const email = server.uniqueEmail();
const password = 'ok';
let client;
return Client.createAndVerifyAndTOTP(
config.publicUrl,
email,
password,
server.mailbox,
{
...testOptions,
keys: true
}
)
.then(() => {
// Create a new unverified session
return Client.login(config.publicUrl, email, password, testOptions);
})
.then((response) => {
client = response;
return client.emailStatus();
})
.then((res) =>
assert.equal(res.sessionVerified, false, 'session not verified')
)
.then(() => client.destroyAccount())
.then(assert.fail, (err) => {
assert.equal(err.errno, 138, 'unverified session');
});
});
after(() => {
return TestServer.stop(server);
});
});
}); });