Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated all storage functions to async #559

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 6 additions & 45 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

95 changes: 48 additions & 47 deletions src/scripts/extensions/authenticationHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,59 +39,60 @@ export class AuthenticationHelper {
return new Promise<UserInfo>((resolve) => {
let updateInterval = 0;

let storedUserInformation = this.clipperData.getValue(ClipperStorageKeys.userInformation);
if (storedUserInformation) {
let currentInfo: any;
try {
currentInfo = JSON.parse(storedUserInformation);
} catch (e) {
this.logger.logJsonParseUnexpected(storedUserInformation);
}
this.clipperData.getValue(ClipperStorageKeys.userInformation).then((storedUserInformation) => {
if (storedUserInformation) {
let currentInfo: any;
try {
currentInfo = JSON.parse(storedUserInformation);
} catch (e) {
this.logger.logJsonParseUnexpected(storedUserInformation);
}

if (currentInfo && currentInfo.data && ObjectUtils.isNumeric(currentInfo.data.accessTokenExpiration)) {
// Expiration is in seconds, not milliseconds. Give additional leniency to account for response time.
updateInterval = Math.max((currentInfo.data.accessTokenExpiration * 1000) - 180000, 0);
if (currentInfo && currentInfo.data && ObjectUtils.isNumeric(currentInfo.data.accessTokenExpiration)) {
// Expiration is in seconds, not milliseconds. Give additional leniency to account for response time.
updateInterval = Math.max((currentInfo.data.accessTokenExpiration * 1000) - 180000, 0);
}
}
}

let getUserInformationFunction = () => {
return this.retrieveUserInformation(clipperId, undefined);
};

let getInfoEvent: Log.Event.PromiseEvent = new Log.Event.PromiseEvent(Log.Event.Label.GetExistingUserInformation);
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.UserInformationStored, !!storedUserInformation);
this.clipperData.getFreshValue(ClipperStorageKeys.userInformation, getUserInformationFunction, updateInterval).then(async (response: TimeStampedData) => {
let isValidUser = this.isValidUserInformation(response.data);
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.FreshUserInfoAvailable, isValidUser);

let writeableCookies = this.isThirdPartyCookiesEnabled(response.data);
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.WriteableCookies, writeableCookies);

getInfoEvent.setCustomProperty(Log.PropertyName.Custom.UserUpdateReason, UpdateReason[updateReason]);

if (isValidUser) {
const dataBoundaryHelper = new UserDataBoundaryHelper();
let userDataBoundary: string = await dataBoundaryHelper.getUserDataBoundary(response.data);
// The default logging has been configured to EU Pipeline. Once we find the
// userdataboundary and if it is different from EUDB , reinit the logger with WW Pipeline
if (userDataBoundary === DataBoundary[DataBoundary.GLOBAL] || userDataBoundary === DataBoundary[DataBoundary.PUBLIC]) {
LogManager.reInitLoggerForDataBoundaryChange(userDataBoundary);
let getUserInformationFunction = () => {
return this.retrieveUserInformation(clipperId, undefined);
};

let getInfoEvent: Log.Event.PromiseEvent = new Log.Event.PromiseEvent(Log.Event.Label.GetExistingUserInformation);
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.UserInformationStored, !!storedUserInformation);
this.clipperData.getFreshValue(ClipperStorageKeys.userInformation, getUserInformationFunction, updateInterval).then(async (response: TimeStampedData) => {
let isValidUser = this.isValidUserInformation(response.data);
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.FreshUserInfoAvailable, isValidUser);

let writeableCookies = this.isThirdPartyCookiesEnabled(response.data);
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.WriteableCookies, writeableCookies);

getInfoEvent.setCustomProperty(Log.PropertyName.Custom.UserUpdateReason, UpdateReason[updateReason]);

if (isValidUser) {
const dataBoundaryHelper = new UserDataBoundaryHelper();
let userDataBoundary: string = await dataBoundaryHelper.getUserDataBoundary(response.data);
// The default logging has been configured to EU Pipeline. Once we find the
// userdataboundary and if it is different from EUDB , reinit the logger with WW Pipeline
if (userDataBoundary === DataBoundary[DataBoundary.GLOBAL] || userDataBoundary === DataBoundary[DataBoundary.PUBLIC]) {
LogManager.reInitLoggerForDataBoundaryChange(userDataBoundary);
}
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.DataBoundary, userDataBoundary);
response.data.dataBoundary = userDataBoundary;
this.user.set({ user: response.data, lastUpdated: response.lastUpdated, updateReason: updateReason, writeableCookies: writeableCookies });
} else {
this.user.set({ updateReason: updateReason, writeableCookies: writeableCookies });
}
getInfoEvent.setCustomProperty(Log.PropertyName.Custom.DataBoundary, userDataBoundary);
response.data.dataBoundary = userDataBoundary;
this.user.set({ user: response.data, lastUpdated: response.lastUpdated, updateReason: updateReason, writeableCookies: writeableCookies });
} else {
this.user.set({ updateReason: updateReason, writeableCookies: writeableCookies });
}

}, (error: OneNoteApi.GenericError) => {
getInfoEvent.setStatus(Log.Status.Failed);
getInfoEvent.setFailureInfo(error);
this.user.set({ updateReason: updateReason });
}).then(() => {
this.logger.logEvent(getInfoEvent);
}, (error: OneNoteApi.GenericError) => {
getInfoEvent.setStatus(Log.Status.Failed);
getInfoEvent.setFailureInfo(error);
this.user.set({ updateReason: updateReason });
}).then(() => {
this.logger.logEvent(getInfoEvent);

resolve(this.user.get());
resolve(this.user.get());
});
});
});
}
Expand Down
94 changes: 50 additions & 44 deletions src/scripts/extensions/extensionBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,31 @@ export abstract class ExtensionBase<TWorker extends ExtensionWorkerBase<TTab, TT

let clipperFirstRun = false;

let clipperId = this.clipperData.getValue(ClipperStorageKeys.clipperId);
if (!clipperId) {
// New install
clipperFirstRun = true;
clipperId = ExtensionBase.generateClipperId();
this.clipperData.setValue(ClipperStorageKeys.clipperId, clipperId);

// Ensure fresh installs don't trigger thats What's New experience
this.updateLastSeenVersionInStorageToCurrent();
}
this.clipperData.getValue(ClipperStorageKeys.clipperId).then((clipperId) => {
if (!clipperId) {
// New install
clipperFirstRun = true;
clipperId = ExtensionBase.generateClipperId();
this.clipperData.setValue(ClipperStorageKeys.clipperId, clipperId);

// Ensure fresh installs don't trigger thats What's New experience
this.updateLastSeenVersionInStorageToCurrent();
}

this.clientInfo = new SmartValue<ClientInfo>({
clipperType: clipperType,
clipperVersion: ExtensionBase.getExtensionVersion(),
clipperId: clipperId
});
this.clientInfo = new SmartValue<ClientInfo>({
clipperType: clipperType,
clipperVersion: ExtensionBase.getExtensionVersion(),
clipperId: clipperId
});

if (clipperFirstRun) {
this.onFirstRun();
}
if (clipperFirstRun) {
this.onFirstRun();
}

this.initializeUserFlighting();
this.initializeUserFlighting();

this.listenForOpportunityToShowPageNavTooltip();
this.listenForOpportunityToShowPageNavTooltip();
});
}

protected abstract addPageNavListener(callback: (tab: TTab) => void);
Expand Down Expand Up @@ -174,14 +175,14 @@ export abstract class ExtensionBase<TWorker extends ExtensionWorkerBase<TTab, TT
/**
* Gets the last seen version from storage, and returns undefined if there is none in storage
*/
protected getLastSeenVersion(): Version {
let lastSeenVersionStr = this.clipperData.getValue(ClipperStorageKeys.lastSeenVersion);
protected async getLastSeenVersion(): Promise<Version> {
let lastSeenVersionStr = await this.clipperData.getValue(ClipperStorageKeys.lastSeenVersion);
return lastSeenVersionStr ? new Version(lastSeenVersionStr) : undefined;
}

protected getNewUpdates(lastSeenVersion: Version, currentVersion: Version): Promise<ChangeLog.Update[]> {
return new Promise<ChangeLog.Update[]>((resolve, reject) => {
let localeOverride = this.clipperData.getValue(ClipperStorageKeys.displayLanguageOverride);
return new Promise<ChangeLog.Update[]>(async(resolve, reject) => {
let localeOverride = await this.clipperData.getValue(ClipperStorageKeys.displayLanguageOverride);
let localeToGet = localeOverride || navigator.language || (<any>navigator).userLanguage;
let changelogUrl = UrlUtils.addUrlQueryValue(Constants.Urls.changelogUrl, Constants.Urls.QueryParams.changelogLocale, localeToGet);
HttpWithRetries.get(changelogUrl).then((response: Response) => {
Expand Down Expand Up @@ -263,17 +264,23 @@ export abstract class ExtensionBase<TWorker extends ExtensionWorkerBase<TTab, TT
let worker = this.getOrCreateWorkerForTab(tab, this.getIdFromTab);
let tooltipImpressionEvent = new Log.Event.BaseEvent(Log.Event.Label.TooltipImpression);
tooltipImpressionEvent.setCustomProperty(Log.PropertyName.Custom.TooltipType, TooltipType[tooltipType]);
tooltipImpressionEvent.setCustomProperty(Log.PropertyName.Custom.LastSeenTooltipTime, this.tooltip.getTooltipInformation(ClipperStorageKeys.lastSeenTooltipTimeBase, tooltipType));
tooltipImpressionEvent.setCustomProperty(Log.PropertyName.Custom.NumTimesTooltipHasBeenSeen, this.tooltip.getTooltipInformation(ClipperStorageKeys.numTimesTooltipHasBeenSeenBase, tooltipType));
let lastSeenTooltipTimeBase = this.tooltip.getTooltipInformation(ClipperStorageKeys.lastSeenTooltipTimeBase, tooltipType);
let numTimesTooltipHasBeenSeenBase = this.tooltip.getTooltipInformation(ClipperStorageKeys.numTimesTooltipHasBeenSeenBase, tooltipType);
worker.invokeTooltip(tooltipType).then((wasInvoked) => {
if (wasInvoked) {
this.tooltip.setTooltipInformation(ClipperStorageKeys.lastSeenTooltipTimeBase, tooltipType, Date.now().toString());
let numSeenStorageKey = ClipperStorageKeys.numTimesTooltipHasBeenSeenBase;
let numTimesSeen = this.tooltip.getTooltipInformation(numSeenStorageKey, tooltipType) + 1;
this.tooltip.setTooltipInformation(ClipperStorageKeys.numTimesTooltipHasBeenSeenBase, tooltipType, numTimesSeen.toString());
this.tooltip.getTooltipInformation(numSeenStorageKey, tooltipType).then((value) => {
let numTimesSeen = value + 1;
this.tooltip.setTooltipInformation(ClipperStorageKeys.numTimesTooltipHasBeenSeenBase, tooltipType, numTimesSeen.toString());
});
}
tooltipImpressionEvent.setCustomProperty(Log.PropertyName.Custom.FeatureEnabled, wasInvoked);
worker.getLogger().logEvent(tooltipImpressionEvent);
Promise.all([lastSeenTooltipTimeBase, numTimesTooltipHasBeenSeenBase]).then((values) => {
tooltipImpressionEvent.setCustomProperty(Log.PropertyName.Custom.LastSeenTooltipTime, values[0]);
tooltipImpressionEvent.setCustomProperty(Log.PropertyName.Custom.NumTimesTooltipHasBeenSeen, values[1]);
worker.getLogger().logEvent(tooltipImpressionEvent);
});
});
}

Expand Down Expand Up @@ -320,17 +327,6 @@ export abstract class ExtensionBase<TWorker extends ExtensionWorkerBase<TTab, TT
*/
private listenForOpportunityToShowPageNavTooltip() {
this.addPageNavListener((tab: TTab) => {
// Fallback behavior for if the last seen version in storage is somehow in a corrupted format
let lastSeenVersion: Version;
try {
lastSeenVersion = this.getLastSeenVersion();
} catch (e) {
this.updateLastSeenVersionInStorageToCurrent();
return;
}

let extensionVersion = new Version(ExtensionBase.getExtensionVersion());

if (this.clientInfo.get().clipperType !== ClientType.FirefoxExtension) {
let tooltips = [TooltipType.Pdf, TooltipType.Product, TooltipType.Recipe];
// Returns the Type of tooltip to show IF the delay is over and the tab has the correct content type
Expand All @@ -346,10 +342,20 @@ export abstract class ExtensionBase<TWorker extends ExtensionWorkerBase<TTab, TT
}
}

// We don't show updates more recent than the local version for now, as it is easy
// for a changelog to be released before a version is actually out
if (this.shouldShowWhatsNewTooltip(tab, lastSeenVersion, extensionVersion)) {
this.showWhatsNewTooltip(tab, lastSeenVersion, extensionVersion);
let extensionVersion = new Version(ExtensionBase.getExtensionVersion());

// Fallback behavior for if the last seen version in storage is somehow in a corrupted format
try {
this.getLastSeenVersion().then((lastSeenVersion) => {
// We don't show updates more recent than the local version for now, as it is easy
// for a changelog to be released before a version is actually out
if (this.shouldShowWhatsNewTooltip(tab, lastSeenVersion, extensionVersion)) {
this.showWhatsNewTooltip(tab, lastSeenVersion, extensionVersion);
return;
}
});
} catch (e) {
this.updateLastSeenVersionInStorageToCurrent();
return;
}
});
Expand Down
Loading