· 6 years ago · Sep 01, 2019, 06:50 AM
1port module Cognito exposing
2 ( DeliveryDetails
3 , Event(..)
4 , MfaDetails
5 , changePassword
6 , completeNewPassword
7 , confirmSignIn
8 , forgotPassword
9 , forgotPasswordSubmit
10 , listen
11 , signIn
12 , signOut
13 , updateUserAttributes
14 )
15
16{-| This module provides a basic interface to the AWS Cognito API via Amplify.
17-}
18
19import Dict exposing (Dict)
20import Json.Decode as Decode exposing (Decoder)
21import Json.Encode as Encode exposing (Value)
22import Session exposing (Session)
23
24
25
26-- Outbound API
27
28
29signIn : String -> String -> Cmd msg
30signIn username password =
31 toCognito <|
32 outboundMessage "signIn" <|
33 Encode.object
34 [ ( "username", Encode.string username )
35 , ( "password", Encode.string password )
36 ]
37
38
39signOut : Cmd msg
40signOut =
41 toCognito <|
42 outboundMessage "signOut" <|
43 Encode.object
44 [ ( "global", Encode.bool False ) ]
45
46
47completeNewPassword :
48 { newPassword : String
49 , name : String
50 }
51 -> Cmd msg
52completeNewPassword { newPassword, name } =
53 let
54 requiredAttributes =
55 Encode.object
56 [ ( "name", Encode.string name ) ]
57 in
58 toCognito <|
59 outboundMessage "completeNewPassword" <|
60 Encode.object
61 [ ( "newPassword", Encode.string newPassword )
62 , ( "requiredAttributes", requiredAttributes )
63 ]
64
65
66forgotPassword : String -> Cmd msg
67forgotPassword username =
68 toCognito <|
69 outboundMessage "forgotPassword" <|
70 Encode.object
71 [ ( "username", Encode.string username ) ]
72
73
74forgotPasswordSubmit :
75 { username : String
76 , code : String
77 , newPassword : String
78 }
79 -> Cmd msg
80forgotPasswordSubmit { username, code, newPassword } =
81 toCognito <|
82 outboundMessage "forgotPasswordSubmit" <|
83 Encode.object
84 [ ( "username", Encode.string username )
85 , ( "code", Encode.string code )
86 , ( "newPassword", Encode.string newPassword )
87 ]
88
89
90confirmSignIn :
91 { code : String
92 , mfaType : String
93 }
94 -> Cmd msg
95confirmSignIn { code, mfaType } =
96 toCognito <|
97 outboundMessage "confirmSignIn" <|
98 Encode.object
99 [ ( "code", Encode.string code )
100 , ( "mfaType", Encode.string mfaType )
101 ]
102
103
104changePassword : { oldPassword : String, newPassword : String } -> Cmd msg
105changePassword { oldPassword, newPassword } =
106 toCognito <|
107 outboundMessage "changePassword" <|
108 Encode.object
109 [ ( "oldPassword", Encode.string oldPassword )
110 , ( "newPassword", Encode.string newPassword )
111 ]
112
113
114updateUserAttributes : Dict String String -> Cmd msg
115updateUserAttributes attrs =
116 toCognito <|
117 outboundMessage "updateUserAttributes" <|
118 Encode.dict identity Encode.string attrs
119
120
121
122-- Outbound Helpers
123
124
125outboundMessage : String -> Value -> Value
126outboundMessage msgType msg =
127 Encode.object
128 [ ( "msgType", Encode.string msgType )
129 , ( "msg", msg )
130 ]
131
132
133
134-- Inbound API
135
136
137{-| An event from the JS AWS Amplify bindings.
138
139 - `GotSession cognito session`: indicates a new session generated.
140
141 - `Updated key value`: Indicates that `key` has changed. If `value` is `Nothing`
142 the key's data has been cleared.
143
144-}
145type Event
146 = GotSession Session
147 | Error CognitoError
148 | BadMessage Decode.Error
149 -- Present information to user for form input response
150 | NewPassword RequiredAttributes
151 | CodeDelivery DeliveryDetails
152 | Mfa MfaDetails
153
154
155type alias CognitoError =
156 { code : String
157 , name : String
158 , message : String
159 }
160
161
162type alias RequiredAttributes =
163 List String
164
165
166type alias DeliveryDetails =
167 { attributeName : String
168 , deliveryMedium : String
169 , destination : String
170 }
171
172
173type alias MfaDetails =
174 { deliveryMedium : String
175 , destination : String
176 }
177
178
179{-| Listen for events from Cognito JS.
180-}
181listen : Sub Event
182listen =
183 cognitoEvent handleCognitoMessage
184
185
186
187-- Inbound Helpers
188
189
190handleCognitoMessage : Value -> Event
191handleCognitoMessage value =
192 case
193 Decode.decodeValue
194 (Decode.oneOf
195 [ errorDecoder
196 , mfaDecoder
197 , codeDeliveryDecoder
198 , newPasswordDecoder
199 , sessionDecoder
200 ]
201 )
202 value
203 of
204 Ok event ->
205 event
206
207 Err error ->
208 BadMessage error
209
210
211newPasswordDecoder : Decoder Event
212newPasswordDecoder =
213 Decode.map NewPassword (Decode.list Decode.string)
214
215
216sessionDecoder : Decoder Event
217sessionDecoder =
218 Decode.map GotSession Session.decoder
219
220
221codeDeliveryDecoder : Decoder Event
222codeDeliveryDecoder =
223 Decode.map CodeDelivery <|
224 Decode.field "CodeDeliveryDetails" <|
225 Decode.map3 DeliveryDetails
226 (Decode.field "AttributeName" Decode.string)
227 (Decode.field "DeliveryMedium" Decode.string)
228 (Decode.field "Destination" Decode.string)
229
230
231mfaDecoder : Decoder Event
232mfaDecoder =
233 Decode.map Mfa <|
234 Decode.map2
235 MfaDetails
236 (Decode.field "CODE_DELIVERY_DELIVERY_MEDIUM" Decode.string)
237 (Decode.field "CODE_DELIVERY_DESTINATION" Decode.string)
238
239
240errorDecoder : Decoder Event
241errorDecoder =
242 Decode.map Error
243 (Decode.map3 CognitoError
244 (Decode.field "code" Decode.string)
245 (Decode.field "name" Decode.string)
246 (Decode.field "message" Decode.string)
247 )
248
249
250
251-- PORTS
252
253
254port toCognito : Value -> Cmd msg
255
256
257port cognitoEvent : (Value -> a) -> Sub a