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

[MOB-9954]: Fix Circular Dependency and Clean Up Auth Checks on API Calls #467

Merged
merged 11 commits into from
Oct 17, 2024
51 changes: 33 additions & 18 deletions src/anonymousUserTracking/tests/userMergeScenarios.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,14 @@ describe('UserMergeScenariosTests', () => {
console.log('', e);
}
// this function call is needed for putting some delay before executing setUserId
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
try {
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
} catch (e) {
console.log(e);
}
await setUserID('testuser123');
expect(localStorageMock.removeItem).toHaveBeenCalledWith(
SHARED_PREF_ANON_USER_ID
Expand Down Expand Up @@ -342,10 +346,14 @@ describe('UserMergeScenariosTests', () => {
} catch (e) {
console.log('', e);
}
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
try {
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
} catch (e) {
console.log(e);
}
await setUserID('testuser123');
expect(localStorageMock.removeItem).toHaveBeenCalledWith(
SHARED_PREF_ANON_USER_ID
Expand Down Expand Up @@ -599,7 +607,7 @@ describe('UserMergeScenariosTests', () => {
}
return null;
});
const { setEmail, logout } = initializeWithConfig({
const { setEmail } = initializeWithConfig({
authToken: '123',
configOptions: {
enableAnonTracking: true,
Expand All @@ -609,16 +617,19 @@ describe('UserMergeScenariosTests', () => {
}
}
});
logout(); // logout to remove logged in users before this test
try {
await track({ eventName: 'testEvent' });
} catch (e) {
console.log('', e);
}
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
try {
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
} catch (e) {
console.log(e);
}
await setEmail('testuser123@test.com');
expect(localStorageMock.removeItem).toHaveBeenCalledWith(
SHARED_PREF_ANON_USER_ID
Expand Down Expand Up @@ -661,10 +672,14 @@ describe('UserMergeScenariosTests', () => {
} catch (e) {
console.log('', e);
}
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
try {
await getInAppMessages({
count: 10,
packageName: 'my-lil-website'
});
} catch (e) {
console.log(e);
}
await setEmail('testuser123@test.com');
expect(localStorageMock.removeItem).toHaveBeenCalledWith(
SHARED_PREF_ANON_USER_ID
Expand Down
3 changes: 1 addition & 2 deletions src/authorization/authorization.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1117,8 +1117,7 @@ describe('User Identification', () => {
.fn()
.mockReturnValue(Promise.resolve(MOCK_JWT_KEY));
const { refreshJwtToken } = initialize('123', mockGenerateJWT);
const res = await refreshJwtToken('hello@gmail.com');
console.log({ res });
await refreshJwtToken('hello@gmail.com');
expect(mockGenerateJWT).toHaveBeenCalledTimes(1);
jest.advanceTimersByTime(60000 * 4.1);
expect(mockGenerateJWT).toHaveBeenCalledTimes(2);
Expand Down
38 changes: 14 additions & 24 deletions src/authorization/authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,9 @@ import {
registerAnonUserIdSetter
} from 'src/anonymousUserTracking/anonymousUserEventManager';
import { IdentityResolution, Options, config } from 'src/utils/config';
import { getTypeOfAuth, setTypeOfAuth, TypeOfAuth } from 'src/utils/typeOfAuth';

const MAX_TIMEOUT = ONE_DAY;
/*
AKA did the user auth with their email (setEmail) or user ID (setUserID)

we're going to use this variable for one circumstance - when calling _updateUserEmail_.
Essentially, when we call the Iterable API to update a user's email address and we get a
successful 200 request, we're going to request a new JWT token, since it might need to
be re-signed with the new email address; however, if the customer code never authorized the
user with an email and instead a user ID, we'll just continue to sign the JWT with the user ID.

This is mainly just a quality-of-life feature, so that the customer's JWT generation code
doesn't _need_ to support email-signed JWTs if they don't want and purely want to issue the
tokens by user ID.
*/
export type TypeOfAuth = null | 'email' | 'userID'
export let typeOfAuth: TypeOfAuth = null;
/* this will be the literal user ID or email they choose to auth with */
let authIdentifier: null | string = null;
let userInterceptor: number | null = null;
let apiKey: null | string = null;
Expand Down Expand Up @@ -124,7 +109,7 @@ const initializeUserId = (userId: string) => {
}

const addUserIdToRequest = (userId: string) => {
typeOfAuth = 'userID';
setTypeOfAuth('userID');
authIdentifier = userId;

if (typeof userInterceptor === 'number') {
Expand Down Expand Up @@ -230,7 +215,7 @@ const syncEvents = () => {
};

const addEmailToRequest = (email: string) => {
typeOfAuth = 'email';
setTypeOfAuth('email');
authIdentifier = email;

if (typeof userInterceptor === 'number') {
Expand Down Expand Up @@ -426,6 +411,7 @@ export function initialize(
isEmail: boolean,
merge?: boolean
): Promise<boolean> => {
const typeOfAuth = getTypeOfAuth();
const enableAnonTracking = config.getConfig('enableAnonTracking');
const sourceUserIdOrEmail =
authIdentifier === null ? getAnonUserId() : authIdentifier;
Expand Down Expand Up @@ -519,7 +505,7 @@ export function initialize(
},
logout: () => {
anonUserManager.removeAnonSessionCriteriaData();
typeOfAuth = null;
setTypeOfAuth(null);
authIdentifier = null;
/* clear fetched in-app messages */
clearMessages();
Expand Down Expand Up @@ -552,7 +538,7 @@ export function initialize(
localStorage.removeItem(SHARED_PREF_ANON_USER_ID);
localStorage.removeItem(SHARED_PREF_ANON_USAGE_TRACKED);

typeOfAuth = null;
setTypeOfAuth(null);
authIdentifier = null;
/* clear fetched in-app messages */
clearMessages();
Expand Down Expand Up @@ -633,7 +619,7 @@ export function initialize(
const newEmail = JSON.parse(config.config.data)?.newEmail;

const payloadToPass =
typeOfAuth === 'email'
getTypeOfAuth() === 'email'
? { email: newEmail }
: { userID: authIdentifier! };

Expand Down Expand Up @@ -894,7 +880,7 @@ export function initialize(
},
logout: () => {
anonUserManager.removeAnonSessionCriteriaData();
typeOfAuth = null;
setTypeOfAuth(null);
authIdentifier = null;
/* clear fetched in-app messages */
clearMessages();
Expand Down Expand Up @@ -941,7 +927,7 @@ export function initialize(
localStorage.removeItem(SHARED_PREF_ANON_USER_ID);
localStorage.removeItem(SHARED_PREF_ANON_USAGE_TRACKED);

typeOfAuth = null;
setTypeOfAuth(null);
authIdentifier = null;
/* clear fetched in-app messages */
clearMessages();
Expand Down Expand Up @@ -984,5 +970,9 @@ export function initializeWithConfig(initializeParams: InitializeParams) {
}

export function setTypeOfAuthForTestingOnly(authType: TypeOfAuth) {
typeOfAuth = authType
if (!authType) {
setTypeOfAuth(null);
} else {
setTypeOfAuth(authType);
}
}
9 changes: 0 additions & 9 deletions src/commerce/commerce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { IterableResponse } from '../types';
import { updateCartSchema, trackPurchaseSchema } from './commerce.schema';
import { AnonymousUserEventManager } from '../anonymousUserTracking/anonymousUserEventManager';
import { canTrackAnonUser } from '../utils/commonFunctions';
import { typeOfAuth } from '../authorization';

export const updateCart = (payload: UpdateCartRequestParams) => {
/* a customer could potentially send these up if they're not using TypeScript */
Expand All @@ -20,10 +19,6 @@ export const updateCart = (payload: UpdateCartRequestParams) => {
return Promise.reject(INITIALIZE_ERROR);
}

if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}

return baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.commerce_update_cart.route,
Expand Down Expand Up @@ -52,10 +47,6 @@ export const trackPurchase = (payload: TrackPurchaseRequestParams) => {
return Promise.reject(INITIALIZE_ERROR);
}

if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}

return baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.commerce_track_purchase.route,
Expand Down
16 changes: 3 additions & 13 deletions src/embedded/embeddedManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,9 @@ import {
import { IterableResponse } from '../types';
import { EmbeddedMessagingProcessor } from './embeddedMessageProcessor';
import { ErrorMessage } from './consts';
import {
SDK_VERSION,
WEB_PLATFORM,
ENDPOINTS,
INITIALIZE_ERROR
} from '../constants';
import { SDK_VERSION, WEB_PLATFORM, ENDPOINTS } from '../constants';
import { trackEmbeddedReceived } from '../events/embedded/events';
import { handleEmbeddedClick } from './utils';
import { typeOfAuth } from '../authorization';

export class IterableEmbeddedManager {
public appPackageName: string;
Expand All @@ -33,12 +27,8 @@ export class IterableEmbeddedManager {
callback: () => void,
placementIds?: number[]
) {
if (typeOfAuth !== null) {
await this.retrieveEmbeddedMessages(packageName, placementIds || []);
callback();
} else {
Promise.reject(INITIALIZE_ERROR);
}
await this.retrieveEmbeddedMessages(packageName, placementIds || []);
callback();
}

private async retrieveEmbeddedMessages(
Expand Down
24 changes: 3 additions & 21 deletions src/events/embedded/events.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { WEB_PLATFORM, ENDPOINTS, INITIALIZE_ERROR } from '../../constants';
import { WEB_PLATFORM, ENDPOINTS } from '../../constants';
import { baseIterableRequest } from '../../request';
import {
IterableEmbeddedDismissRequestPayload,
Expand All @@ -12,17 +12,12 @@ import {
embeddedDismissSchema,
embeddedSessionSchema
} from './events.schema';
import { typeOfAuth } from '../../authorization';

export const trackEmbeddedReceived = (
messageId: string,
appPackageName: string
) => {
if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}

return baseIterableRequest<IterableResponse>({
) =>
baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.msg_received_event_track.route,
data: {
Expand All @@ -37,17 +32,12 @@ export const trackEmbeddedReceived = (
data: trackEmbeddedSchema
}
});
};

export const trackEmbeddedClick = (
payload: IterableEmbeddedClickRequestPayload
) => {
const { appPackageName, ...rest } = payload;

if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}

return baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.msg_click_event_track.route,
Expand All @@ -71,10 +61,6 @@ export const trackEmbeddedDismiss = (
) => {
const { appPackageName, ...rest } = payload;

if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}

return baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.msg_dismiss.route,
Expand All @@ -98,10 +84,6 @@ export const trackEmbeddedSession = (
) => {
const { appPackageName, ...rest } = payload;

if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}

return baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.msg_session_event_track.route,
Expand Down
4 changes: 0 additions & 4 deletions src/events/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { IterableResponse } from '../types';
import { trackSchema } from './events.schema';
import { AnonymousUserEventManager } from '../anonymousUserTracking/anonymousUserEventManager';
import { canTrackAnonUser } from '../utils/commonFunctions';
import { typeOfAuth } from '../authorization';

export const track = (payload: InAppTrackRequestParams) => {
/* a customer could potentially send these up if they're not using TypeScript */
Expand All @@ -17,9 +16,6 @@ export const track = (payload: InAppTrackRequestParams) => {
anonymousUserEventManager.trackAnonEvent(payload);
return Promise.reject(INITIALIZE_ERROR);
}
if (typeOfAuth === null) {
return Promise.reject(INITIALIZE_ERROR);
}
return baseIterableRequest<IterableResponse>({
method: 'POST',
url: ENDPOINTS.event_track.route,
Expand Down
Loading
Loading