diff --git a/src/auth/index.ts b/src/auth/index.ts index 44cffd00..dd6f1ffb 100755 --- a/src/auth/index.ts +++ b/src/auth/index.ts @@ -3,7 +3,15 @@ export { Authorizer } from './authorizer' export { AuthGroupName } from './authGroup' export type { AuthGroup } from './authGroup' -export type { User, UserPrefs, UserProps, UserPrefSurveys, UserInvitation } from './user' +export type { + User, + UserAuthGroup, + UserAuthGroupProps, + UserPrefs, + UserProps, + UserPrefSurveys, + UserInvitation, +} from './user' export type { UserService } from './userService' export { UserStatus, UserTitle } from './user' diff --git a/src/auth/user.ts b/src/auth/user.ts index 8fb901e6..6f547e54 100755 --- a/src/auth/user.ts +++ b/src/auth/user.ts @@ -31,8 +31,16 @@ export interface UserInvitation { expired: boolean } +export interface UserAuthGroupProps { + extra: Dictionary +} + +export interface UserAuthGroup extends AuthGroup { + props: UserAuthGroupProps +} + export interface User extends ArenaObject { - authGroups?: AuthGroup[] + authGroups?: UserAuthGroup[] email: string hasProfilePicture: boolean name: string diff --git a/src/auth/users.ts b/src/auth/users.ts index 97cb7e7c..49dc5591 100755 --- a/src/auth/users.ts +++ b/src/auth/users.ts @@ -1,23 +1,33 @@ -import { User } from './user' -import { AuthGroup } from './authGroup' +import { User, UserAuthGroup } from './user' import { AuthGroups } from './authGroups' +import { Dictionary } from '../common' -const getAuthGroups = (user: User): AuthGroup[] => user?.authGroups ?? [] +const getAuthGroups = (user: User): UserAuthGroup[] => user?.authGroups ?? [] const isSystemAdmin = (user: User): boolean => (getAuthGroups(user) ?? []).some(AuthGroups.isSystemAdmin) const getAuthGroupBySurveyUuid = (surveyUuid?: string, includeSystemAdmin = true) => - (user: User): AuthGroup | undefined => { + (user: User): UserAuthGroup | undefined => { const authGroups = getAuthGroups(user) - if (includeSystemAdmin && isSystemAdmin(user) && authGroups) { - return authGroups[0] - } + if (!authGroups) return undefined + return includeSystemAdmin && isSystemAdmin(user) + ? authGroups[0] + : authGroups.find((authGroup) => authGroup.surveyUuid === surveyUuid) + } - return authGroups?.find((authGroup) => authGroup?.surveyUuid === surveyUuid) +const getCombinedExtraProps = + (surveyUuid: string) => + (user: User): Dictionary => { + const userSurveyAuthGroup = user ? Users.getAuthGroupBySurveyUuid(surveyUuid)(user) : null + const userAuthGroupExtraProps = userSurveyAuthGroup?.props?.extra ?? {} + const userExtraProps = user?.props.extra ?? {} + // user auth group extra props overwrite user extra props + return { ...userExtraProps, ...userAuthGroupExtraProps } } export const Users = { isSystemAdmin, getAuthGroupBySurveyUuid, + getCombinedExtraProps, } diff --git a/src/index.ts b/src/index.ts index 411da6c2..9e104e79 100755 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,16 @@ export type { AppInfo } from './app' export { Authorizer, AuthGroupName, UserStatus, Permission, UserTitle, UserFactory, Users } from './auth' -export type { User, UserPrefs, UserPrefSurveys, UserProps, AuthGroup, UserService } from './auth' +export type { + User, + UserAuthGroup, + UserAuthGroupProps, + UserPrefs, + UserPrefSurveys, + UserProps, + AuthGroup, + UserService, +} from './auth' export { CategoryFactory, CategoryImportColumnType, CategoryItemFactory, CategoryLevelFactory } from './category' export type { diff --git a/src/nodeDefExpressionEvaluator/functions.ts b/src/nodeDefExpressionEvaluator/functions.ts index 28379f4b..6c67992b 100755 --- a/src/nodeDefExpressionEvaluator/functions.ts +++ b/src/nodeDefExpressionEvaluator/functions.ts @@ -8,6 +8,7 @@ import { Dates } from '../utils/dates' import { NodeDefExpressionContext } from './context' import { SystemError } from '../error' import { ExtraProps } from '../extraProp/extraProps' +import { Users } from '../auth' const sampleGeoJsonPolygon = { type: 'Feature', @@ -174,6 +175,12 @@ export const nodeDefExpressionFunctions: ExpressionFunctions (propName: string) => context.user?.props.extra?.[propName], + executor: (context: NodeDefExpressionContext) => (propName: string) => { + const { user, survey } = context + if (!survey || !user) return undefined + const { uuid: surveyUuid } = survey + const combinedExtraProps = Users.getCombinedExtraProps(surveyUuid)(user) + return combinedExtraProps[propName] + }, }, }