Skip to content

Commit

Permalink
feat: add support to fetch memberGroups
Browse files Browse the repository at this point in the history
  • Loading branch information
rakibansary committed Aug 20, 2021
1 parent e713264 commit b72d035
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 12 deletions.
3 changes: 2 additions & 1 deletion __tests__/__snapshots__/index.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ exports[`Library interface test 1`] = `
Object {
"actions": Object {
"auth": Object {
"getMemberGroups": [Function],
"getAuthenticatedMemberGroups": [Function],
"loadProfile": [Function],
"setTcTokenV2": [Function],
"setTcTokenV3": [Function],
Expand Down Expand Up @@ -54,6 +54,7 @@ Object {
"dropGroups": [Function],
"getGroupsDone": [Function],
"getGroupsInit": [Function],
"getMemberGroups": [Function],
},
"looker": Object {
"getLookerDone": [Function],
Expand Down
2 changes: 1 addition & 1 deletion __tests__/reducers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const photoURL = 'http://url';
const mockActions = {
auth: {
loadProfile: mockAction('LOAD_PROFILE', Promise.resolve('Profile')),
getMemberGroups: mockAction('GET_MEMBER_GROUPS', Promise.resolve(['Group'])),
getAuthenticatedMemberGroups: mockAction('GET_AUTHENTICATED_MEMBER_GROUPS', Promise.resolve(['Group'])),
setTcTokenV2: mockAction('SET_TC_TOKEN_V2', 'Token V2'),
setTcTokenV3: mockAction('SET_TC_TOKEN_V3', 'Token V3'),
},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"lint:js": "./node_modules/.bin/eslint --ext .js,.jsx .",
"test": "npm run lint && npm run jest"
},
"version": "1000.27.15",
"version": "1000.27.16",
"dependencies": {
"auth0-js": "^6.8.4",
"config": "^3.2.0",
Expand Down
9 changes: 4 additions & 5 deletions src/actions/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { createActions } from 'redux-actions';
import { decodeToken } from '@topcoder-platform/tc-auth-lib';
import { getApiV3, getApiV5 } from '../services/api';
import { setErrorIcon, ERROR_ICON_TYPES } from '../utils/errors';
import { getService } from '../services/groups';

/**
* Helper method that checks for HTTP error response v5 and throws Error in this case.
Expand Down Expand Up @@ -77,19 +78,17 @@ function setTcTokenV3(tokenV3) {
* @param {*} tokenV3 the member's token
* @returns
*/
async function getMemberGroups(tokenV3) {
async function getAuthenticatedMemberGroups(tokenV3) {
if (!tokenV3) return Promise.resolve([]);
const user = decodeToken(tokenV3);
const apiV5 = getApiV5(tokenV3);
const res = await apiV5.get(`/groups/memberGroups/${user.userId}`).then(checkErrorV5).then(r => r.result || []);
return res;
return getService(tokenV3).getMemberGroups(user.userId);
}

export default createActions({
AUTH: {
LOAD_PROFILE: loadProfileDone,
SET_TC_TOKEN_V2: setTcTokenV2,
SET_TC_TOKEN_V3: setTcTokenV3,
GET_MEMBER_GROUPS: getMemberGroups,
GET_AUTHENTICATED_MEMBER_GROUPS: getAuthenticatedMemberGroups,
},
});
11 changes: 11 additions & 0 deletions src/actions/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,21 @@ function getGroupsDone(groupIds, tokenV3) {
return getService(tokenV3).getGroupMap(groupIds);
}

/**
* Get groups that a member belong to
* @param {*} userId the member's userId
* @param {*} tokenV3 the logged in users token
* @returns
*/
function getMemberGroups(userId, tokenV3) {
return getService(tokenV3).getMemberGroups(userId);
}

export default createActions({
GROUPS: {
DROP_GROUPS: dropGroups,
GET_GROUPS_INIT: getGroupsInit,
GET_GROUPS_DONE: getGroupsDone,
GET_MEMBER_GROUPS: getMemberGroups,
},
});
8 changes: 4 additions & 4 deletions src/reducers/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { redux } from 'topcoder-react-utils';
import actions from '../actions/auth';
import profileActions from '../actions/profile';

function onGetMemberGroups(state, action) {
function onGetAuthenticatedMemberGroups(state, action) {
return { ...state, memberGroups: action.payload };
}

Expand All @@ -43,7 +43,7 @@ function onProfileLoaded(state, action) {
*/
function create(initialState) {
return redux.handleActions({
[actions.auth.getMemberGroups]: onGetMemberGroups,
[actions.auth.getAuthenticatedMemberGroups]: onGetAuthenticatedMemberGroups,
[actions.auth.loadProfile]: onProfileLoaded,
[actions.auth.setTcTokenV2]: (state, action) => ({
...state,
Expand Down Expand Up @@ -134,10 +134,10 @@ export async function factory(options = {}) {
if (state.tokenV3) {
state.user = decodeToken(state.tokenV3);
let a = actions.auth.loadProfile(state.tokenV3);
let g = actions.auth.getMemberGroups(state.tokenV3);
let g = actions.auth.getAuthenticatedMemberGroups(state.tokenV3);
a = await redux.resolveAction(a);
g = await redux.resolveAction(g);
return create(onGetMemberGroups(onProfileLoaded(state, a), g));
return create(onGetAuthenticatedMemberGroups(onProfileLoaded(state, a), g));
}
return create(state);
}
Expand Down
7 changes: 7 additions & 0 deletions src/reducers/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import _ from 'lodash';
import { handleActions } from 'redux-actions';
import actions from '../actions/groups';
// import { getApiResponsePayload } from '../utils/tc';

/**
* Private. Given two user group maps, it adds to "dst" the root group from
Expand Down Expand Up @@ -84,6 +85,10 @@ function onGetGroupsDone(state, action) {
return { ...state, groups, loading };
}

function onGetMemberGroups(state, action) {
return { ...state, memberGroups: action.payload };
}


/**
* Creates a new Groups reducer with the specified initial state.
Expand All @@ -96,9 +101,11 @@ function create(initialState) {
[a.dropGroups]: onDropGroups,
[a.getGroupsInit]: onGetGroupsInit,
[a.getGroupsDone]: onGetGroupsDone,
[a.getMemberGroups]: onGetMemberGroups,
}, _.defaults(initialState ? _.clone(initialState) : {}, {
groups: {},
loading: {},
memberGroups: [],
}));
}

Expand Down
39 changes: 39 additions & 0 deletions src/services/groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import _ from 'lodash';
import { config } from 'topcoder-react-utils';
import logger from '../utils/logger';
import { getApi } from './api';
import { setErrorIcon, ERROR_ICON_TYPES } from '../utils/errors';

/* The value of USER_GROUP_MAXAGE constant converted to [ms]. */
const USER_GROUP_MAXAGE = config.USER_GROUP_MAXAGE * 1000;
Expand Down Expand Up @@ -142,6 +143,29 @@ function handleApiResponse(response) {
return response.json();
}

/**
* Helper method that checks for HTTP error response v5 and throws Error in this case.
* @param {Object} res HTTP response object
* @return {Object} API JSON response object
* @private
*/
async function checkErrorV5(res) {
if (!res.ok) {
if (res.status === 403) {
setErrorIcon(ERROR_ICON_TYPES.API, 'Auth0', res.statusText);
}
throw new Error(res.statusText);
}
const jsonRes = (await res.json());
if (jsonRes.message) {
throw new Error(res.message);
}
return {
result: jsonRes,
headers: res.headers,
};
}

/**
* Private. Merges given user group (possibly a tree of user groups) into
* groups map. This function intended only for internal use inside this module,
Expand Down Expand Up @@ -354,6 +378,21 @@ class GroupService {
getTokenV3() {
return this.private.tokenV3;
}

/**
* Gets the corresponding user's groups information
* @param {*} userId the userId
* @returns
*/
async getMemberGroups(userId) {
const url = `/groups/memberGroups/${userId}`;
const response = await this.private.api.get(url)
.then(res => checkErrorV5(res))
.then(r => r.result || [])
.catch(() => []);

return response;
}
}

let lastInstance = null;
Expand Down

0 comments on commit b72d035

Please sign in to comment.