Не удается получить токен удостоверения пользователя через Office JS API

Наши производственные клиенты борются со следующей ошибкой: API-интерфейс Office JS не возвращает токен идентификации пользователя, и это блокирует все использование нашей надстройки.

Ошибка, которую мы видим в логах:

{
    "name": "AccessRestricted",
    "message": "Internal protocol error: '-2147467259'.",
    "code": 9017
}

Иногда он появляется, когда ноутбук выходит из спящего режима, иногда нет.

Кроме того, иногда (но не каждый раз, когда появляется ошибка AccessRestricted) в Office JS API, когда наш код выполняет асинхронное получение токена идентификации пользователя, возникает следующая ошибка:

"Unable to get property 'Execute' of undefined or null reference",
"number": -2146823281,
"stack": 
    "TypeError: Unable to get property 'Execute' of undefined or null reference
     at n.prototype.execute (https://appsforoffice.microsoft.com/lib/1... (truncated by our logging system)

Версия Outlook - 16.0.8528.2147, надстройка закреплена. P.S. API-интерфейс Office JS был инициализирован, но это не основная причина проблемы.

Вот фрагменты кода:

sfMailApp.OfficeManager.prototype.getCallbackTokenAsync = function () {
    var item = this.getItem();

    return !item.isFake ? this._loadItemAsync(Office.context.mailbox, 'getCallbackTokenAsync') : sfMailApp.utils.resolveDeferred('');
};

sfMailApp.OfficeManager.prototype.getIdentityTokenAsync = function (force) {
    var ls = getLocalStorage();
    var lastUpdateIdentityTokenTimestamp = ls.getItem('identityTokenUpdate');
    var cachedIdentityToken = ls.getItem('identityToken');

    var lastUpdateIdentityTokenDifference = !sfMailApp.utils.isNullOrEmpty(lastUpdateIdentityTokenTimestamp) ? (new Date().getTime() - parseInt(lastUpdateIdentityTokenTimestamp)) : null;

    if (sfMailApp.utils.isNullOrEmpty(cachedIdentityToken) || cachedIdentityToken === 'null' || sfMailApp.utils.isNullOrEmpty(lastUpdateIdentityTokenDifference) || force ||
        (lastUpdateIdentityTokenDifference / (1000 * 60)) > sfMailApp.settings.identityTokenUpdateIntervalMinutes) {
        var deferred = $.Deferred();

        var item = this.getItem();

        if (!item.isFake) {
            sfMailApp.analytics.trackEvent('LoadUserIdentityTokenAsync', 'Start', {
                user: sfMailApp.mailService.userEmail
            });

            this._loadItemAsync(Office.context.mailbox, 'getUserIdentityTokenAsync').done(function (token) {
                ls.setItem('identityTokenUpdate', new Date().getTime());
                ls.setItem('identityToken', token);
                sfMailApp.sessionManager.setIdentityToken(token);
                deferred.resolve(token);
            }).fail(function (err) {
                ls.setItem('identityTokenUpdate', null);
                ls.setItem('identityToken', null);
                sfMailApp.analytics.trackEvent('LoadUserIdentityTokenAsync', 'Fail', {
                    user: sfMailApp.mailService.userEmail,
                    message: err ? JSON.stringify(err) : 'null'
                });
                deferred.reject(err);
            });
        } else {
            sfMailApp.analytics.trackEvent('Item', 'Empty', {
                user: sfMailApp.mailService.userEmail,
                message: 'Error while getting identity token - inbox item is empty'
            });
            sfMailApp.sessionManager.setIdentityToken(cachedIdentityToken);
            return sfMailApp.utils.resolveDeferred(cachedIdentityToken);
        }

        return deferred.promise();
    } else {
        sfMailApp.sessionManager.setIdentityToken(cachedIdentityToken);
        return sfMailApp.utils.resolveDeferred(cachedIdentityToken);
    }
};


sfMailApp.OfficeManager.prototype._loadItemAsync = function (obj, name) {

    if (sfMailApp.utils.isCommands() && sfMailApp.isCommandsMagicPixel) {
        return sfMailApp.utils.rejectDeferred({
            message: 'Async Office JS API should not be called in Commands while inserting MagicPixel'
        });
    }

    var deferred = $.Deferred();

    var maxAttempCount = 5;
    var attempInterval = 1000;
    var attempCount = 0;
    var _this = this;

    function checkResult(asyncResult) {
        var processFunc = function () {
            try {
                if (_this._checkProperyExists(obj, name)) {
                    obj[name](checkResult);
                } else {
                    checkResult(null);
                }
            } catch (e) {
                if (name !== 'loadCustomPropertiesAsync' && name !== 'getCallbackTokenAsync') {
                    sfMailApp.analytics.trackException(e, name + '.Fail', {
                        user: sfMailApp.mailService.userEmail,
                        error: e ? JSON.stringify(e) : null
                    });
                }
                checkResult(null);
            }
        }

        if ((sfMailApp.utils.isNullOrEmpty(asyncResult) || asyncResult.status !== Office.AsyncResultStatus.Succeeded) && attempCount < maxAttempCount) {
            attempCount++;
            if (attempCount <= 1) {
                processFunc();
            } else {
                setTimeout(processFunc, attempInterval);
            }
        } else {
            if (asyncResult && asyncResult.status === Office.AsyncResultStatus.Succeeded) {
                deferred.resolve(asyncResult.value);
            } else {
                var params = {
                    user: sfMailApp.mailService.userEmail
                };
                if (asyncResult) {
                    params.status = asyncResult.status;
                    params.value = asyncResult.value;
                    params.error = JSON.stringify(asyncResult.error);
                }

                if (name !== 'loadCustomPropertiesAsync' && name !== 'getCallbackTokenAsync') {
                    sfMailApp.analytics.trackException(new Error(name + '.Fail'), '', params);
                }
                deferred.reject(asyncResult);
            }
        }
    }

    var inboxItem = this.getItem();

    if (obj && !obj.isFake && !inboxItem.isFake) {
        checkResult(null);
    } else {
        deferred.resolve({});
    }

    return deferred.promise();
};

person Sviatoslav Lobach    schedule 08.11.2017    source источник
comment
Можете ли вы предоставить код, который вы используете, что приводит к этой ошибке?   -  person Marc LaFleur    schedule 08.11.2017
comment
@MarcLaFleur спасибо за оперативный ответ, код прилагается.   -  person Sviatoslav Lobach    schedule 08.11.2017
comment
Я не вижу, где вы ссылаетесь на метод или свойство с именем Execute. На какой линии он не работает?   -  person Marc LaFleur    schedule 08.11.2017
comment
@Mark, пожалуйста, проверьте ссылку на URL-адрес скрипта. Это ваш код Office JS API appsforoffice.microsoft.com/lib/1 ...   -  person Sviatoslav Lobach    schedule 08.11.2017
comment
Я понимаю, но мне все еще не ясно, какой вызов в Office.js вызывает ошибку.   -  person Marc LaFleur    schedule 08.11.2017
comment
@MarcLaFleur, к сожалению, я не могу вам с этим помочь. После stackoverflow.com/questions/46294347/ исправлено, я могу предоставить подробную информацию.   -  person Sviatoslav Lobach    schedule 08.11.2017
comment
@MarcLaFleur кажется, что вызов window.reload устраняет проблему. Итак, мы добавили следующий обходной путь: перезагружать окно при обнаружении либо кода ошибки 9017, либо сообщения об ошибке AccessRestricted. Не могли бы вы подтвердить, что этот обходной путь можно использовать?   -  person Sviatoslav Lobach    schedule 11.11.2017


Ответы (1)


Спасибо, Святослав. Нам известно об этой проблеме, и мы ее расследуем. Мы обновим этот ответ, как только будет найдено исправление!

person Outlook Add-ins Team - MSFT    schedule 08.11.2017
comment
Я предполагаю, что вы все еще видите проблемы с вызовами useridentitytoken. Вы видите их в последних сборках Outlook? Если да, не могли бы вы поделиться недавним номером сборки? Мы добавили дополнительный параметр в объект asyncResult, называемый диагностикой, для вызовов токенов, который должен предоставить вам дополнительную информацию об ошибке. Это должно быть доступно в клиентах с версией ›16.0.10224.10000. Не могли бы вы взглянуть на это и посмотреть, поможет ли это с дополнительной информацией, и поделитесь здесь. К какой версии обмена подключается клиент? - person Outlook Add-ins Team - MSFT; 01.08.2019
comment
@ OutlookAdd-insTeam-MSFT В настоящее время у меня возникла эта ошибка. Моя версия - 16.35 20030802. Вы уже нашли решение? Может быть, я использую свой школьный адрес электронной почты в Outlook, а администратор ограничил определенный доступ к API? - person Rahmi Pruitt; 19.04.2020