feat(secevents): remove DELETE endpoint

Because:

* We no longer support this endpoint

This commit:

* Removes the endpoint
This commit is contained in:
Wil Clouser 2024-09-12 10:54:50 -07:00
Родитель 7af8c8270f
Коммит 07751c5fc1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 69C9C9207C73946E
18 изменённых файлов: 1762 добавлений и 1928 удалений

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

@ -0,0 +1,5 @@
SET NAMES utf8mb4 COLLATE utf8mb4_bin;
DROP PROCEDURE `deleteSecurityEventsByUid_1`;
UPDATE dbMetadata SET value = '154' WHERE name = 'schema-patch-level';

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

@ -0,0 +1,10 @@
-- SET NAMES utf8mb4 COLLATE utf8mb4_bin;
-- CREATE PROCEDURE `deleteSecurityEventsByUid_1` (
-- IN `inUid` BINARY(16)
-- )
-- BEGIN
-- DELETE FROM securityEvents WHERE uid = inUid;
-- END;
-- UPDATE dbMetadata SET value = '153' WHERE name = 'schema-patch-level';

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

@ -1596,17 +1596,6 @@ export default class AuthClient {
return this.sessionGet('/securityEvents', sessionToken, headers);
}
async deleteSecurityEvents(sessionToken: hexstring, headers?: Headers) {
return this.hawkRequest(
'DELETE',
'/securityEvents',
sessionToken,
tokenType.sessionToken,
{},
headers
);
}
async attachedClients(sessionToken: hexstring, headers?: Headers) {
return this.sessionGet('/account/attached_clients', sessionToken, headers);
}

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

@ -21,20 +21,7 @@ const SECURITYEVENTS_GET = {
],
};
const SECURITYEVENTS_DELETE = {
...TAGS_SECURITY_EVENTS,
description: '/securityEvents',
notes: [
dedent`
🔒 Authenticated with session token
Deletes all the security events of a signed in account.
`,
],
};
const API_DOCS = {
SECURITYEVENTS_DELETE,
SECURITYEVENTS_GET,
};

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

@ -845,14 +845,6 @@ module.exports = (config, log, Token, UnblockCode = null) => {
return SecurityEvent.findByUid(uid);
};
DB.prototype.deleteSecurityEvents = async function (params) {
log.trace('DB.deleteSecurityEvents', {
params: params,
});
const { uid } = params;
await SecurityEvent.delete(uid);
};
DB.prototype.createUnblockCode = async function (uid) {
if (!UnblockCode) {
return Promise.reject(new Error('Unblock has not been configured'));

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

@ -26,22 +26,5 @@ module.exports = (log, db, config) => {
return events;
},
},
{
method: 'DELETE',
path: '/securityEvents',
options: {
...SECURITY_EVENTS_DOCS.SECURITYEVENTS_DELETE,
auth: {
strategy: 'sessionToken',
},
},
handler: async function (request) {
log.begin('SecurityEventsDelete', request);
const { uid } = request.auth.credentials;
await db.deleteSecurityEvents({ uid });
return {};
},
},
];
};

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

@ -1023,12 +1023,6 @@ module.exports = (config) => {
});
};
ClientApi.prototype.deleteSecurityEvents = function (sessionTokenHex) {
return tokens.SessionToken.fromHex(sessionTokenHex).then((token) => {
return this.doRequest('DELETE', `${this.baseURL}/securityEvents`, token);
});
};
ClientApi.prototype.accountProfile = function (sessionTokenHex, headers) {
const o = sessionTokenHex
? tokens.SessionToken.fromHex(sessionTokenHex)

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

@ -701,13 +701,6 @@ module.exports = (config) => {
});
};
Client.prototype.deleteSecurityEvents = function () {
const o = this.sessionToken ? Promise.resolve(null) : this.login();
return o.then(() => {
return this.api.deleteSecurityEvents(this.sessionToken);
});
};
Client.prototype.accountProfile = function (oauthToken) {
if (oauthToken) {
return this.api.accountProfile(null, {

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

@ -56,18 +56,3 @@ describe('GET /securityEvents', () => {
});
});
});
describe('DELETE /securityEvents', () => {
it('deletes the security events', () => {
const requestOptions = {
credentials: {
email: TEST_EMAIL,
uid: UID,
},
method: 'DELETE',
};
return setup('/securityEvents', requestOptions).then((res) => {
assert.deepEqual(res, {});
});
});
});

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

@ -63,7 +63,6 @@ const DB_METHOD_NAMES = [
'deleteEmail',
'deleteKeyFetchToken',
'deletePasswordChangeToken',
'deleteSecurityEvents',
'deleteSessionToken',
'deviceFromTokenVerificationId',
'deleteRecoveryKey',
@ -543,9 +542,6 @@ function mockDB(data, errors) {
assert.ok(device);
return Promise.resolve(device);
}),
deleteSecurityEvents: sinon.spy(() => {
return Promise.resolve({});
}),
deleteSessionToken: sinon.spy(() => {
return Promise.resolve();
}),

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

@ -1281,28 +1281,6 @@ describe(`#integration - remote db`, function () {
});
});
it('db.deleteSecurityEvents', () => {
return db
.securityEvent({
ipAddr: '127.0.0.1',
name: 'account.create',
uid: account.uid,
})
.then(() => {
return db.deleteSecurityEvents({
uid: account.uid,
});
})
.then(() => {
return db.securityEventsByUid({
uid: account.uid,
});
})
.then((events) => {
assert.equal(events.length, 0);
});
});
it('unblock code', () => {
let unblockCode;
return db

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

@ -19,142 +19,104 @@ function delay(seconds) {
return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
[{version:""},{version:"V2"}].forEach((testOptions) => {
[{ version: '' }, { version: 'V2' }].forEach((testOptions) => {
describe(`#integration${testOptions.version} - remote securityEvents`, () => {
let server;
describe(`#integration${testOptions.version} - remote securityEvents`, () => {
let server;
before(function () {
this.timeout(15000);
config.securityHistory.ipProfiling.allowedRecency = 0;
config.signinConfirmation.skipForNewAccounts.enabled = false;
return TestServer.start(config).then((s) => {
server = s;
});
});
before(function () {
this.timeout(15000);
config.securityHistory.ipProfiling.allowedRecency = 0;
config.signinConfirmation.skipForNewAccounts.enabled = false;
return TestServer.start(config).then((s) => {
server = s;
it('returns securityEvents on creating and login into an account', () => {
const email = server.uniqueEmail();
const password = 'abcdef';
let client;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
return client.login().then(() => {
return delay(1).then(() => {
return client.securityEvents();
});
});
})
.then((events) => {
assert.equal(events.length, 2);
assert.equal(events[0].name, 'account.login');
assert.isBelow(events[0].createdAt, new Date().getTime());
assert.equal(events[0].verified, false);
assert.equal(events[1].name, 'account.create');
assert.isBelow(events[1].createdAt, new Date().getTime());
assert.equal(events[1].verified, true);
});
});
it('returns security events after account reset w/o keys, with sessionToken', () => {
const email = server.uniqueEmail();
const password = 'oldPassword';
const newPassword = 'newPassword';
let client;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
})
.then(() => {
return client.forgotPassword();
})
.then(() => {
return server.mailbox.waitForCode(email);
})
.then((code) => {
assert.isRejected(client.resetPassword(newPassword));
return resetPassword(client, code, newPassword);
})
.then((response) => {
assert.ok(response.sessionToken, 'session token is in response');
assert(
!response.keyFetchToken,
'keyFetchToken token is not in response'
);
assert.equal(response.verified, true, 'verified is true');
})
.then(() => {
return delay(1).then(() => {
return client.securityEvents();
});
})
.then((events) => {
assert.equal(events.length, 2);
assert.equal(events[0].name, 'account.reset');
assert.isBelow(events[0].createdAt, new Date().getTime());
assert.equal(events[0].verified, true);
assert.equal(events[1].name, 'account.create');
assert.isBelow(events[1].createdAt, new Date().getTime());
assert.equal(events[1].verified, true);
});
});
after(() => {
return TestServer.stop(server);
});
});
it('returns securityEvents on creating and login into an account', () => {
const email = server.uniqueEmail();
const password = 'abcdef';
let client;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
return client.login().then(() => {
return delay(1).then(() => {
return client.securityEvents();
});
});
})
.then((events) => {
assert.equal(events.length, 2);
assert.equal(events[0].name, 'account.login');
assert.isBelow(events[0].createdAt, new Date().getTime());
assert.equal(events[0].verified, false);
assert.equal(events[1].name, 'account.create');
assert.isBelow(events[1].createdAt, new Date().getTime());
assert.equal(events[1].verified, true);
});
});
it('returns no securityEvents after deleting them', () => {
const email = server.uniqueEmail();
const password = 'abcdef';
let client;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
return client.login().then(() => {
return delay(1).then(() => {
return client.securityEvents();
});
});
})
.then((events) => {
assert.equal(events.length, 2);
assert.equal(events[0].name, 'account.login');
assert.isBelow(events[0].createdAt, new Date().getTime());
assert.equal(events[0].verified, false);
assert.equal(events[1].name, 'account.create');
assert.isBelow(events[1].createdAt, new Date().getTime());
assert.equal(events[1].verified, true);
})
.then(() => client.deleteSecurityEvents())
.then((events) => {
assert.deepEqual(events, {});
});
});
it('returns security events after account reset w/o keys, with sessionToken', () => {
const email = server.uniqueEmail();
const password = 'oldPassword';
const newPassword = 'newPassword';
let client;
return Client.createAndVerify(
config.publicUrl,
email,
password,
server.mailbox,
testOptions
)
.then((x) => {
client = x;
})
.then(() => {
return client.forgotPassword();
})
.then(() => {
return server.mailbox.waitForCode(email);
})
.then((code) => {
assert.isRejected(client.resetPassword(newPassword));
return resetPassword(client, code, newPassword);
})
.then((response) => {
assert.ok(response.sessionToken, 'session token is in response');
assert(
!response.keyFetchToken,
'keyFetchToken token is not in response'
);
assert.equal(response.verified, true, 'verified is true');
})
.then(() => {
return delay(1).then(() => {
return client.securityEvents();
});
})
.then((events) => {
assert.equal(events.length, 2);
assert.equal(events[0].name, 'account.reset');
assert.isBelow(events[0].createdAt, new Date().getTime());
assert.equal(events[0].verified, true);
assert.equal(events[1].name, 'account.create');
assert.isBelow(events[1].createdAt, new Date().getTime());
assert.equal(events[1].verified, true);
});
});
after(() => {
return TestServer.stop(server);
});
});
});

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

@ -153,7 +153,7 @@ FxaClientWrapper.prototype = {
}
const options = {
keyStretchVersion: determineKeyStretchVersion()
keyStretchVersion: determineKeyStretchVersion(),
};
return AuthClient.create(this._authServerUrl, options).then((client) => {
@ -919,14 +919,6 @@ FxaClientWrapper.prototype = {
*/
securityEvents: createClientDelegate('securityEvents'),
/**
* Delete user's security events
*
* @param {String} sessionToken
* @returns {Promise} resolves with empty response when complete.
*/
deleteSecurityEvents: createClientDelegate('deleteSecurityEvents'),
/**
* Get user's attached clients
*

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

@ -481,22 +481,6 @@ const Account = Backbone.Model.extend(
});
},
/**
* Delete user's security events from the DELETE /securityEvents on the auth server
*
* @returns {Promise} resolves with empty response if succeeded
*/
deleteSecurityEvents() {
return Promise.resolve().then(() => {
const sessionToken = this.get('sessionToken');
if (!sessionToken) {
throw AuthErrors.toError('INVALID_TOKEN');
}
return this._fxaClient.deleteSecurityEvents(sessionToken);
});
},
setProfileImage(profileImage) {
this.set({
profileImageId: profileImage.get('id'),

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -3022,21 +3022,6 @@ describe('models/account', function () {
});
});
describe('deleteSecurityEvents', () => {
it('deletes the security events', () => {
account.set('sessionToken', SESSION_TOKEN);
sinon.stub(fxaClient, 'deleteSecurityEvents').callsFake(() => {
return Promise.resolve({});
});
return account.deleteSecurityEvents().then((res) => {
assert.isTrue(fxaClient.deleteSecurityEvents.calledOnce);
assert.isTrue(fxaClient.deleteSecurityEvents.calledWith(SESSION_TOKEN));
assert.deepEqual(res, {});
});
});
});
describe('verifyIdToken', () => {
beforeEach(() => {
sinon

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

@ -36,7 +36,6 @@ export enum Proc {
DeletePasswordForgotToken = 'deletePasswordForgotToken_1',
DeleteRecoveryCodes = 'deleteRecoveryCodes_1',
DeleteRecoveryKey = 'deleteRecoveryKey_2',
DeleteSecurityEvents = 'deleteSecurityEventsByUid_1',
DeleteSessionToken = 'deleteSessionToken_4',
DeleteTotpToken = 'deleteTotpToken_4',
Device = 'device_3',

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

@ -104,18 +104,6 @@ export class SecurityEvent extends BaseAuthModel {
return !!result;
}
static async delete(uid: string) {
try {
await this.callProcedure(
Proc.DeleteSecurityEvents,
uuidTransformer.to(uid)
);
} catch (e) {
console.error(e);
throw convertError(e);
}
}
static async findByUid(uid: string) {
const id = uuidTransformer.to(uid);
return this.query()