зеркало из https://github.com/mozilla/fxa.git
feat(secevents): remove DELETE endpoint
Because: * We no longer support this endpoint This commit: * Removes the endpoint
This commit is contained in:
Родитель
7af8c8270f
Коммит
07751c5fc1
|
@ -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()
|
||||
|
|
Загрузка…
Ссылка в новой задаче