handler: async function()

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 {};
      },