requests.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. package libcobalt
  2. import (
  3. "encoding/json"
  4. "io/ioutil"
  5. "net/http"
  6. "strings"
  7. "time"
  8. "notabug.org/apiote/gott"
  9. )
  10. func marshalRequest(values ...interface{}) (interface{}, error) {
  11. data := values[0]
  12. marshaledData, err := json.Marshal(data)
  13. values[0] = marshaledData
  14. return gott.Tuple(values), err
  15. }
  16. func setHeadersAuthed(values ...interface{}) interface{} {
  17. r := values[0].(*http.Request)
  18. account := values[1].(Account)
  19. accessToken := account.authToken
  20. uid := account.uid
  21. r.Header.Add("Authorization", "Bearer "+accessToken)
  22. r.Header.Add("x-pm-uid", uid)
  23. values[0] = r
  24. return setHeaders(values...)
  25. }
  26. func doRequest(values ...interface{}) (interface{}, error) {
  27. httpClient := http.Client{Timeout: 10 * time.Second}
  28. response, err := httpClient.Do(values[0].(*http.Request))
  29. values[0] = response
  30. return gott.Tuple(values), err
  31. }
  32. func checkResponse(values ...interface{}) (interface{}, error) {
  33. if r := values[0].(*http.Response); r.StatusCode != 200 { // todo 20x
  34. return gott.Tuple(values), HttpError{r.StatusCode, r.Body}
  35. } else {
  36. values[0] = r
  37. return gott.Tuple(values), nil
  38. }
  39. }
  40. func readResponse(values ...interface{}) (interface{}, error) {
  41. defer values[0].(*http.Response).Body.Close()
  42. response, err := ioutil.ReadAll(values[0].(*http.Response).Body)
  43. values[0] = response
  44. return gott.Tuple(values), err
  45. }
  46. func setHeaders(values ...interface{}) interface{} {
  47. r := values[0].(*http.Request)
  48. r.Header.Add("Content-Type", "application/json;charset=utf-8")
  49. r.Header.Add("x-pm-appversion", "Other")
  50. r.Header.Add("x-pm-apiversion", "3")
  51. r.Header.Add("Accept", "application/vnd.protonmail.v1+json")
  52. values[0] = r
  53. return gott.Tuple(values)
  54. }
  55. func prepareInfoRequest(request ...interface{}) (interface{}, error) {
  56. return http.NewRequest("POST",
  57. "https://mail.protonmail.com/api/auth/info",
  58. strings.NewReader(string(request[0].([]byte))))
  59. }
  60. type authInfo struct {
  61. Code int
  62. Modulus string
  63. ServerEphemeral string
  64. Version int
  65. Salt string
  66. SessionKey string `json:"SRPSession"`
  67. TwoFactorOld int `json:"TwoFactor"`
  68. TwoFactorNew map[string]interface{} `json:"2FA"`
  69. modulusBytes []byte
  70. serverEphemeralBytes []byte
  71. saltBytes []byte
  72. }
  73. func unmarshalInfoResponse(response ...interface{}) (interface{}, error) {
  74. var res authInfo
  75. err := json.Unmarshal(response[0].([]byte), &res)
  76. return res, err
  77. }
  78. func prepareAuthRequest(request ...interface{}) (interface{}, error) {
  79. return http.NewRequest("POST",
  80. "https://mail.protonmail.com/api/auth/",
  81. strings.NewReader(string(request[0].([]byte))))
  82. }
  83. type authResult struct {
  84. Code int
  85. AccessToken string
  86. ExpiresIn int
  87. TokenType string
  88. Scope string
  89. Uid string
  90. UID string
  91. UserID string
  92. RefreshToken string
  93. EventID string
  94. PasswordMode int
  95. TwoFactorOld int `json:"TwoFactor"`
  96. TwoFactorNew map[string]interface{} `json:"2FA"`
  97. ServerProof string
  98. expiryDate time.Time
  99. }
  100. func unmarshalAuthResponse(values ...interface{}) (interface{}, error) {
  101. response := values[0].([]byte)
  102. var res authResult
  103. err := json.Unmarshal(response, &res)
  104. return res, err
  105. }
  106. func prepareRefreshRequest(values ...interface{}) (interface{}, error) {
  107. r, err := http.NewRequest("POST",
  108. "https://mail.protonmail.com/api/auth/refresh",
  109. strings.NewReader(string(values[0].([]byte))))
  110. values[0] = r
  111. return gott.Tuple(values), err
  112. }
  113. type refreshResponse struct {
  114. Code int
  115. AccessToken string
  116. ExpiresIn int
  117. TokenType string
  118. Scope string
  119. Uid string
  120. UserStatus interface{}
  121. RefreshToken string
  122. }
  123. func unmarshalRefreshResponse(values ...interface{}) (interface{}, error) {
  124. var res refreshResponse
  125. err := json.Unmarshal(values[0].([]byte), &res)
  126. return res, err
  127. }
  128. func prepareRevokeRequest(values ...interface{}) (interface{}, error) {
  129. r, err := http.NewRequest("DELETE",
  130. "https://mail.protonmail.com/api/auth", nil)
  131. values[0] = r
  132. return gott.Tuple(values), err
  133. }
  134. func prepareSaltsRequest(values ...interface{}) (interface{}, error) {
  135. r, err := http.NewRequest("GET",
  136. "https://mail.protonmail.com/api/keys/salts", nil)
  137. values[0] = r
  138. return gott.Tuple(values), err
  139. }
  140. type keySalt struct {
  141. ID string
  142. KeySalt string
  143. }
  144. type saltsResponse struct {
  145. Code int
  146. KeySalts []keySalt
  147. }
  148. func unmarshalSaltsResponse(values ...interface{}) (interface{}, error) {
  149. var res saltsResponse
  150. err := json.Unmarshal(values[0].([]byte), &res)
  151. values[0] = res
  152. return gott.Tuple(values), err
  153. }
  154. func prepareAddressesRequest(values ...interface{}) (interface{}, error) {
  155. r, err := http.NewRequest("GET",
  156. "https://mail.protonmail.com/api/addresses", nil)
  157. values[0] = r
  158. return gott.Tuple(values), err
  159. }
  160. type addressesResponse struct {
  161. Code int
  162. Addresses []struct {
  163. ID string
  164. DomainID string
  165. Email string
  166. Send int
  167. Receive int
  168. Status int
  169. Type int
  170. Order int
  171. DisplayName string
  172. Signature string
  173. Priority int
  174. HasKeys int
  175. Keys []struct {
  176. ID string
  177. Version int
  178. Flags int
  179. PublicKey string
  180. PrivateKey string
  181. Fingerprint string
  182. Fingerprints []string
  183. Activation interface{}
  184. Primary int
  185. Token interface{}
  186. Signature interface{}
  187. }
  188. }
  189. }
  190. func unmarshalAddressesResponse(values ...interface{}) (interface{}, error) {
  191. var res addressesResponse
  192. err := json.Unmarshal(values[0].([]byte), &res)
  193. values[0] = res
  194. return gott.Tuple(values), err
  195. }
  196. func preparePostDraftRequest(values ...interface{}) (interface{}, error) {
  197. r, err := http.NewRequest("POST",
  198. "https://mail.protonmail.com/api/messages",
  199. strings.NewReader(string(values[0].([]byte))))
  200. values[0] = r
  201. return gott.Tuple(values), err
  202. }
  203. type responseAddress struct {
  204. Address string
  205. Name string
  206. Group string
  207. }
  208. type draftResponse struct {
  209. Code int
  210. Message struct {
  211. ID string
  212. Order int
  213. ConversationID string
  214. Subject string
  215. Unread int
  216. SenderAddress string
  217. SenderName string
  218. Sender EmailAddress
  219. Flags int
  220. Type int
  221. IsEncrypted int
  222. IsReplied int
  223. IsRepliedAll int
  224. IsForwarded int
  225. ToList []responseAddress
  226. CCList []responseAddress
  227. BCCList []responseAddress
  228. Time int
  229. Size int
  230. NumAttachments int
  231. ExpirationTime int
  232. SpamScore int
  233. AddressID string
  234. ExternalID string
  235. Body string
  236. MIMEType string
  237. Header string
  238. ParsedHeaders map[string]string
  239. ReplyTo EmailAddress
  240. ReplyTos []EmailAddress
  241. Attachments []interface{}
  242. Starred int
  243. Location int
  244. LabelIDs []string
  245. }
  246. }
  247. func unmarshalDraftResponse(values ...interface{}) (interface{}, error) {
  248. var res draftResponse
  249. err := json.Unmarshal(values[0].([]byte), &res)
  250. values[0] = res
  251. return gott.Tuple(values), err
  252. }