in packages/fxa-auth-server/lib/routes/attached-clients.js [147:220]
handler: async function (request) {
log.begin('Account.attachedClientDestroy', request);
const credentials = request.auth.credentials;
const payload = request.payload;
if (payload.deviceId) {
// If we got a `deviceId`, then deleting that should also delete `sessionTokenId` and `refreshTokenId`,
// assuming that they match the ones that were actually on the device record.
const destroyedDevice = await devices.destroy(
request,
payload.deviceId
);
if (
payload.sessionTokenId &&
destroyedDevice.sessionTokenId !== payload.sessionTokenId
) {
throw error.invalidRequestParameter(
'sessionTokenId did not match device record'
);
}
if (
payload.refreshTokenId &&
destroyedDevice.refreshTokenId !== payload.refreshTokenId
) {
throw error.invalidRequestParameter(
'refreshTokenId did not match device record'
);
}
} else if (payload.refreshTokenId) {
// We've got device-less refreshToken. There should be no sessionToken.
if (payload.sessionTokenId) {
throw error.invalidRequestParameter(
'sessionTokenId cannot be present for non-device OAuth client'
);
}
// If we find the refresh_token_id doesn't exist, swallow the error.
// It was probably some sort of race in deleting the token, and the account
// is in the desired state.
try {
await authorizedClients.destroy(
payload.clientId,
credentials.uid,
payload.refreshTokenId
);
} catch (err) {
if (err.errno !== error.ERRNO.REFRESH_TOKEN_UNKNOWN) {
throw err;
}
}
} else if (payload.clientId) {
// We've got an OAuth client that isn't using refresh tokens. There should be no sessionToken.
if (payload.sessionTokenId) {
throw error.invalidRequestParameter(
'sessionTokenId cannot be present for non-device OAuth client'
);
}
await authorizedClients.destroy(payload.clientId, credentials.uid);
} else if (payload.sessionTokenId) {
// We've got a plain web session on our hands.
// Need to check that it actually belongs to this user, unless it's the current session.
if (payload.sessionTokenId === credentials.id) {
await db.deleteSessionToken(credentials);
} else {
const sessionToken = await db.sessionToken(payload.sessionTokenId);
if (!sessionToken || sessionToken.uid !== credentials.uid) {
throw error.invalidRequestParameter('sessionTokenId');
}
await db.deleteSessionToken(sessionToken);
}
}
return {};
},