1 {-# LANGUAGE DeriveAnyClass #-}
2 {-# LANGUAGE DuplicateRecordFields #-}
4 module Gargantext.API.GraphQL.UserInfo where
7 import Data.Maybe (fromMaybe)
8 import Data.Morpheus.Types
15 import Data.Text (Text)
16 import qualified Data.Text as T
17 import Gargantext.API.Prelude (GargM, GargError)
18 import Gargantext.Core.Mail.Types (HasMail)
19 import Gargantext.Database.Admin.Types.Hyperdata
24 import Gargantext.Database.Admin.Types.Hyperdata.Contact
41 import Gargantext.Database.Prelude (HasConnectionPool, HasConfig)
42 import Gargantext.Database.Query.Table.Node.UpdateOpaleye (updateHyperdata)
43 import Gargantext.Database.Query.Table.User (getUsersWithHyperdata, getUsersWithNodeHyperdata, updateUserEmail)
44 import Gargantext.Database.Schema.User (UserLight(..))
45 import Gargantext.Database.Schema.Node (node_id, node_hyperdata, NodePoly (Node, _node_id))
46 import Gargantext.Prelude
47 import GHC.Generics (Generic)
48 import Gargantext.API.GraphQL.Utils (AuthStatus(Invalid, Valid), authUser)
49 import Gargantext.API.Admin.Types (HasSettings)
51 data UserInfo = UserInfo
55 , ui_title :: Maybe Text
56 , ui_source :: Maybe Text
57 , ui_cwFirstName :: Maybe Text
58 , ui_cwLastName :: Maybe Text
59 , ui_cwCity :: Maybe Text
60 , ui_cwCountry :: Maybe Text
61 , ui_cwOrganization :: [Text]
62 , ui_cwLabTeamDepts :: [Text]
63 , ui_cwOffice :: Maybe Text
64 , ui_cwRole :: Maybe Text
65 , ui_cwTouchPhone :: Maybe Text
66 , ui_cwTouchMail :: Maybe Text -- TODO: Remove. userLight_email should be used instead
68 deriving (Generic, GQLType, Show)
70 -- | Arguments to the "user info" query.
74 } deriving (Generic, GQLType)
76 -- | Arguments to the "user info" mutation,
81 , ui_username :: Maybe Text
82 , ui_email :: Maybe Text
83 , ui_title :: Maybe Text
84 , ui_source :: Maybe Text
85 , ui_cwFirstName :: Maybe Text
86 , ui_cwLastName :: Maybe Text
87 , ui_cwCity :: Maybe Text
88 , ui_cwCountry :: Maybe Text
89 , ui_cwOrganization :: Maybe [Text]
90 , ui_cwLabTeamDepts :: Maybe [Text]
91 , ui_cwOffice :: Maybe Text
92 , ui_cwRole :: Maybe Text
93 , ui_cwTouchPhone :: Maybe Text
94 , ui_cwTouchMail :: Maybe Text
95 } deriving (Generic, GQLType)
97 type GqlM e env = Resolver QUERY e (GargM env GargError)
98 type GqlM' e env err = ResolverM e (GargM env err) Int
100 -- | Function to resolve user from a query.
102 :: (HasConnectionPool env, HasConfig env, HasMail env)
103 => UserInfoArgs -> GqlM e env [UserInfo]
104 resolveUserInfos UserInfoArgs { user_id } = dbUsers user_id
106 -- | Mutation for user info
108 :: (HasConnectionPool env, HasConfig env, HasMail env, HasSettings env)
109 -- => UserInfoMArgs -> ResolverM e (GargM env err) Int
110 => UserInfoMArgs -> GqlM' e env err
111 updateUserInfo (UserInfoMArgs { ui_id, .. }) = do
112 -- lift $ printDebug "[updateUserInfo] ui_id" ui_id
113 users <- lift (getUsersWithNodeHyperdata ui_id)
115 [] -> panic $ "[updateUserInfo] User with id " <> (T.pack $ show ui_id) <> " doesn't exist."
116 ((UserLight { .. }, node_u):_) -> do
117 testAuthUser <- lift $ authUser (nId node_u) token
119 Invalid -> panic "[updateUserInfo] failed to validate user"
121 let u_hyperdata = node_u ^. node_hyperdata
122 -- lift $ printDebug "[updateUserInfo] u" u
123 let u_hyperdata' = uh ui_titleL ui_title $
124 uh ui_sourceL ui_source $
125 uh ui_cwFirstNameL ui_cwFirstName $
126 uh ui_cwLastNameL ui_cwLastName $
127 uh ui_cwCityL ui_cwCity $
128 uh ui_cwCountryL ui_cwCountry $
129 uh' ui_cwLabTeamDeptsL ui_cwLabTeamDepts $
130 uh' ui_cwOrganizationL ui_cwOrganization $
131 uh ui_cwOfficeL ui_cwOffice $
132 uh ui_cwRoleL ui_cwRole $
133 uh ui_cwTouchMailL ui_cwTouchMail $
134 uh ui_cwTouchPhoneL ui_cwTouchPhone $
136 -- NOTE: We have 1 username and 2 emails: userLight_email and ui_cwTouchMail
137 -- The userLight_email is more important: it is used for login and sending mail.
138 -- Therefore we update ui_cwTouchMail and userLight_email.
139 -- ui_cwTouchMail is to be removed in the future.
140 let u' = UserLight { userLight_id
142 , userLight_email = fromMaybe userLight_email $ view ui_cwTouchMailL u_hyperdata
143 , userLight_password }
144 -- lift $ printDebug "[updateUserInfo] with firstName" u_hyperdata'
145 _ <- lift $ updateHyperdata (node_u ^. node_id) u_hyperdata'
146 _ <- lift $ updateUserEmail u'
147 --let _newUser = toUser (u, u_hyperdata')
150 uh _ Nothing u_hyperdata = u_hyperdata
151 uh lens' (Just val) u_hyperdata = u_hyperdata & lens' .~ Just val
152 uh' _ Nothing u_hyperdata = u_hyperdata
153 uh' lens' (Just val) u_hyperdata = u_hyperdata & lens' .~ val
154 nId Node {_node_id} = _node_id
156 -- | Inner function to fetch the user from DB.
158 :: (HasConnectionPool env, HasConfig env, HasMail env)
159 => Int -> GqlM e env [UserInfo]
161 -- lift $ printDebug "[dbUsers]" user_id
162 -- user <- getUsersWithId user_id
163 -- hyperdata <- getUserHyperdata user_id
164 -- lift (map toUser <$> zip user hyperdata)
165 lift (map toUser <$> (getUsersWithHyperdata user_id))
167 toUser :: (UserLight, HyperdataUser) -> UserInfo
168 toUser (UserLight { .. }, u_hyperdata) =
169 UserInfo { ui_id = userLight_id
170 , ui_username = userLight_username
171 , ui_email = userLight_email
172 , ui_title = u_hyperdata ^. ui_titleL
173 , ui_source = u_hyperdata ^. ui_sourceL
174 , ui_cwFirstName = u_hyperdata ^. ui_cwFirstNameL
175 , ui_cwLastName = u_hyperdata ^. ui_cwLastNameL
176 , ui_cwCity = u_hyperdata ^. ui_cwCityL
177 , ui_cwCountry = u_hyperdata ^. ui_cwCountryL
178 , ui_cwLabTeamDepts = u_hyperdata ^. ui_cwLabTeamDeptsL
179 , ui_cwOrganization = u_hyperdata ^. ui_cwOrganizationL
180 , ui_cwOffice = u_hyperdata ^. ui_cwOfficeL
181 , ui_cwRole = u_hyperdata ^. ui_cwRoleL
182 --, ui_cwTouchMail = u_hyperdata ^. ui_cwTouchMailL
183 , ui_cwTouchMail = Just userLight_email
184 , ui_cwTouchPhone = u_hyperdata ^. ui_cwTouchPhoneL }
186 sharedL :: Traversal' HyperdataUser HyperdataContact
187 sharedL = hu_shared . _Just
188 ui_titleL :: Traversal' HyperdataUser (Maybe Text)
189 ui_titleL = sharedL . hc_title
190 ui_sourceL :: Traversal' HyperdataUser (Maybe Text)
191 ui_sourceL = sharedL . hc_source
192 contactWhoL :: Traversal' HyperdataUser ContactWho
193 contactWhoL = sharedL . hc_who . _Just
194 ui_cwFirstNameL :: Traversal' HyperdataUser (Maybe Text)
195 ui_cwFirstNameL = contactWhoL . cw_firstName
196 ui_cwLastNameL :: Traversal' HyperdataUser (Maybe Text)
197 ui_cwLastNameL = contactWhoL . cw_lastName
198 contactWhereL :: Traversal' HyperdataUser ContactWhere
199 contactWhereL = sharedL . hc_where . (ix 0)
200 ui_cwCityL :: Traversal' HyperdataUser (Maybe Text)
201 ui_cwCityL = contactWhereL . cw_city
202 ui_cwCountryL :: Traversal' HyperdataUser (Maybe Text)
203 ui_cwCountryL = contactWhereL . cw_country
204 ui_cwLabTeamDeptsL :: Traversal' HyperdataUser [Text]
205 ui_cwLabTeamDeptsL = hu_shared . _Just . (hc_where . (ix 0) . cw_labTeamDepts)
206 ui_cwOrganizationL :: Traversal' HyperdataUser [Text]
207 ui_cwOrganizationL = hu_shared . _Just . (hc_where . (ix 0) . cw_organization)
208 ui_cwOfficeL :: Traversal' HyperdataUser (Maybe Text)
209 ui_cwOfficeL = contactWhereL . cw_office
210 ui_cwRoleL :: Traversal' HyperdataUser (Maybe Text)
211 ui_cwRoleL = contactWhereL . cw_role
212 ui_cwTouchMailL :: Traversal' HyperdataUser (Maybe Text)
213 ui_cwTouchMailL = hu_shared . _Just . (hc_where . (ix 0) . cw_touch . _Just . ct_mail)
214 --ui_cwTouchMailL = contactWhereL . cw_touch . _Just . ct_mail
215 ui_cwTouchPhoneL :: Traversal' HyperdataUser (Maybe Text)
216 ui_cwTouchPhoneL = hu_shared . _Just . (hc_where . (ix 0) . cw_touch . _Just . ct_phone)
217 --ui_cwTouchPhoneL = contactWhereL . cw_touch . _Just . ct_phone