emailengine-app 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (405) hide show
  1. package/.eslintrc +14 -0
  2. package/.github/CODE_OF_CONDUCT.md +76 -0
  3. package/.github/FUNDING.yml +4 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  6. package/.github/contributing.md +17 -0
  7. package/.ncurc.js +10 -0
  8. package/.prettierrc.js +8 -0
  9. package/Dockerfile +17 -0
  10. package/Gruntfile.js +16 -0
  11. package/LICENSE.txt +661 -0
  12. package/README.md +524 -0
  13. package/bin/emailengine.js +14 -0
  14. package/config/default.toml +39 -0
  15. package/docker-compose.yml +47 -0
  16. package/encrypt.js +179 -0
  17. package/examples/api.md +137 -0
  18. package/examples/auth-server.js +104 -0
  19. package/getswagger.sh +8 -0
  20. package/lib/account.js +562 -0
  21. package/lib/append-list.js +67 -0
  22. package/lib/bounce-detect.js +380 -0
  23. package/lib/connection.js +1753 -0
  24. package/lib/consts.js +22 -0
  25. package/lib/db.js +72 -0
  26. package/lib/encrypt.js +100 -0
  27. package/lib/enum-message-flags.js +6 -0
  28. package/lib/get-raw-email.js +292 -0
  29. package/lib/get-secret.js +83 -0
  30. package/lib/logger.js +35 -0
  31. package/lib/lua/s-list-accounts.lua +51 -0
  32. package/lib/lua/z-expunge.lua +20 -0
  33. package/lib/lua/z-get-by-uid.lua +16 -0
  34. package/lib/lua/z-get-mailbox-id.lua +15 -0
  35. package/lib/lua/z-get-mailbox-path.lua +4 -0
  36. package/lib/lua/z-get.lua +15 -0
  37. package/lib/lua/z-push.lua +14 -0
  38. package/lib/lua/z-set.lua +17 -0
  39. package/lib/mailbox.js +1545 -0
  40. package/lib/message-port-stream.js +79 -0
  41. package/lib/schemas.js +311 -0
  42. package/lib/settings.js +63 -0
  43. package/lib/tools.js +488 -0
  44. package/package.json +79 -0
  45. package/scan.js +111 -0
  46. package/server.js +672 -0
  47. package/static/bootstrap-4.6.0-dist/css/bootstrap-grid.css +3872 -0
  48. package/static/bootstrap-4.6.0-dist/css/bootstrap-grid.css.map +1 -0
  49. package/static/bootstrap-4.6.0-dist/css/bootstrap-grid.min.css +7 -0
  50. package/static/bootstrap-4.6.0-dist/css/bootstrap-grid.min.css.map +1 -0
  51. package/static/bootstrap-4.6.0-dist/css/bootstrap-reboot.css +325 -0
  52. package/static/bootstrap-4.6.0-dist/css/bootstrap-reboot.css.map +1 -0
  53. package/static/bootstrap-4.6.0-dist/css/bootstrap-reboot.min.css +8 -0
  54. package/static/bootstrap-4.6.0-dist/css/bootstrap-reboot.min.css.map +1 -0
  55. package/static/bootstrap-4.6.0-dist/css/bootstrap.css +10298 -0
  56. package/static/bootstrap-4.6.0-dist/css/bootstrap.css.map +1 -0
  57. package/static/bootstrap-4.6.0-dist/css/bootstrap.min.css +7 -0
  58. package/static/bootstrap-4.6.0-dist/css/bootstrap.min.css.map +1 -0
  59. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.js +7045 -0
  60. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.js.map +1 -0
  61. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.min.js +7 -0
  62. package/static/bootstrap-4.6.0-dist/js/bootstrap.bundle.min.js.map +1 -0
  63. package/static/bootstrap-4.6.0-dist/js/bootstrap.js +4432 -0
  64. package/static/bootstrap-4.6.0-dist/js/bootstrap.js.map +1 -0
  65. package/static/bootstrap-4.6.0-dist/js/bootstrap.min.js +7 -0
  66. package/static/bootstrap-4.6.0-dist/js/bootstrap.min.js.map +1 -0
  67. package/static/css/callout.css +63 -0
  68. package/static/css/emailengine.css +33 -0
  69. package/static/favicon/android-chrome-192x192.png +0 -0
  70. package/static/favicon/android-chrome-512x512.png +0 -0
  71. package/static/favicon/apple-touch-icon.png +0 -0
  72. package/static/favicon/favicon-16x16.png +0 -0
  73. package/static/favicon/favicon-32x32.png +0 -0
  74. package/static/favicon/manifest.json +20 -0
  75. package/static/favicon.ico +0 -0
  76. package/static/icons/alarm-fill.svg +3 -0
  77. package/static/icons/alarm.svg +7 -0
  78. package/static/icons/alert-circle-fill.svg +3 -0
  79. package/static/icons/alert-circle.svg +4 -0
  80. package/static/icons/alert-octagon-fill.svg +3 -0
  81. package/static/icons/alert-octagon.svg +5 -0
  82. package/static/icons/alert-square-fill.svg +3 -0
  83. package/static/icons/alert-square.svg +5 -0
  84. package/static/icons/alert-triangle-fill.svg +3 -0
  85. package/static/icons/alert-triangle.svg +5 -0
  86. package/static/icons/archive-fill.svg +3 -0
  87. package/static/icons/archive.svg +4 -0
  88. package/static/icons/arrow-bar-bottom.svg +4 -0
  89. package/static/icons/arrow-bar-left.svg +4 -0
  90. package/static/icons/arrow-bar-right.svg +4 -0
  91. package/static/icons/arrow-bar-up.svg +4 -0
  92. package/static/icons/arrow-clockwise.svg +4 -0
  93. package/static/icons/arrow-counterclockwise.svg +4 -0
  94. package/static/icons/arrow-down-left.svg +4 -0
  95. package/static/icons/arrow-down-right.svg +4 -0
  96. package/static/icons/arrow-down-short.svg +4 -0
  97. package/static/icons/arrow-down.svg +4 -0
  98. package/static/icons/arrow-left-right.svg +5 -0
  99. package/static/icons/arrow-left-short.svg +4 -0
  100. package/static/icons/arrow-left.svg +4 -0
  101. package/static/icons/arrow-repeat.svg +5 -0
  102. package/static/icons/arrow-right-short.svg +4 -0
  103. package/static/icons/arrow-right.svg +4 -0
  104. package/static/icons/arrow-up-down.svg +5 -0
  105. package/static/icons/arrow-up-left.svg +4 -0
  106. package/static/icons/arrow-up-right.svg +4 -0
  107. package/static/icons/arrow-up-short.svg +4 -0
  108. package/static/icons/arrow-up.svg +4 -0
  109. package/static/icons/arrows-angle-contract.svg +5 -0
  110. package/static/icons/arrows-angle-expand.svg +5 -0
  111. package/static/icons/arrows-collapse.svg +5 -0
  112. package/static/icons/arrows-expand.svg +5 -0
  113. package/static/icons/arrows-fullscreen.svg +7 -0
  114. package/static/icons/at.svg +3 -0
  115. package/static/icons/award.svg +4 -0
  116. package/static/icons/backspace-fill.svg +3 -0
  117. package/static/icons/backspace-reverse-fill.svg +3 -0
  118. package/static/icons/backspace-reverse.svg +5 -0
  119. package/static/icons/backspace.svg +5 -0
  120. package/static/icons/bar-chart-fill.svg +5 -0
  121. package/static/icons/bar-chart.svg +3 -0
  122. package/static/icons/battery-charging.svg +5 -0
  123. package/static/icons/battery-full.svg +4 -0
  124. package/static/icons/battery.svg +4 -0
  125. package/static/icons/bell-fill.svg +3 -0
  126. package/static/icons/bell.svg +4 -0
  127. package/static/icons/blockquote-left.svg +4 -0
  128. package/static/icons/blockquote-right.svg +4 -0
  129. package/static/icons/book-half-fill.svg +4 -0
  130. package/static/icons/book.svg +4 -0
  131. package/static/icons/bookmark-fill.svg +3 -0
  132. package/static/icons/bookmark.svg +3 -0
  133. package/static/icons/bootstrap-fill.svg +3 -0
  134. package/static/icons/bootstrap-reboot.svg +3 -0
  135. package/static/icons/bootstrap.svg +4 -0
  136. package/static/icons/box-arrow-bottom-left.svg +4 -0
  137. package/static/icons/box-arrow-bottom-right.svg +4 -0
  138. package/static/icons/box-arrow-down.svg +5 -0
  139. package/static/icons/box-arrow-left.svg +5 -0
  140. package/static/icons/box-arrow-right.svg +5 -0
  141. package/static/icons/box-arrow-up-left.svg +4 -0
  142. package/static/icons/box-arrow-up-right.svg +4 -0
  143. package/static/icons/box-arrow-up.svg +5 -0
  144. package/static/icons/braces.svg +3 -0
  145. package/static/icons/brightness-fill-high.svg +4 -0
  146. package/static/icons/brightness-fill-low.svg +11 -0
  147. package/static/icons/brightness-high.svg +3 -0
  148. package/static/icons/brightness-low.svg +11 -0
  149. package/static/icons/brush.svg +4 -0
  150. package/static/icons/bucket-fill.svg +4 -0
  151. package/static/icons/bucket.svg +4 -0
  152. package/static/icons/building.svg +5 -0
  153. package/static/icons/bullseye.svg +6 -0
  154. package/static/icons/calendar-fill.svg +4 -0
  155. package/static/icons/calendar.svg +4 -0
  156. package/static/icons/camera-video-fill.svg +4 -0
  157. package/static/icons/camera-video.svg +4 -0
  158. package/static/icons/camera.svg +5 -0
  159. package/static/icons/capslock-fill.svg +3 -0
  160. package/static/icons/capslock.svg +3 -0
  161. package/static/icons/chat-fill.svg +3 -0
  162. package/static/icons/chat.svg +3 -0
  163. package/static/icons/check-box.svg +4 -0
  164. package/static/icons/check-circle.svg +4 -0
  165. package/static/icons/check.svg +3 -0
  166. package/static/icons/chevron-compact-down.svg +3 -0
  167. package/static/icons/chevron-compact-left.svg +3 -0
  168. package/static/icons/chevron-compact-right.svg +3 -0
  169. package/static/icons/chevron-compact-up.svg +3 -0
  170. package/static/icons/chevron-down.svg +3 -0
  171. package/static/icons/chevron-left.svg +3 -0
  172. package/static/icons/chevron-right.svg +3 -0
  173. package/static/icons/chevron-up.svg +3 -0
  174. package/static/icons/circle-fill.svg +3 -0
  175. package/static/icons/circle-half.svg +3 -0
  176. package/static/icons/circle-slash.svg +3 -0
  177. package/static/icons/circle.svg +3 -0
  178. package/static/icons/clock-fill.svg +3 -0
  179. package/static/icons/clock.svg +4 -0
  180. package/static/icons/cloud-download.svg +5 -0
  181. package/static/icons/cloud-fill.svg +3 -0
  182. package/static/icons/cloud-upload.svg +5 -0
  183. package/static/icons/cloud.svg +3 -0
  184. package/static/icons/code-slash.svg +3 -0
  185. package/static/icons/code.svg +3 -0
  186. package/static/icons/columns-gutters.svg +3 -0
  187. package/static/icons/columns.svg +4 -0
  188. package/static/icons/command.svg +4 -0
  189. package/static/icons/compass.svg +5 -0
  190. package/static/icons/cone-striped.svg +4 -0
  191. package/static/icons/cone.svg +4 -0
  192. package/static/icons/controller.svg +5 -0
  193. package/static/icons/credit-card.svg +5 -0
  194. package/static/icons/cursor-fill.svg +3 -0
  195. package/static/icons/cursor.svg +3 -0
  196. package/static/icons/dash.svg +3 -0
  197. package/static/icons/diamond-half.svg +3 -0
  198. package/static/icons/diamond.svg +3 -0
  199. package/static/icons/display-fill.svg +5 -0
  200. package/static/icons/display.svg +4 -0
  201. package/static/icons/document-code.svg +4 -0
  202. package/static/icons/document-diff.svg +5 -0
  203. package/static/icons/document-richtext.svg +4 -0
  204. package/static/icons/document-spreadsheet.svg +5 -0
  205. package/static/icons/document-text.svg +4 -0
  206. package/static/icons/document.svg +3 -0
  207. package/static/icons/documents-alt.svg +4 -0
  208. package/static/icons/documents.svg +4 -0
  209. package/static/icons/dot.svg +3 -0
  210. package/static/icons/download.svg +5 -0
  211. package/static/icons/egg-fried.svg +4 -0
  212. package/static/icons/eject-fill.svg +3 -0
  213. package/static/icons/eject.svg +3 -0
  214. package/static/icons/envelope-fill.svg +3 -0
  215. package/static/icons/envelope-open-fill.svg +3 -0
  216. package/static/icons/envelope-open.svg +5 -0
  217. package/static/icons/envelope.svg +4 -0
  218. package/static/icons/eye-fill.svg +4 -0
  219. package/static/icons/eye-slash-fill.svg +5 -0
  220. package/static/icons/eye-slash.svg +6 -0
  221. package/static/icons/eye.svg +4 -0
  222. package/static/icons/filter.svg +3 -0
  223. package/static/icons/flag-fill.svg +4 -0
  224. package/static/icons/flag.svg +4 -0
  225. package/static/icons/folder-fill.svg +3 -0
  226. package/static/icons/folder-symlink-fill.svg +3 -0
  227. package/static/icons/folder-symlink.svg +5 -0
  228. package/static/icons/folder.svg +4 -0
  229. package/static/icons/fonts.svg +3 -0
  230. package/static/icons/forward-fill.svg +3 -0
  231. package/static/icons/forward.svg +3 -0
  232. package/static/icons/gear-fill.svg +3 -0
  233. package/static/icons/gear-wide-connected.svg +4 -0
  234. package/static/icons/gear-wide.svg +3 -0
  235. package/static/icons/gear.svg +4 -0
  236. package/static/icons/geo.svg +5 -0
  237. package/static/icons/graph-down.svg +5 -0
  238. package/static/icons/graph-up.svg +5 -0
  239. package/static/icons/grid-fill.svg +6 -0
  240. package/static/icons/grid.svg +3 -0
  241. package/static/icons/hammer.svg +4 -0
  242. package/static/icons/hash.svg +3 -0
  243. package/static/icons/heart-fill.svg +3 -0
  244. package/static/icons/heart.svg +3 -0
  245. package/static/icons/house-fill.svg +4 -0
  246. package/static/icons/house.svg +4 -0
  247. package/static/icons/image-alt.svg +4 -0
  248. package/static/icons/image-fill.svg +3 -0
  249. package/static/icons/image.svg +5 -0
  250. package/static/icons/images.svg +5 -0
  251. package/static/icons/inbox-fill.svg +4 -0
  252. package/static/icons/inbox.svg +4 -0
  253. package/static/icons/inboxes-fill.svg +4 -0
  254. package/static/icons/inboxes.svg +4 -0
  255. package/static/icons/info-fill.svg +3 -0
  256. package/static/icons/info-square-fill.svg +3 -0
  257. package/static/icons/info-square.svg +5 -0
  258. package/static/icons/info.svg +5 -0
  259. package/static/icons/justify-left.svg +3 -0
  260. package/static/icons/justify-right.svg +3 -0
  261. package/static/icons/justify.svg +3 -0
  262. package/static/icons/kanban-fill.svg +3 -0
  263. package/static/icons/kanban.svg +6 -0
  264. package/static/icons/laptop.svg +4 -0
  265. package/static/icons/layout-sidebar-reverse.svg +4 -0
  266. package/static/icons/layout-sidebar.svg +4 -0
  267. package/static/icons/layout-split.svg +3 -0
  268. package/static/icons/list-check.svg +3 -0
  269. package/static/icons/list-ol.svg +4 -0
  270. package/static/icons/list-task.svg +5 -0
  271. package/static/icons/list-ul.svg +3 -0
  272. package/static/icons/list.svg +3 -0
  273. package/static/icons/lock-fill.svg +4 -0
  274. package/static/icons/lock.svg +3 -0
  275. package/static/icons/map.svg +3 -0
  276. package/static/icons/mic.svg +4 -0
  277. package/static/icons/moon.svg +3 -0
  278. package/static/icons/music-player-fill.svg +4 -0
  279. package/static/icons/music-player.svg +5 -0
  280. package/static/icons/option.svg +3 -0
  281. package/static/icons/outlet.svg +5 -0
  282. package/static/icons/pause-fill.svg +3 -0
  283. package/static/icons/pause.svg +3 -0
  284. package/static/icons/pen.svg +5 -0
  285. package/static/icons/pencil.svg +4 -0
  286. package/static/icons/people-fill.svg +3 -0
  287. package/static/icons/people.svg +3 -0
  288. package/static/icons/person-fill.svg +3 -0
  289. package/static/icons/person.svg +3 -0
  290. package/static/icons/phone-landscape.svg +4 -0
  291. package/static/icons/phone.svg +4 -0
  292. package/static/icons/pie-chart-fill.svg +3 -0
  293. package/static/icons/pie-chart.svg +4 -0
  294. package/static/icons/play-fill.svg +3 -0
  295. package/static/icons/play.svg +3 -0
  296. package/static/icons/plug.svg +4 -0
  297. package/static/icons/plus.svg +4 -0
  298. package/static/icons/power.svg +4 -0
  299. package/static/icons/question-fill.svg +3 -0
  300. package/static/icons/question-square-fill.svg +3 -0
  301. package/static/icons/question-square.svg +4 -0
  302. package/static/icons/question.svg +4 -0
  303. package/static/icons/reply-all-fill.svg +4 -0
  304. package/static/icons/reply-all.svg +4 -0
  305. package/static/icons/reply-fill.svg +3 -0
  306. package/static/icons/reply.svg +3 -0
  307. package/static/icons/screwdriver.svg +3 -0
  308. package/static/icons/search.svg +4 -0
  309. package/static/icons/shield-fill.svg +3 -0
  310. package/static/icons/shield-lock-fill.svg +3 -0
  311. package/static/icons/shield-lock.svg +5 -0
  312. package/static/icons/shield-shaded.svg +4 -0
  313. package/static/icons/shield.svg +3 -0
  314. package/static/icons/shift-fill.svg +3 -0
  315. package/static/icons/shift.svg +3 -0
  316. package/static/icons/skip-backward-fill.svg +4 -0
  317. package/static/icons/skip-backward.svg +3 -0
  318. package/static/icons/skip-end-fill.svg +5 -0
  319. package/static/icons/skip-end.svg +4 -0
  320. package/static/icons/skip-forward-fill.svg +5 -0
  321. package/static/icons/skip-forward.svg +3 -0
  322. package/static/icons/skip-start-fill.svg +4 -0
  323. package/static/icons/skip-start.svg +4 -0
  324. package/static/icons/speaker.svg +4 -0
  325. package/static/icons/square-fill.svg +3 -0
  326. package/static/icons/square-half.svg +3 -0
  327. package/static/icons/square.svg +3 -0
  328. package/static/icons/star-fill.svg +3 -0
  329. package/static/icons/star-half.svg +3 -0
  330. package/static/icons/star.svg +3 -0
  331. package/static/icons/stop-fill.svg +3 -0
  332. package/static/icons/stop.svg +3 -0
  333. package/static/icons/stopwatch-fill.svg +3 -0
  334. package/static/icons/stopwatch.svg +5 -0
  335. package/static/icons/sun.svg +4 -0
  336. package/static/icons/table.svg +7 -0
  337. package/static/icons/tablet-landscape.svg +4 -0
  338. package/static/icons/tablet.svg +4 -0
  339. package/static/icons/tag-fill.svg +3 -0
  340. package/static/icons/tag.svg +4 -0
  341. package/static/icons/terminal-fill.svg +3 -0
  342. package/static/icons/terminal.svg +4 -0
  343. package/static/icons/text-center.svg +3 -0
  344. package/static/icons/text-indent-left.svg +3 -0
  345. package/static/icons/text-indent-right.svg +3 -0
  346. package/static/icons/text-left.svg +3 -0
  347. package/static/icons/text-right.svg +3 -0
  348. package/static/icons/three-dots-vertical.svg +3 -0
  349. package/static/icons/three-dots.svg +3 -0
  350. package/static/icons/toggle-off.svg +3 -0
  351. package/static/icons/toggle-on.svg +3 -0
  352. package/static/icons/toggles.svg +4 -0
  353. package/static/icons/tools.svg +4 -0
  354. package/static/icons/trash-fill.svg +3 -0
  355. package/static/icons/trash.svg +4 -0
  356. package/static/icons/triangle-fill.svg +3 -0
  357. package/static/icons/triangle-half.svg +3 -0
  358. package/static/icons/triangle.svg +3 -0
  359. package/static/icons/trophy.svg +6 -0
  360. package/static/icons/tv-fill.svg +3 -0
  361. package/static/icons/tv.svg +3 -0
  362. package/static/icons/type-bold.svg +3 -0
  363. package/static/icons/type-h1.svg +3 -0
  364. package/static/icons/type-h2.svg +3 -0
  365. package/static/icons/type-h3.svg +3 -0
  366. package/static/icons/type-italic.svg +3 -0
  367. package/static/icons/type-strikethrough.svg +4 -0
  368. package/static/icons/type-underline.svg +4 -0
  369. package/static/icons/type.svg +3 -0
  370. package/static/icons/unlock-fill.svg +4 -0
  371. package/static/icons/unlock.svg +3 -0
  372. package/static/icons/upload.svg +4 -0
  373. package/static/icons/volume-down-fill.svg +4 -0
  374. package/static/icons/volume-down.svg +4 -0
  375. package/static/icons/volume-mute-fill.svg +4 -0
  376. package/static/icons/volume-mute.svg +4 -0
  377. package/static/icons/volume-up-fill.svg +6 -0
  378. package/static/icons/volume-up.svg +6 -0
  379. package/static/icons/wallet.svg +3 -0
  380. package/static/icons/watch.svg +5 -0
  381. package/static/icons/wifi.svg +5 -0
  382. package/static/icons/window.svg +5 -0
  383. package/static/icons/wrench.svg +3 -0
  384. package/static/icons/x-circle-fill.svg +3 -0
  385. package/static/icons/x-circle.svg +5 -0
  386. package/static/icons/x-octagon-fill.svg +3 -0
  387. package/static/icons/x-octagon.svg +4 -0
  388. package/static/icons/x-square-fill.svg +3 -0
  389. package/static/icons/x-square.svg +4 -0
  390. package/static/icons/x.svg +4 -0
  391. package/static/index.html +752 -0
  392. package/static/js/emailengine.js +581 -0
  393. package/static/js/jquery-3.4.1.slim.min.js +2 -0
  394. package/static/js/moment-with-locales-2.24.0.min.js +1 -0
  395. package/static/js/popper.min.js +5 -0
  396. package/static/logo.png +0 -0
  397. package/systemd/emailengine.service +89 -0
  398. package/systemd/nginx-proxy.conf +77 -0
  399. package/views/error.hbs +2 -0
  400. package/workers/api.js +2266 -0
  401. package/workers/arena.js +89 -0
  402. package/workers/imap.js +611 -0
  403. package/workers/smtp.js +278 -0
  404. package/workers/submit.js +214 -0
  405. package/workers/webhooks.js +134 -0
@@ -0,0 +1,752 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="h-100">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
6
+ <meta name="description" content="EmailEngine Homepage" />
7
+ <title>EmailEngine</title>
8
+
9
+ <link rel="apple-touch-icon" href="/static/favicon/apple-touch-icon.png" sizes="180x180" />
10
+ <link rel="icon" href="/static/favicon/favicon-32x32.png" sizes="32x32" type="image/png" />
11
+ <link rel="icon" href="/static/favicon/favicon-16x16.png" sizes="16x16" type="image/png" />
12
+ <link rel="manifest" href="/static/favicon/manifest.json" />
13
+ <link rel="icon" href="/favicon.ico" />
14
+
15
+ <link href="/static/bootstrap-4.6.0-dist/css/bootstrap.min.css" rel="stylesheet" />
16
+ <link href="/static/css/callout.css" rel="stylesheet" />
17
+ <link href="/static/css/emailengine.css" rel="stylesheet" />
18
+ </head>
19
+ <body class="d-flex flex-column h-100">
20
+ <main role="main" class="flex-shrink-0">
21
+ <div class="container mt-4">
22
+ <div id="toastContainer" style="position: absolute; top: 50px; right: 50px; min-width: 250px"></div>
23
+
24
+ <img src="/static/logo.png" style="display: block; float: left; margin: 10px 10px 0 0; max-width: 32px; max-height: 32px" />
25
+
26
+ <h1>EmailEngine</h1>
27
+
28
+ <div class="row mt-4">
29
+ <div class="col-12 col-sm-12 col-md-12 col-lg-8">
30
+ <ul class="nav nav-tabs" id="myTab" role="tablist">
31
+ <li class="nav-item">
32
+ <a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true"
33
+ >Overview</a
34
+ >
35
+ </li>
36
+ <li class="nav-item">
37
+ <a class="nav-link" id="docs-tab" data-toggle="tab" href="#docs" role="tab" aria-controls="docs" aria-selected="false">
38
+ <img src="/static/icons/document-code.svg" width="20" height="20" title="Documentation" />
39
+ Documentation</a
40
+ >
41
+ </li>
42
+ <li class="nav-item">
43
+ <a
44
+ class="nav-link"
45
+ id="settings-tab"
46
+ data-toggle="tab"
47
+ href="#settings"
48
+ role="tab"
49
+ aria-controls="settings"
50
+ aria-selected="false"
51
+ >
52
+ <img src="/static/icons/gear.svg" width="20" height="20" title="Setings" />
53
+ Settings</a
54
+ >
55
+ </li>
56
+
57
+ <li class="nav-item">
58
+ <a class="nav-link" id="logs-tab" data-toggle="tab" href="#logs" role="tab" aria-controls="logs" aria-selected="false">
59
+ <img src="/static/icons/download.svg" width="20" height="20" title="Logs" />
60
+ Logs</a
61
+ >
62
+ </li>
63
+ </ul>
64
+
65
+ <div class="tab-content mt-4">
66
+ <div class="tab-pane active" id="home" role="tabpanel" aria-labelledby="home-tab">
67
+ <p>
68
+ EmailEngine is a self hosted headless email client for accessing IMAP accounts over REST API. EmailEngine connects to user's
69
+ IMAP account, translates API requests to IMAP and also sends webhooks for changes like new or deleted emails.
70
+ </p>
71
+
72
+ <div class="row">
73
+ <div class="col-sm-3">
74
+ <div class="bd-callout bd-callout-info text-center">
75
+ <h4 class="stats-counter-events_messageNew" title="New messages found today"></h4>
76
+ <div class="small-text">New messages</div>
77
+ </div>
78
+ </div>
79
+
80
+ <div class="col-sm-3">
81
+ <div class="bd-callout bd-callout-info text-center">
82
+ <h4 class="stats-counter-events_messageDeleted" title="Deleted messages found today"></h4>
83
+ <div class="small-text">Deleted messages</div>
84
+ </div>
85
+ </div>
86
+
87
+ <div class="col-sm-3">
88
+ <div class="bd-callout bd-callout-success text-center">
89
+ <h4 class="stats-counter-webhooks_success" title="Number of webhooks successfully sent today"></h4>
90
+ <div class="small-text">Webhooks sent</div>
91
+ </div>
92
+ </div>
93
+
94
+ <div class="col-sm-3">
95
+ <div class="bd-callout bd-callout-danger text-center">
96
+ <h4 class="stats-counter-webhooks_fail" title="Number of webhooks that failed today"></h4>
97
+ <div class="small-text">Webhooks failed</div>
98
+ </div>
99
+ </div>
100
+ </div>
101
+
102
+ <div class="table-responsive">
103
+ <table class="table table-hover">
104
+ <thead>
105
+ <tr>
106
+ <th>Accounts</th>
107
+ <th>Connecting</th>
108
+ <th>Connected</th>
109
+ <th>Failed Login</th>
110
+ <th>Failed Connection</th>
111
+ <th>&nbsp;</th>
112
+ </tr>
113
+ </thead>
114
+ <tbody>
115
+ <tr>
116
+ <th class="text-center"><a href="#" class="btn btn-primary stats-accounts">0</a></th>
117
+ <td class="text-center"><a href="#" class="btn btn-info stats-conn-connecting">0</a></td>
118
+ <td class="text-center"><a href="#" class="btn btn-info stats-conn-connected">0</a></td>
119
+ <td class="text-center"><a href="#" class="btn btn-info stats-conn-authenticationError">0</a></td>
120
+ <td class="text-center"><a href="#" class="btn btn-info stats-conn-connectError">0</a></td>
121
+ <td class="text-right">
122
+ <button type="submit" class="btn btn-primary" id="addAccountButton">
123
+ <svg
124
+ class="bi bi-person-plus"
125
+ width="1em"
126
+ height="1em"
127
+ viewBox="0 0 16 16"
128
+ fill="currentColor"
129
+ xmlns="http://www.w3.org/2000/svg"
130
+ >
131
+ <path
132
+ fill-rule="evenodd"
133
+ d="M11 14s1 0 1-1-1-4-6-4-6 3-6 4 1 1 1 1h10zm-9.995-.944v-.002.002zM1.022 13h9.956a.274.274 0 00.014-.002l.008-.002c-.001-.246-.154-.986-.832-1.664C9.516 10.68 8.289 10 6 10c-2.29 0-3.516.68-4.168 1.332-.678.678-.83 1.418-.832 1.664a1.05 1.05 0 00.022.004zm9.974.056v-.002.002zM6 7a2 2 0 100-4 2 2 0 000 4zm3-2a3 3 0 11-6 0 3 3 0 016 0zm4.5 0a.5.5 0 01.5.5v2a.5.5 0 01-.5.5h-2a.5.5 0 010-1H13V5.5a.5.5 0 01.5-.5z"
134
+ clip-rule="evenodd"
135
+ />
136
+ <path
137
+ fill-rule="evenodd"
138
+ d="M13 7.5a.5.5 0 01.5-.5h2a.5.5 0 010 1H14v1.5a.5.5 0 01-1 0v-2z"
139
+ clip-rule="evenodd"
140
+ />
141
+ </svg>
142
+ </button>
143
+ </td>
144
+ </tr>
145
+ </tbody>
146
+ </table>
147
+ </div>
148
+
149
+ <p class="mt-3">EmailEngine allows you to:</p>
150
+
151
+ <ul>
152
+ <li>
153
+ List folders and messages in a user's email account
154
+ <span class="text-muted">– EmailEngine provides an easy to use paging and sorts newer messages first</span>
155
+ </li>
156
+ <li>
157
+ Track changes in user's email account
158
+ <span class="text-muted">– EmailEngine uses webhooks to notify your application</span>
159
+ </li>
160
+ <li>
161
+ Send out emails on behalf of the user
162
+ <span class="text-muted"
163
+ >– EmailEngine sets all required headers and message flags when replying or forwarding a message and also uploads
164
+ the message to the Sent Mail folder</span
165
+ >
166
+ </li>
167
+ </ul>
168
+ </div>
169
+
170
+ <div class="tab-pane" id="docs" role="tabpanel" aria-labelledby="docs-tab">
171
+ <div class="bd-callout bd-callout-info">
172
+ <p style="margin: 1rem">
173
+ <a href="/docs" target="_blank" class="btn btn-primary">
174
+ <svg
175
+ xmlns="http://www.w3.org/2000/svg"
176
+ width="16"
177
+ height="16"
178
+ fill="currentColor"
179
+ class="bi bi-arrow-right-square"
180
+ viewBox="0 0 16 16"
181
+ >
182
+ <path
183
+ fill-rule="evenodd"
184
+ d="M15 2a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V2zM0 2a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V2zm4.5 5.5a.5.5 0 0 0 0 1h5.793l-2.147 2.146a.5.5 0 0 0 .708.708l3-3a.5.5 0 0 0 0-.708l-3-3a.5.5 0 1 0-.708.708L10.293 7.5H4.5z"
185
+ />
186
+ </svg>
187
+
188
+ API Reference
189
+ </a>
190
+ </p>
191
+ </div>
192
+
193
+ <h4>Getting started</h4>
194
+
195
+ <h5 class="mt-4">1. Set up webhook target</h5>
196
+
197
+ <p>
198
+ Open the <em>Settings</em> tab and set an URL for webhooks. Whenever something happens with any of the tracked email
199
+ accounts you get a notification to this URL.
200
+ </p>
201
+
202
+ <p>For example if flags are updated for a message you'd get a notification that looks like this:</p>
203
+
204
+ <pre>
205
+ {
206
+ "account": "example",
207
+ "path": "[Google Mail]/All Mail",
208
+ "event": "messageUpdated",
209
+ "data": {
210
+ "id": "AAAAAQAAAeE",
211
+ "uid": 350861,
212
+ "changes": {
213
+ "flags": {
214
+ "added": [
215
+ "\\Seen"
216
+ ]
217
+ }
218
+ }
219
+ }
220
+ }</pre
221
+ >
222
+
223
+ <h5 class="mt-4">2. Register an email account with EmailEngine</h5>
224
+ <p>
225
+ You need IMAP and SMTP settings and also provide some kind of an identification string value for this account. You can use
226
+ the same IDs as your main system or generate some unique ones. This value is later needed to identify this account and to
227
+ perform operations on it.
228
+ </p>
229
+
230
+ <pre>
231
+ $ curl -XPOST "<span class="domainName">localhost:3000</span>/v1/account" -H "content-type: application/json" -d '{
232
+ "account": "example",
233
+ "name": "My Example Account",
234
+ "imap": {
235
+ "host": "imap.gmail.com",
236
+ "port": 993,
237
+ "secure": true,
238
+ "auth": {
239
+ "user": "myuser@gmail.com",
240
+ "pass": "verysecret"
241
+ }
242
+ },
243
+ "smtp": {
244
+ "host": "smtp.gmail.com",
245
+ "port": 465,
246
+ "secure": true,
247
+ "auth": {
248
+ "user": "myuser@gmail.com",
249
+ "pass": "verysecret"
250
+ }
251
+ }
252
+ }'</pre>
253
+
254
+ <h5 class="mt-4">3. That's about it</h5>
255
+
256
+ <p>
257
+ Now whenever something happens you get a notification. If this is not enought then you can perform normal operations with
258
+ the IMAP account as well. See the <a href="/docs">API docs</a> page for details.
259
+ </p>
260
+
261
+ <h5 class="mt-4">Bonus! List some messages</h5>
262
+
263
+ <p>
264
+ EmailEngine returns paged results, newer messages first. So to get the first page or in other words the newest messages in a
265
+ mailbox folder you can do it like this (notice the "example" id string that we set earlier in the request URL):
266
+ </p>
267
+
268
+ <pre>$ curl -XGET "<span class="domainName">localhost:3000</span>/v1/account/example/messages?path=INBOX"</pre>
269
+
270
+ <p>In the response you should see a listing of messages.</p>
271
+
272
+ <pre>
273
+ {
274
+ "page": 0,
275
+ "pages": 10,
276
+ "messages": [
277
+ {
278
+ "id": "AAAAAQAAAeE",
279
+ "uid": 481,
280
+ "date": "2019-10-07T06:05:23.000Z",
281
+ "size": 4334,
282
+ "subject": "Test message",
283
+ "from": {
284
+ "name": "Peter Põder",
285
+ "address": "Peter.Poder@example.com"
286
+ },
287
+ "to": [
288
+ {
289
+ "name": "",
290
+ "address": "andris@emailengine.app"
291
+ }
292
+ ],
293
+ "messageId": "<0ebdd7b084794911b03986c827128f1b@example.com>",
294
+ "text": {
295
+ "id": "AAAAAQAAAeGTkaExkaEykA",
296
+ "encodedSize": {
297
+ "plain": 17,
298
+ "html": 2135
299
+ }
300
+ }
301
+ },
302
+ ...
303
+ ]
304
+ }</pre
305
+ >
306
+
307
+ <div class="mt-4"></div>
308
+ </div>
309
+
310
+ <div class="tab-pane" id="settings" role="tabpanel" aria-labelledby="settings-tab">
311
+ <form id="settingsForm" class="needs-validation" novalidate>
312
+ <div class="card card-body">
313
+ <h5 class="card-title">Webhooks</h5>
314
+
315
+ <div class="form-group">
316
+ <label for="settingsWebhooks">Webhook URL</label>
317
+ <input type="url" class="form-control" id="settingsWebhooks" />
318
+ <div class="invalid-feedback">Enter valid URL for the webhook</div>
319
+ <small class="form-text text-muted"
320
+ >EmailEngine makes a POST request against this URL for every detected change in user's account. This includes
321
+ new messages, deleted messages and flag changes. Leave empty to disable notifications.</small
322
+ >
323
+ </div>
324
+
325
+ <div class="form-group form-check">
326
+ <input type="checkbox" class="form-check-input" id="settingsNotifyText" />
327
+ <label class="form-check-label" for="settingsNotifyText">Include text content in new email webhooks</label>
328
+ <small class="form-text text-muted"
329
+ >By default only message metadata without HTML or plaintext values is included in the webhook to keep
330
+ notification payload size at minimum. If enabled then text values are also added to the webhook.</small
331
+ >
332
+ </div>
333
+
334
+ <div class="form-group">
335
+ <label for="settingsNotifyTextSize">Maximum text size</label>
336
+ <input type="number" class="form-control" id="settingsNotifyTextSize" min="0" />
337
+ <div class="invalid-feedback">Enter valid number</div>
338
+ <small class="form-text text-muted"
339
+ >To keep webhook size with text values in check you can define maximum text size limit. Longer texts are cropped
340
+ to fit that size. This limit is applied per text-type, so if the limit is 1000 bytes and email has both
341
+ plaintext and html content, then you get 1000 bytes of plaintext and 1000 bytes of HTML.</small
342
+ >
343
+ </div>
344
+
345
+ <div class="form-group">
346
+ <label for="settingsWebhookEvents">Events to listen</label>
347
+ <input type="text" class="form-control" id="settingsWebhookEvents" />
348
+ <div class="invalid-feedback">Enter valid events</div>
349
+ <small class="form-text text-muted"
350
+ >Comma separated list of event names (case sensitive). Use <code>*</code> for all events.<br />
351
+ Available events: <em><span id="infoEventTypes"></span></em
352
+ ></small>
353
+ </div>
354
+
355
+ <div class="form-group">
356
+ <label for="settingsNotifyHeaders">Headers to include</label>
357
+ <input type="text" class="form-control" id="settingsNotifyHeaders" />
358
+ <div class="invalid-feedback">Enter valid headers</div>
359
+ <small class="form-text text-muted"
360
+ >Comma separated list of header names. Use <code>*</code> for all headers or leave empty to not include headers
361
+ in the webhook.</small
362
+ >
363
+ </div>
364
+ </div>
365
+
366
+ <div class="card card-body mt-3">
367
+ <h5 class="card-title">Authentication</h5>
368
+ <div class="form-group">
369
+ <label for="settingsAuthServer">Auth Server URL</label>
370
+ <input type="url" class="form-control" id="settingsAuthServer" />
371
+ <div class="invalid-feedback">Enter valid URL for Auth Server</div>
372
+ <small class="form-text text-muted"
373
+ >You can configure accounts to resolve authentication info from an
374
+ <a href="https://github.com/postalsys/emailengine/blob/master/examples/auth-server.js" target="_blank"
375
+ >authentication server</a
376
+ >
377
+ instead of setting fixed credentials. Whenever EmailEngine needs to authenticate such account it makes a GET
378
+ request against this URL with 2 additional query arguments - <code>account</code> as the account ID and
379
+ <code>proto</code> which is either "imap" or "smtp". Recommended when using OAuth accounts.</small
380
+ >
381
+ </div>
382
+ </div>
383
+
384
+ <div class="card card-body mt-3">
385
+ <h5 class="card-title">OAuth2 <span class="text-muted">(Gmail only)</span></h5>
386
+
387
+ <p>
388
+ <small class="text-muted">
389
+ You OAuth2 project must have the following scope enabled:
390
+ <strong>&quot;https://mail.google.com/&quot;</strong>.<br />
391
+ Setting these values allows you to use the OAuth2 tab in the "Add account" form.
392
+ </small>
393
+ </p>
394
+
395
+ <div class="form-group">
396
+ <label for="settingsGmailClientId">Client Id</label>
397
+ <input type="text" class="form-control" id="settingsGmailClientId" />
398
+ <div class="invalid-feedback">Enter valid client id</div>
399
+ <small class="form-text text-muted">OAuth2 client id.</small>
400
+ </div>
401
+
402
+ <div class="form-group">
403
+ <label for="settingsGmailClientSecret">Client Secret</label>
404
+ <input type="text" class="form-control" id="settingsGmailClientSecret" />
405
+ <div class="invalid-feedback">Enter valid client id</div>
406
+ <small class="form-text text-muted">OAuth2 client secret.</small>
407
+ </div>
408
+
409
+ <div class="form-group">
410
+ <label for="settingsGmailRedirectUrl">Callback URL</label>
411
+ <input type="url" class="form-control" id="settingsGmailRedirectUrl" />
412
+ <div class="invalid-feedback">Enter valid URL for the callback</div>
413
+ <small class="form-text text-muted"
414
+ >Redirect URL for OAuth2. Must point to your EmailEngine installation and end with <code>/oauth</code></small
415
+ >
416
+ </div>
417
+ </div>
418
+
419
+ <div class="card card-body mt-3">
420
+ <h5 class="card-title">IMAP logs</h5>
421
+
422
+ <p>
423
+ <small class="text-muted">
424
+ In case there are issues syncing some specific accounts you can turn on IMAP logging. This stores all IMAP
425
+ traffic except user credentials and message content for selected accounts. You can then download these logs for
426
+ inspection.
427
+ </small>
428
+ </p>
429
+
430
+ <div class="form-group form-check">
431
+ <input type="checkbox" class="form-check-input" id="settingsLogsAll" />
432
+ <label class="form-check-label" for="settingsLogsAll">Store IMAP logs for all accounts</label>
433
+ <small class="form-text text-muted">Not recommended if EmailEngine tracks large number of accounts</small>
434
+ </div>
435
+
436
+ <div class="form-group">
437
+ <label for="settingsLogsAccounts">Store IMAP logs for the following accounts</label>
438
+ <textarea class="form-control" id="settingsLogsAccounts" rows="3"></textarea>
439
+ <small class="form-text text-muted">Enter one account ID per line</small>
440
+ </div>
441
+
442
+ <div class="form-group form-check">
443
+ <input type="checkbox" class="form-check-input" id="settingsResetLoggedAccounts" />
444
+ <label class="form-check-label" for="settingsResetLoggedAccounts">Reconnect logged accounts</label>
445
+ <small class="form-text text-muted"
446
+ >Mark this checkbox if you want to make sure that logged accounts are reconnected and authenticated (one time
447
+ action, checkbox state is not stored). Established connections are kept alive as long as possible so enabling
448
+ logging for existing users without forced reconnect may not give any useful info.</small
449
+ >
450
+ </div>
451
+
452
+ <div class="form-group">
453
+ <label for="settingsLogsMaxLogLines">Maximum lines of logs to store</label>
454
+ <input type="number" class="form-control" id="settingsLogsMaxLogLines" min="0" max="1000000" />
455
+ <div class="invalid-feedback">Enter valid number between 0 and 1000000</div>
456
+ <small class="form-text text-muted"
457
+ >Logs are stored in Redis which in other words means RAM, so it might not be a good idea to store too much data
458
+ in it</small
459
+ >
460
+ </div>
461
+ </div>
462
+
463
+ <div class="mt-3">
464
+ <button type="submit" class="btn btn-primary">Update settings</button>
465
+ </div>
466
+ <div class="mt-3"></div>
467
+ </form>
468
+ </div>
469
+
470
+ <div class="tab-pane" id="logs" role="tabpanel" aria-labelledby="logs-tab">
471
+ <form id="logsForm" class="needs-validation" novalidate>
472
+ <p class="text-muted">
473
+ You can download stored logs here for accounts that have logging enabled. Logging can be enabled either for all or
474
+ specific accounts in the Settings tab.
475
+ </p>
476
+ <div class="form-group">
477
+ <label for="logsAccount">Account ID</label>
478
+ <input type="text" class="form-control" id="logsAccount" required />
479
+ <div class="invalid-feedback">Enter valid account ID</div>
480
+ </div>
481
+
482
+ <div class="mt-3">
483
+ <button type="submit" class="btn btn-primary">Download logs</button>
484
+ </div>
485
+ <div class="mt-3"></div>
486
+ </form>
487
+ </div>
488
+ </div>
489
+ </div>
490
+ </div>
491
+ </div>
492
+ </main>
493
+
494
+ <footer class="footer mt-auto py-3">
495
+ <div class="container">
496
+ <div class="row">
497
+ <div class="col-sm-8">
498
+ <a href="https://emailengine.app" target="_blank">EmailEngine</a>
499
+ <span class="text-muted app-version"></span> |
500
+ <span class="text-muted">&copy; 2020-2021</span>
501
+ <a class="text-muted" href="mailto:andris@emailengine.app" target="_blank">Andris Reinman</a> |
502
+ <span class="text-muted">Licensed under </span><span class="text-muted app-license"></span>
503
+ </div>
504
+ </div>
505
+ <div class="row no-mit-license d-none">
506
+ <div class="col-sm-8 text-muted">
507
+ Postal Systems subscribers can <a href="https://postalsys.com/plans">upgrade EmailEngine</a> to use MIT license instead.
508
+ </div>
509
+ </div>
510
+ </div>
511
+ </footer>
512
+
513
+ <div id="modals">
514
+ <div class="modal fade" id="accountsModal" tabindex="-1" role="dialog" aria-hidden="true">
515
+ <div class="modal-dialog modal-dialog-scrollable modal-xl" role="document">
516
+ <div class="modal-content">
517
+ <div class="modal-header">
518
+ <h5 class="modal-title" id="accountsModalTitle">Accounts</h5>
519
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
520
+ <span aria-hidden="true">&times;</span>
521
+ </button>
522
+ </div>
523
+ <div class="modal-body">
524
+ <table class="table table-hover users-table">
525
+ <thead class="thead-light">
526
+ <tr>
527
+ <th class="row-account">Account</th>
528
+ <th class="row-name">Name</th>
529
+ <th class="row-state">State</th>
530
+ <th class="row-description">Info</th>
531
+ <th class="row-btn"></th>
532
+ </tr>
533
+ </thead>
534
+ <tbody id="accountsTableBody"></tbody>
535
+ </table>
536
+ </div>
537
+ <div class="modal-footer">
538
+ <button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
539
+ </div>
540
+ </div>
541
+ </div>
542
+ </div>
543
+
544
+ <div class="modal fade" id="addAccountModal" tabindex="-1" role="dialog" aria-hidden="true">
545
+ <form id="addAccountForm" class="needs-validation" novalidate>
546
+ <div class="modal-dialog modal-lg" role="document">
547
+ <div class="modal-content">
548
+ <div class="modal-header">
549
+ <h5 class="modal-title" id="addAccountModalTitle">Add account</h5>
550
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">
551
+ <span aria-hidden="true">&times;</span>
552
+ </button>
553
+ </div>
554
+ <div class="modal-body">
555
+ <div class="form-group row">
556
+ <label for="addAccountFormId" class="col-sm-2 col-form-label">Account ID</label>
557
+ <div class="col-sm-5">
558
+ <input type="text" class="form-control" id="addAccountFormId" required />
559
+ </div>
560
+ </div>
561
+
562
+ <div class="form-group row">
563
+ <label for="addAccountFormName" class="col-sm-2 col-form-label">Name</label>
564
+ <div class="col-sm-5">
565
+ <input type="text" class="form-control" id="addAccountFormName" required />
566
+ </div>
567
+ </div>
568
+
569
+ <hr />
570
+ <ul class="nav nav-tabs" id="addAccountTab" role="tablist">
571
+ <li class="nav-item">
572
+ <a
573
+ class="nav-link active"
574
+ id="add-account-imap-tab"
575
+ data-toggle="tab"
576
+ href="#add-account-imap"
577
+ role="tab"
578
+ aria-controls="home"
579
+ aria-selected="true"
580
+ >IMAP</a
581
+ >
582
+ </li>
583
+ <li class="nav-item">
584
+ <a
585
+ class="nav-link"
586
+ id="add-account-smtp-tab"
587
+ data-toggle="tab"
588
+ href="#add-account-smtp"
589
+ role="tab"
590
+ aria-controls="docs"
591
+ aria-selected="false"
592
+ >
593
+ SMTP</a
594
+ >
595
+ </li>
596
+ <li class="nav-item">
597
+ <a
598
+ class="nav-link"
599
+ id="add-account-oauth2-tab"
600
+ data-toggle="tab"
601
+ href="#add-account-oauth2"
602
+ role="tab"
603
+ aria-controls="docs"
604
+ aria-selected="false"
605
+ >
606
+ OAuth2</a
607
+ >
608
+ </li>
609
+ </ul>
610
+
611
+ <div class="tab-content mt-4">
612
+ <div class="tab-pane active" id="add-account-imap" role="tabpanel" aria-labelledby="add-account-imap-imap">
613
+ <fieldset id="addAccountIMAPSection">
614
+ <div class="form-group row">
615
+ <label for="addAccountIMAPUser" class="col-sm-2 col-form-label">Username</label>
616
+ <div class="col-sm-10">
617
+ <input type="text" class="form-control" id="addAccountIMAPUser" required />
618
+ </div>
619
+ </div>
620
+
621
+ <div class="form-group row">
622
+ <label for="addAccountIMAPPass" class="col-sm-2 col-form-label">Password</label>
623
+ <div class="col-sm-10">
624
+ <input type="password" class="form-control" id="addAccountIMAPPass" required />
625
+ </div>
626
+ </div>
627
+
628
+ <div class="form-group row">
629
+ <label for="addAccountIMAPHost" class="col-sm-2 col-form-label">Hostname</label>
630
+ <div class="col-sm-10">
631
+ <input type="text" class="form-control" id="addAccountIMAPHost" required />
632
+ </div>
633
+ </div>
634
+
635
+ <div class="form-group row">
636
+ <label for="addAccountIMAPPort" class="col-sm-2 col-form-label">Port</label>
637
+ <div class="col-sm-2">
638
+ <input type="number" class="form-control text-right" id="addAccountIMAPPort" required />
639
+ </div>
640
+ <div class="col-sm-2">
641
+ <div class="form-check">
642
+ <input class="form-check-input" type="checkbox" id="addAccountIMAPSecure" />
643
+ <label class="form-check-label" for="addAccountIMAPSecure"> Use TLS </label>
644
+ </div>
645
+ </div>
646
+ <div class="col-sm-4">
647
+ <div class="form-check">
648
+ <input class="form-check-input" type="checkbox" id="addAccountIMAPUnauthorized" />
649
+ <label class="form-check-label" for="addAccountIMAPUnauthorized">
650
+ Allow self signed certificates
651
+ </label>
652
+ </div>
653
+ </div>
654
+ </div>
655
+
656
+ <div class="form-group row">
657
+ <label for="addAccountIMAPResyncDelay" class="col-sm-2 col-form-label">Resync delay</label>
658
+ <div class="col-sm-2">
659
+ <input type="number" class="form-control text-right" id="addAccountIMAPResyncDelay" value="900" required />
660
+ </div>
661
+ </div>
662
+ </fieldset>
663
+ </div>
664
+
665
+ <div class="tab-pane" id="add-account-smtp" role="tabpanel" aria-labelledby="add-account-smtp-tab">
666
+ <div class="form-group form-check">
667
+ <input type="checkbox" class="form-check-input" id="addAccountSMTPEnable" />
668
+ <label class="form-check-label" for="addAccountSMTPEnable">Enable SMTP Account</label>
669
+ </div>
670
+
671
+ <fieldset id="addAccountSMTPSection" disabled>
672
+ <div class="form-group row">
673
+ <label for="addAccountSMTPUser" class="col-sm-2 col-form-label">Username</label>
674
+ <div class="col-sm-10">
675
+ <input type="text" class="form-control" id="addAccountSMTPUser" required />
676
+ </div>
677
+ </div>
678
+
679
+ <div class="form-group row">
680
+ <label for="addAccountSMTPPass" class="col-sm-2 col-form-label">Password</label>
681
+ <div class="col-sm-10">
682
+ <input type="password" class="form-control" id="addAccountSMTPPass" required />
683
+ </div>
684
+ </div>
685
+
686
+ <div class="form-group row">
687
+ <label for="addAccountSMTPHost" class="col-sm-2 col-form-label">Hostname</label>
688
+ <div class="col-sm-10">
689
+ <input type="text" class="form-control" id="addAccountSMTPHost" required />
690
+ </div>
691
+ </div>
692
+
693
+ <div class="form-group row">
694
+ <label for="addAccountSMTPPort" class="col-sm-2 col-form-label">Port</label>
695
+ <div class="col-sm-2">
696
+ <input type="number" class="form-control text-right" id="addAccountSMTPPort" required />
697
+ </div>
698
+ <div class="col-sm-2">
699
+ <div class="form-check">
700
+ <input class="form-check-input" type="checkbox" id="addAccountSMTPSecure" />
701
+ <label class="form-check-label" for="addAccountSMTPSecure"> Use TLS </label>
702
+ </div>
703
+ </div>
704
+ <div class="col-sm-4">
705
+ <div class="form-check">
706
+ <input class="form-check-input" type="checkbox" id="addAccountSMTPUnauthorized" />
707
+ <label class="form-check-label" for="addAccountSMTPUnauthorized">
708
+ Allow self signed certificates
709
+ </label>
710
+ </div>
711
+ </div>
712
+ </div>
713
+ </fieldset>
714
+ </div>
715
+
716
+ <div class="tab-pane" id="add-account-oauth2" role="tabpanel" aria-labelledby="add-account-oauth2-tab">
717
+ <div class="form-group form-check">
718
+ <input type="checkbox" class="form-check-input" id="AddAccountOAuth2Enable" />
719
+ <label class="form-check-label" for="AddAccountOAuth2Enable">Set up an OAuth2 account for both IMAP and SMTP</label>
720
+ </div>
721
+ <fieldset id="addAccountOAuth2Section" disabled>
722
+ <!--
723
+ <div class="form-group row">
724
+ <label for="addAccountOAuth2User" class="col-sm-2 col-form-label">Username</label>
725
+ <div class="col-sm-10">
726
+ <input type="text" class="form-control" id="addAccountOAuth2User" required />
727
+ </div>
728
+ </div>
729
+ -->
730
+ </fieldset>
731
+ <p><strong>NB!</strong> Currently only Gmail/G-Suite OAuth2 accounts are supported.</p>
732
+ </div>
733
+ </div>
734
+ </div>
735
+
736
+ <div class="modal-footer">
737
+ <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
738
+ <button type="submit" class="btn btn-primary">Add account</button>
739
+ </div>
740
+ </div>
741
+ </div>
742
+ </form>
743
+ </div>
744
+ </div>
745
+
746
+ <script src="/static/js/jquery-3.4.1.slim.min.js"></script>
747
+ <script src="/static/js/popper.min.js"></script>
748
+ <script src="/static/bootstrap-4.6.0-dist/js/bootstrap.min.js"></script>
749
+ <script src="/static/js/moment-with-locales-2.24.0.min.js"></script>
750
+ <script src="/static/js/emailengine.js"></script>
751
+ </body>
752
+ </html>