Skip to content

Commit

Permalink
Fix: ProfileType persistence (#1074)
Browse files Browse the repository at this point in the history
  • Loading branch information
thewahome authored Aug 27, 2021
1 parent fe79593 commit da30d67
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 258 deletions.
19 changes: 11 additions & 8 deletions src/app/services/actions/permissions-action-creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { MessageBarType } from '@fluentui/react';
import { geLocale } from '../../../appLocale';
import { authenticationWrapper } from '../../../modules/authentication';
import { IAction } from '../../../types/action';
import { IUser } from '../../../types/profile';
import { IRequestOptions } from '../../../types/request';
import { IRootState } from '../../../types/root';
import { sanitizeQueryUrl } from '../../utils/query-url-sanitization';
Expand Down Expand Up @@ -44,15 +45,10 @@ export function fetchScopes(): Function {
return async (dispatch: Function, getState: Function) => {
let hasUrl = false; // whether permissions are for a specific url
try {
const { devxApi, permissionsPanelOpen, profileType, sampleQuery: query }: IRootState = getState();
const { devxApi, permissionsPanelOpen, profile, sampleQuery: query }: IRootState = getState();
let permissionsUrl = `${devxApi.baseUrl}/permissions`;
let scope = PERMS_SCOPE.WORK;

if (profileType === ACCOUNT_TYPE.AAD) {
scope = PERMS_SCOPE.WORK;
} else if (profileType === ACCOUNT_TYPE.MSA) {
scope = PERMS_SCOPE.PERSONAL;
}
const scopeType = getPermissionsScopeType(profile);

if (!permissionsPanelOpen) {
const signature = sanitizeQueryUrl(query.sampleUrl);
Expand All @@ -62,7 +58,7 @@ export function fetchScopes(): Function {
throw new Error('url is invalid');
}

permissionsUrl = `${permissionsUrl}?requesturl=/${requestUrl}&method=${query.selectedVerb}&scopeType=${scope}`;
permissionsUrl = `${permissionsUrl}?requesturl=/${requestUrl}&method=${query.selectedVerb}&scopeType=${scopeType}`;
hasUrl = true;
}

Expand Down Expand Up @@ -102,6 +98,13 @@ export function fetchScopes(): Function {
};
}

function getPermissionsScopeType(profile: IUser | null | undefined) {
if (profile?.profileType === ACCOUNT_TYPE.MSA) {
return PERMS_SCOPE.PERSONAL;
}
return PERMS_SCOPE.WORK;
}

export function consentToScopes(scopes: string[]): Function {
return async (dispatch: Function) => {
try {
Expand Down
122 changes: 76 additions & 46 deletions src/app/services/actions/profile-action-creators.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { IUser } from '../../../types/profile';
import { IQuery } from '../../../types/query-runner';
import { PROFILE_IMAGE_REQUEST_SUCCESS, PROFILE_REQUEST_ERROR, PROFILE_REQUEST_SUCCESS, PROFILE_TYPE_SUCCESS } from '../redux-constants';
import { authenticatedRequest, isBetaURLResponse, isImageResponse, parseResponse } from './query-action-creator-util';
import {
ACCOUNT_TYPE, BETA_USER_INFO_URL, DEFAULT_USER_SCOPES,
USER_INFO_URL, USER_PICTURE_URL
} from '../graph-constants';
import { PROFILE_REQUEST_ERROR, PROFILE_REQUEST_SUCCESS } from '../redux-constants';
import { makeRequest, parseResponse } from './query-action-creator-util';
import { queryRunningStatus } from './query-loading-action-creators';

export function profileRequestSuccess(response: object): any {
return {
Expand All @@ -9,64 +15,88 @@ export function profileRequestSuccess(response: object): any {
};
}

export function profileImageRequestSuccess(response: object): any {
return {
type: PROFILE_IMAGE_REQUEST_SUCCESS,
response,
};
}

export function profileRequestError(response: object): any {
return {
type: PROFILE_REQUEST_ERROR,
response,
};
}

export function profileTypeSuccess(response: any): any {
return {
type: PROFILE_TYPE_SUCCESS,
response,
}
const query: IQuery = {
selectedVerb: 'GET',
sampleHeaders: [{
name: 'Cache-Control',
value: 'no-cache'
}],
selectedVersion: '',
sampleUrl: ''
}

export function getProfileInfo(query: IQuery): Function {
return (dispatch: Function) => {
const respHeaders: any = {};

if (!query.sampleHeaders) {
query.sampleHeaders = [];
export function getProfileInfo(): Function {
return async (dispatch: Function) => {
dispatch(queryRunningStatus(true));
try {
const profile: IUser = await getProfileInformation();
profile.profileType = await getProfileType();
profile.profileImageUrl = await getProfileImage();
dispatch(profileRequestSuccess(profile));
} catch (error) {
dispatch(profileRequestError({ error }));
}
};
}

query.sampleHeaders.push({
name: 'Cache-Control',
value: 'no-cache'
});
async function getProfileInformation(): Promise<IUser> {
const profile: IUser = {
displayName: '',
emailAddress: '',
profileImageUrl: '',
};
try {
query.sampleUrl = USER_INFO_URL;
const { userInfo } = await getProfileResponse();
profile.displayName = userInfo.displayName;
profile.emailAddress = userInfo.mail || userInfo.userPrincipalName;
return profile;
} catch (error) {
throw error;
}
}

return authenticatedRequest(dispatch, query).then(async (response: Response) => {
async function getProfileType(): Promise<ACCOUNT_TYPE> {
try {
query.sampleUrl = BETA_USER_INFO_URL;
const { userInfo } = await getProfileResponse();
return userInfo?.account?.[0]?.source?.type?.[0];
} catch (error) {
return ACCOUNT_TYPE.MSA;
}
}

if (response && response.ok) {
const json = await parseResponse(response, respHeaders);
const contentType = respHeaders['content-type'];
const isImageResult = isImageResponse(contentType);
const isBetaUserResult = isBetaURLResponse(json);
async function getProfileImage(): Promise<string> {
let profileImageUrl = '';
try {
query.sampleUrl = USER_PICTURE_URL;
const { response, userInfo: userPicture } = await getProfileResponse();
if (userPicture) {
const buffer = await response.arrayBuffer();
const blob = new Blob([buffer], { type: 'image/jpeg' });
profileImageUrl = URL.createObjectURL(blob);
}
} catch (error) {
return profileImageUrl;
}
return profileImageUrl;
}

if (isImageResult) {
return dispatch(
profileImageRequestSuccess(json),
);
} else if (isBetaUserResult) {
return dispatch(
profileTypeSuccess(json?.account?.[0]?.source?.type?.[0])
);
} else {
return dispatch(
profileRequestSuccess(json),
);
}
}
return dispatch(profileRequestError({ response }));
});
async function getProfileResponse() {
const scopes = DEFAULT_USER_SCOPES.split(' ');
const respHeaders: any = {};

const response = await makeRequest(query.selectedVerb, scopes)(query);
const userInfo = await parseResponse(response, respHeaders);
return {
userInfo,
response
};
}
16 changes: 6 additions & 10 deletions src/app/services/actions/query-action-creator-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,10 @@ export function createAnonymousRequest(query: IQuery, proxyUrl: string) {
return { graphUrl, options };
}

export function authenticatedRequest(
dispatch: Function,
query: IQuery,
scopes: string[] = DEFAULT_USER_SCOPES.split(' ')
) {
return makeRequest(query.selectedVerb, scopes)(dispatch, query);
export function authenticatedRequest(dispatch: Function, query: IQuery,
scopes: string[] = DEFAULT_USER_SCOPES.split(' ')) {
dispatch(queryRunningStatus(true));
return makeRequest(query.selectedVerb, scopes)(query);
}

export function isImageResponse(contentType: string | undefined) {
Expand Down Expand Up @@ -107,8 +105,8 @@ export function parseResponse(response: any, respHeaders: any): Promise<any> {
return response;
}

const makeRequest = (httpVerb: string, scopes: string[]): Function => {
return async (dispatch: Function, query: IQuery) => {
export function makeRequest(httpVerb: string, scopes: string[]): Function {
return async (query: IQuery) => {
const sampleHeaders: any = {};
sampleHeaders.SdkVersion = 'GraphExplorer/4.0';

Expand All @@ -131,8 +129,6 @@ const makeRequest = (httpVerb: string, scopes: string[]): Function => {

let response;

dispatch(queryRunningStatus(true));

switch (httpVerb) {
case 'GET':
response = await client.get();
Expand Down
5 changes: 2 additions & 3 deletions src/app/services/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { dimensions } from './dimensions-reducers';
import { permissionsPanelOpen } from './permissions-panel-reducer';
import { graphExplorerMode } from './graph-explorer-mode-reducer';
import { scopes } from './permissions-reducer';
import { profile, profileType } from './profile-reducer';
import { profile } from './profile-reducer';
import { sampleQuery } from './query-input-reducers';
import { isLoadingData } from './query-loading-reducers';
import { graphResponse } from './query-runner-reducers';
Expand Down Expand Up @@ -43,6 +43,5 @@ export default combineReducers({
termsOfUse,
theme,
dimensions,
permissionsPanelOpen,
profileType
permissionsPanelOpen
});
14 changes: 2 additions & 12 deletions src/app/services/reducers/profile-reducer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { IAction } from '../../../types/action';
import { ACCOUNT_TYPE } from '../graph-constants';
import { LOGOUT_SUCCESS, PROFILE_REQUEST_SUCCESS, PROFILE_TYPE_SUCCESS } from '../redux-constants';
import { LOGOUT_SUCCESS, PROFILE_REQUEST_SUCCESS } from '../redux-constants';

export function profile(state = null, action: IAction): any {
switch (action.type) {
Expand All @@ -11,13 +10,4 @@ export function profile(state = null, action: IAction): any {
default:
return state;
}
}

export function profileType(state = ACCOUNT_TYPE.AAD, action: IAction): any {
switch (action.type) {
case PROFILE_TYPE_SUCCESS:
return action.response
default:
return state;
}
}
}
3 changes: 0 additions & 3 deletions src/app/services/reducers/query-loading-reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { IAction } from '../../../types/action';
import {
FETCH_SCOPES_ERROR,
GET_CONSENT_ERROR,
PROFILE_IMAGE_REQUEST_SUCCESS,
PROFILE_REQUEST_ERROR,
PROFILE_REQUEST_SUCCESS,
QUERY_GRAPH_RUNNING,
Expand All @@ -28,8 +27,6 @@ export function isLoadingData(state = {}, action: IAction): any {
return false;
case PROFILE_REQUEST_SUCCESS:
return false;
case PROFILE_IMAGE_REQUEST_SUCCESS:
return false;
default:
return state;
}
Expand Down
2 changes: 0 additions & 2 deletions src/app/services/redux-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export const HEADER_REMOVE_SUCCESS = 'HEADER_REMOVE_SUCCESS';
export const SET_GRAPH_EXPLORER_MODE_SUCCESS = 'SET_GRAPH_EXPLORER_MODE_SUCCESS';
export const SET_SAMPLE_QUERY_SUCCESS = 'SET_SAMPLE_QUERY_SUCCESS';
export const PROFILE_REQUEST_SUCCESS = 'PROFILE_REQUEST_SUCCESS';
export const PROFILE_IMAGE_REQUEST_SUCCESS = 'PROFILE_IMAGE_REQUEST_SUCCESS';
export const PROFILE_REQUEST_ERROR = 'PROFILE_REQUEST_ERROR';
export const GET_SNIPPET_SUCCESS = 'GET_SNIPPET_SUCCESS';
export const GET_SNIPPET_ERROR = 'GET_SNIPPET_ERROR';
Expand Down Expand Up @@ -43,4 +42,3 @@ export const RESPONSE_EXPANDED = 'RESPONSE_EXPANDED';
export const PERMISSIONS_PANEL_OPEN = 'PERMISSIONS_PANEL_OPEN';
export const AUTHENTICATION_PENDING = 'AUTHENTICATION_PENDING';
export const SET_GRAPH_PROXY_URL = 'SET_GRAPH_PROXY_URL';
export const PROFILE_TYPE_SUCCESS = 'PROFILE_TYPE_SUCCESS';
Loading

0 comments on commit da30d67

Please sign in to comment.