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)
50 import Gargantext.Database.Admin.Types.Node (unNodeId)
52 data UserInfo = UserInfo
56 , ui_title :: Maybe Text
57 , ui_source :: Maybe Text
58 , ui_cwFirstName :: Maybe Text
59 , ui_cwLastName :: Maybe Text
60 , ui_cwCity :: Maybe Text
61 , ui_cwCountry :: Maybe Text
62 , ui_cwOrganization :: [Text]
63 , ui_cwLabTeamDepts :: [Text]
64 , ui_cwOffice :: Maybe Text
65 , ui_cwRole :: Maybe Text
66 , ui_cwTouchPhone :: Maybe Text
67 , ui_cwTouchMail :: Maybe Text -- TODO: Remove. userLight_email should be used instead
69 deriving (Generic, GQLType, Show)
71 -- | Arguments to the "user info" query.
75 } deriving (Generic, GQLType)
77 -- | Arguments to the "user info" mutation,
82 , ui_username :: Maybe Text
83 , ui_email :: Maybe Text
84 , ui_title :: Maybe Text
85 , ui_source :: Maybe Text
86 , ui_cwFirstName :: Maybe Text
87 , ui_cwLastName :: Maybe Text
88 , ui_cwCity :: Maybe Text
89 , ui_cwCountry :: Maybe Text
90 , ui_cwOrganization :: Maybe [Text]
91 , ui_cwLabTeamDepts :: Maybe [Text]
92 , ui_cwOffice :: Maybe Text
93 , ui_cwRole :: Maybe Text
94 , ui_cwTouchPhone :: Maybe Text
95 , ui_cwTouchMail :: Maybe Text
96 } deriving (Generic, GQLType)
98 type GqlM e env = Resolver QUERY e (GargM env GargError)
99 type GqlM' e env err = ResolverM e (GargM env err) Int
101 -- | Function to resolve user from a query.
103 :: (HasConnectionPool env, HasConfig env, HasMail env)
104 => UserInfoArgs -> GqlM e env [UserInfo]
105 resolveUserInfos UserInfoArgs { user_id } = dbUsers user_id
107 -- | Mutation for user info
109 :: (HasConnectionPool env, HasConfig env, HasMail env, HasSettings env)
110 -- => UserInfoMArgs -> ResolverM e (GargM env err) Int
111 => UserInfoMArgs -> GqlM' e env err
112 updateUserInfo (UserInfoMArgs { ui_id, .. }) = do
113 -- lift $ printDebug "[updateUserInfo] ui_id" ui_id
114 users <- lift (getUsersWithNodeHyperdata ui_id)
116 [] -> panic $ "[updateUserInfo] User with id " <> (T.pack $ show ui_id) <> " doesn't exist."
117 ((UserLight { .. }, node_u):_) -> do
118 testAuthUser <- lift $ authUser (nId node_u) token
120 Invalid -> panic "[updateUserInfo] failed to validate user"
122 let u_hyperdata = node_u ^. node_hyperdata
123 -- lift $ printDebug "[updateUserInfo] u" u
124 let u_hyperdata' = uh ui_titleL ui_title $
125 uh ui_sourceL ui_source $
126 uh ui_cwFirstNameL ui_cwFirstName $
127 uh ui_cwLastNameL ui_cwLastName $
128 uh ui_cwCityL ui_cwCity $
129 uh ui_cwCountryL ui_cwCountry $
130 uh' ui_cwLabTeamDeptsL ui_cwLabTeamDepts $
131 uh' ui_cwOrganizationL ui_cwOrganization $
132 uh ui_cwOfficeL ui_cwOffice $
133 uh ui_cwRoleL ui_cwRole $
134 uh ui_cwTouchMailL ui_cwTouchMail $
135 uh ui_cwTouchPhoneL ui_cwTouchPhone $
137 -- NOTE: We have 1 username and 2 emails: userLight_email and ui_cwTouchMail
138 -- The userLight_email is more important: it is used for login and sending mail.
139 -- Therefore we update ui_cwTouchMail and userLight_email.
140 -- ui_cwTouchMail is to be removed in the future.
141 let u' = UserLight { userLight_id
143 , userLight_email = fromMaybe userLight_email $ view ui_cwTouchMailL u_hyperdata
144 , userLight_password }
145 -- lift $ printDebug "[updateUserInfo] with firstName" u_hyperdata'
146 _ <- lift $ updateHyperdata (node_u ^. node_id) u_hyperdata'
147 _ <- lift $ updateUserEmail u'
148 --let _newUser = toUser (u, u_hyperdata')
151 uh _ Nothing u_hyperdata = u_hyperdata
152 uh lens' (Just val) u_hyperdata = u_hyperdata & lens' .~ Just val
153 uh' _ Nothing u_hyperdata = u_hyperdata
154 uh' lens' (Just val) u_hyperdata = u_hyperdata & lens' .~ val
155 nId Node {_node_id} = unNodeId _node_id
157 -- | Inner function to fetch the user from DB.
159 :: (HasConnectionPool env, HasConfig env, HasMail env)
160 => Int -> GqlM e env [UserInfo]
162 -- lift $ printDebug "[dbUsers]" user_id
163 -- user <- getUsersWithId user_id
164 -- hyperdata <- getUserHyperdata user_id
165 -- lift (map toUser <$> zip user hyperdata)
166 lift (map toUser <$> (getUsersWithHyperdata user_id))
168 toUser :: (UserLight, HyperdataUser) -> UserInfo
169 toUser (UserLight { .. }, u_hyperdata) =
170 UserInfo { ui_id = userLight_id
171 , ui_username = userLight_username
172 , ui_email = userLight_email
173 , ui_title = u_hyperdata ^. ui_titleL
174 , ui_source = u_hyperdata ^. ui_sourceL
175 , ui_cwFirstName = u_hyperdata ^. ui_cwFirstNameL
176 , ui_cwLastName = u_hyperdata ^. ui_cwLastNameL
177 , ui_cwCity = u_hyperdata ^. ui_cwCityL
178 , ui_cwCountry = u_hyperdata ^. ui_cwCountryL
179 , ui_cwLabTeamDepts = u_hyperdata ^. ui_cwLabTeamDeptsL
180 , ui_cwOrganization = u_hyperdata ^. ui_cwOrganizationL
181 , ui_cwOffice = u_hyperdata ^. ui_cwOfficeL
182 , ui_cwRole = u_hyperdata ^. ui_cwRoleL
183 --, ui_cwTouchMail = u_hyperdata ^. ui_cwTouchMailL
184 , ui_cwTouchMail = Just userLight_email
185 , ui_cwTouchPhone = u_hyperdata ^. ui_cwTouchPhoneL }
187 sharedL :: Traversal' HyperdataUser HyperdataContact
188 sharedL = hu_shared . _Just
189 ui_titleL :: Traversal' HyperdataUser (Maybe Text)
190 ui_titleL = sharedL . hc_title
191 ui_sourceL :: Traversal' HyperdataUser (Maybe Text)
192 ui_sourceL = sharedL . hc_source
193 contactWhoL :: Traversal' HyperdataUser ContactWho
194 contactWhoL = sharedL . hc_who . _Just
195 ui_cwFirstNameL :: Traversal' HyperdataUser (Maybe Text)
196 ui_cwFirstNameL = contactWhoL . cw_firstName
197 ui_cwLastNameL :: Traversal' HyperdataUser (Maybe Text)
198 ui_cwLastNameL = contactWhoL . cw_lastName
199 contactWhereL :: Traversal' HyperdataUser ContactWhere
200 contactWhereL = sharedL . hc_where . (ix 0)
201 ui_cwCityL :: Traversal' HyperdataUser (Maybe Text)
202 ui_cwCityL = contactWhereL . cw_city
203 ui_cwCountryL :: Traversal' HyperdataUser (Maybe Text)
204 ui_cwCountryL = contactWhereL . cw_country
205 ui_cwLabTeamDeptsL :: Traversal' HyperdataUser [Text]
206 ui_cwLabTeamDeptsL = hu_shared . _Just . (hc_where . (ix 0) . cw_labTeamDepts)
207 ui_cwOrganizationL :: Traversal' HyperdataUser [Text]
208 ui_cwOrganizationL = hu_shared . _Just . (hc_where . (ix 0) . cw_organization)
209 ui_cwOfficeL :: Traversal' HyperdataUser (Maybe Text)
210 ui_cwOfficeL = contactWhereL . cw_office
211 ui_cwRoleL :: Traversal' HyperdataUser (Maybe Text)
212 ui_cwRoleL = contactWhereL . cw_role
213 ui_cwTouchMailL :: Traversal' HyperdataUser (Maybe Text)
214 ui_cwTouchMailL = hu_shared . _Just . (hc_where . (ix 0) . cw_touch . _Just . ct_mail)
215 --ui_cwTouchMailL = contactWhereL . cw_touch . _Just . ct_mail
216 ui_cwTouchPhoneL :: Traversal' HyperdataUser (Maybe Text)
217 ui_cwTouchPhoneL = hu_shared . _Just . (hc_where . (ix 0) . cw_touch . _Just . ct_phone)
218 --ui_cwTouchPhoneL = contactWhereL . cw_touch . _Just . ct_phone