diff --git a/keyserver/src/cron/compare-users.js b/keyserver/src/cron/compare-users.js index 7697275f7..b51d25249 100644 --- a/keyserver/src/cron/compare-users.js +++ b/keyserver/src/cron/compare-users.js @@ -1,41 +1,41 @@ // @flow import { getRustAPI } from 'rust-node-addon'; import { deleteCookies } from '../deleters/cookie-deleters.js'; -import { fetchNativeCookieIDsForUserIDs } from '../fetchers/cookie-fetchers.js'; +import { fetchCookieIDsToInvalidateToPopulateIdentityService } from '../fetchers/cookie-fetchers.js'; import { fetchAllUserIDs } from '../fetchers/user-fetchers.js'; async function compareMySQLUsersToIdentityService(): Promise { const [allUserIDs, rustAPI] = await Promise.all([ fetchAllUserIDs(), getRustAPI(), ]); const userComparisonResult = await rustAPI.compareUsers(allUserIDs); const { usersMissingFromKeyserver, usersMissingFromIdentity } = userComparisonResult; if (usersMissingFromKeyserver.length > 0) { console.warn( "found users in identity service that aren't in MySQL! " + JSON.stringify(usersMissingFromKeyserver), ); } if (usersMissingFromIdentity.length === 0) { return; } - const cookieIDs = await fetchNativeCookieIDsForUserIDs( + const cookieIDs = await fetchCookieIDsToInvalidateToPopulateIdentityService( usersMissingFromIdentity, ); if (cookieIDs.length === 0) { return; } // By deleting a cookie associated with a user's device, we trigger an // auto-log-in from that device, which lets us access the user's password. We // need the password in order to double-write user data to the identity // service. We only delete cookies associated with native devices because we // don't cache passwords on other platforms. await deleteCookies(cookieIDs); } export { compareMySQLUsersToIdentityService }; diff --git a/keyserver/src/fetchers/cookie-fetchers.js b/keyserver/src/fetchers/cookie-fetchers.js index 272734c54..3f603aee9 100644 --- a/keyserver/src/fetchers/cookie-fetchers.js +++ b/keyserver/src/fetchers/cookie-fetchers.js @@ -1,25 +1,30 @@ // @flow -import { deviceTypes } from 'lib/types/device-types.js'; - import { dbQuery, SQL } from '../database/database.js'; // This function is used for invalidating native sessions so that we can trigger // a log-in on the next socket connection attempt. We initially introduced this // during the rollout of the identity service, where we needed the user's // password on the keyserver to populate the identity service. We only // invalidate native sessions because web sessions don't cache the user's // password, and we don't want any user-visible issues to result from this. -async function fetchNativeCookieIDsForUserIDs( +async function fetchCookieIDsToInvalidateToPopulateIdentityService( userIDs: $ReadOnlyArray, ): Promise { + // Native clients before codeVersion 193 don't provide the info necessary to + // call the identity service, so there's no point to invalidating their + // sessions. On Android, builds 193/194 have a bug that breaks log-in, so we + // don't want to invalidate their sessions. const query = SQL` SELECT id FROM cookies - WHERE platform IN (${deviceTypes}) AND user IN (${userIDs}) + WHERE user IN (${userIDs}) AND ( + (platform = 'ios' AND JSON_EXTRACT(versions, '$.codeVersion') > 192) OR + (platform = 'android' AND JSON_EXTRACT(versions, '$.codeVersion') > 194) + ) `; const [result] = await dbQuery(query); return result.map(({ id }) => id.toString()); } -export { fetchNativeCookieIDsForUserIDs }; +export { fetchCookieIDsToInvalidateToPopulateIdentityService };