@bkazemi/verily 0.1.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 (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +503 -0
  3. package/dist/browser/badge.d.ts +39 -0
  4. package/dist/browser/badge.js +440 -0
  5. package/dist/browser/connect-dialog.d.ts +83 -0
  6. package/dist/browser/connect-dialog.js +514 -0
  7. package/dist/browser/evidence-dialog.d.ts +59 -0
  8. package/dist/browser/evidence-dialog.js +541 -0
  9. package/dist/browser/index.d.ts +59 -0
  10. package/dist/browser/index.js +809 -0
  11. package/dist/browser/logo.d.ts +2 -0
  12. package/dist/browser/logo.js +17 -0
  13. package/dist/browser/mark.d.ts +19 -0
  14. package/dist/browser/mark.js +77 -0
  15. package/dist/browser/provider-mark.d.ts +6 -0
  16. package/dist/browser/provider-mark.js +99 -0
  17. package/dist/browser/signed.d.ts +40 -0
  18. package/dist/browser/signed.js +219 -0
  19. package/dist/browser.d.ts +3 -0
  20. package/dist/browser.js +3 -0
  21. package/dist/core/index.d.ts +454 -0
  22. package/dist/core/index.js +128 -0
  23. package/dist/core/signed.d.ts +49 -0
  24. package/dist/core/signed.js +113 -0
  25. package/dist/index.d.ts +5 -0
  26. package/dist/index.js +5 -0
  27. package/dist/logo.d.ts +21 -0
  28. package/dist/logo.js +38 -0
  29. package/dist/postgres/index.d.ts +12 -0
  30. package/dist/postgres/index.js +76 -0
  31. package/dist/server/addresses.d.ts +2 -0
  32. package/dist/server/addresses.js +61 -0
  33. package/dist/server/body.d.ts +11 -0
  34. package/dist/server/body.js +49 -0
  35. package/dist/server/copy.d.ts +8 -0
  36. package/dist/server/copy.js +42 -0
  37. package/dist/server/discord.d.ts +7 -0
  38. package/dist/server/discord.js +69 -0
  39. package/dist/server/email-logo.d.ts +11 -0
  40. package/dist/server/email-logo.js +122 -0
  41. package/dist/server/email.d.ts +46 -0
  42. package/dist/server/email.js +145 -0
  43. package/dist/server/escape.d.ts +2 -0
  44. package/dist/server/escape.js +2 -0
  45. package/dist/server/github-gist.d.ts +11 -0
  46. package/dist/server/github-gist.js +68 -0
  47. package/dist/server/github.d.ts +7 -0
  48. package/dist/server/github.js +65 -0
  49. package/dist/server/index.d.ts +70 -0
  50. package/dist/server/index.js +862 -0
  51. package/dist/server/link.d.ts +64 -0
  52. package/dist/server/link.js +458 -0
  53. package/dist/server/openpgp.d.ts +49 -0
  54. package/dist/server/openpgp.js +158 -0
  55. package/dist/server/pgp.d.ts +29 -0
  56. package/dist/server/pgp.js +198 -0
  57. package/dist/server/public-fetch.d.ts +23 -0
  58. package/dist/server/public-fetch.js +62 -0
  59. package/dist/server/resend.d.ts +13 -0
  60. package/dist/server/resend.js +37 -0
  61. package/dist/server/service.d.ts +311 -0
  62. package/dist/server/service.js +1178 -0
  63. package/dist/server/signing.d.ts +16 -0
  64. package/dist/server/signing.js +56 -0
  65. package/dist/server/style.d.ts +17 -0
  66. package/dist/server/style.js +244 -0
  67. package/dist/server/wkd.d.ts +7 -0
  68. package/dist/server/wkd.js +65 -0
  69. package/dist/server/youtube.d.ts +11 -0
  70. package/dist/server/youtube.js +99 -0
  71. package/dist/site/index.d.ts +139 -0
  72. package/dist/site/index.js +239 -0
  73. package/dist/verily.js +11907 -0
  74. package/dist/version.d.ts +10 -0
  75. package/dist/version.js +10 -0
  76. package/docs/licenses/gpl-3.0.txt +232 -0
  77. package/docs/licenses/octicons.txt +21 -0
  78. package/docs/licenses/openpgp.txt +172 -0
  79. package/docs/licenses/rubik.txt +93 -0
  80. package/docs/licenses/simple-icons.txt +8 -0
  81. package/package.json +86 -0
@@ -0,0 +1,122 @@
1
+ /**
2
+ * The Verily logotype on its plate, as a PNG, for mail. A message cannot draw the logotype
3
+ * the way a page does: the clients most people read mail in strip an inline SVG. So it
4
+ * travels inside the message as an image of its own, which is shown without anything
5
+ * being fetched.
6
+ *
7
+ * This is docs/design/verily-logo-plate.svg drawn at 281 by 120, three times the 94 by 40
8
+ * it is shown at, with the plate's corners left transparent. Regenerate it from that file
9
+ * if the logotype changes.
10
+ */
11
+ export const emailLogo = 'iVBORw0KGgoAAAANSUhEUgAAARkAAAB4CAYAAADGz4ZcAAAABmJLR0QA/wD/AP+gvaeTAAAchUlEQVR4nO2dd3wU' +
12
+ 'VdfHf7Obzab3DklIoQQISJEnVHnoIKhUUVqAUEREsePr86qoqA+W10YnoYMgKEWUkpBIr+mNkFACKZtKyiab7O68' +
13
+ 'f2CUkGTmZndmS7jfz4fPR2ZO7jnrkjN37mkMCLF19gyVAOMBDAQQAsAdgD3pz1MoFLNFA6AMDG4DSGJYNtqCUR8u' +
14
+ 'LS2tIPlhhk/A0cVjlFbLfAwG/fS1lEKhtBlqGLBRGhlWVisUhVyCLToZezefzqxa8z3DYKTw9lEolDZCFcuyq6vK' +
15
+ 'FasAqJsTaNbJOLp4jNKyzE8AnMS0jkKhtBXYP9l6yZSqqoKiR+80cTL2Lp4LwWINAKlBbKNQKG0DBllqSIfXlObl' +
16
+ 'Nr78EH/tYH4DYGFQ4ygUSpuAARKsLTGosLCwuuGapOE/7N18OmtZZi+og6FQKDrCAk/U1CHq4Wt/vxJZWdrsAYOu' +
17
+ 'hjeLQqG0MbrJrezi62qrM4G/djIOLh6jWQYjjGsXhUJpMzDsf/HXW5EUACzldrvAoJ1RjaJQKG0Ixs3KyjZbVVud' +
18
+ 'KLFz9uxOE+0oFIrQsAwzFwAkDDDB2MZQKJQ2yWBHRz9nCR7UIlEoFIrQSFlJXZgEQBdjW0KhUNomLKMNkQDwMrYh' +
19
+ 'FAqljcLCUwLAxth2UCiUtgkD2ElA0O6BQqFQdEPCSPiFhMVGIoW3XG5otXoRbE03exSKrhisTslWKsVEd3fM9PTB' +
20
+ 'dWU1lmVlGkq1XrSTyxEV0hU5NTXYoyjEsdISaFnW2GY91ixcMA8r3n4Trq4uTe5ptVqkpKZhydLXkJScotP6Hu7u' +
21
+ '6Ny5Iyyk//x6qDVqZGZmQVHUpJMBhQfG3tlT1N8YZ5kMk9zcMd3TC7bSf7pHLMpIR3J1lZiqBWFFhw6Y4Or+999z' +
22
+ 'amuws6AAx0tLoKHOxuD4+fki8eoFSKXcnUgSk5IxeGjr+61NGD8OkRvXQS63bHJPparD3IhFOPLb761e93GFAbNW' +
23
+ 'tNclL0tLLPf1w4HQHpjv066RgwGAmV7eYqkWDA+ZDGOc3RpdC7Syxn86BGBft1BM8/SE3PBvnI81QYGBvA4GALqG' +
24
+ '6JaZsfzVpc06GACQyy2xZPFCndZ9nBH8dclZJsPSdu0xysUVUqblM+VBTk4IsrZGdk2N0CYIxgwvb8gkzX8GL7kc' +
25
+ 'r7X3wwxPL2zNz8eBIoWBrXs8kUjInDrD8W+PC2cn7maQTk6OOq37OCP4Y1ipVqOfoyOngwEehLRmm/BuxsnCAhPc' +
26
+ '3Hnl3GWWaG9lXgfZFIohEdzJqFgW+wo5m5f/zXBnF/haWQltgiBM9/SCFcFTs07LYncB2eelUB5HRDlQ2F+kQJWm' +
27
+ '2cbljZUzDF70NL2EY1upFJPc+XcxAHC0tAhF9XUiW0ShmC+iOJlqjQY/K8jOKJ52dYOnZfMHbcZimocn7KT8x1Va' +
28
+ 'lsVuwl0bRRiUSiWRXHV1Nb8QxSCIFhr5SVGIGq2GV86CYTDdw3R2M3K5DLYDgqGS8h8cniwrRW5trQGsojQQH5+A' +
29
+ 'zOtZvHJbt+80gDUUEkRLxruvVuNQUTGe9/TklX3O3R3bCvNRVl8vljnEhA7tho19nLG3uxbP5VRjclY17Ou1TeRY' +
30
+ 'ANsK8g1v4GNOrUqFYSPHYfzTY+Hl6dHkvlqtQUpKKk7F/WkE6yjNIWrG7+7CfEx094BlC2HgBuQSCaa6e2BD3j0x' +
31
+ 'zeHFwkKK/L4PupDel0uwNcQe+4LtMOa2Ei9mVsG19p+d2enyMuSYcPi9LVNZWYnde/Ya2wwKIaJmkinq6/F7aTGR' +
32
+ '7FTCcxAx6Tk4BMW2jW1QyhgcCLbFC2M98FVvRyisHySC7SgoMIaJFIrZIXq66vaCfKL0+9ZEdMRAIpWgKMy/xfv1' +
33
+ 'EgZHAmwxc4wnvvGVIMUMSiIoFFNAdCeTp1IhpqyUSPYFwtwUMQgN64RCe/6dVL0ESMqiZzEUCikG+Y3ekp9PVLns' +
34
+ 'SJhlKzQMA1QOCCCSDSiuRWbqHZEtolDaDgZxMjdra3D2/n0iWa56IbHo1rcj7jmT5epIY/nDpxQK5R8M9m6yNT+P' +
35
+ 'SK65ymexUQ8KJJJrX6ZCWnyOyNZQKG0Lg4Vz0pTVuFJRgb4ODryys729cbS02CD9WrqE+uOmO1n9lN2ZHIhtkpVc' +
36
+ 'ji4hndG+XTvY2dnB3s4WjESC6upqVFVWo7ikGJnXs1BcXCKuIRSKQBg0ZrytMJ/IybSTyzHMyRknCA+M9UH6705E' +
37
+ 'ch6V9Ui+dENw/RYWFhg4IAwTnh6HoUOHICgwgKhfSkFhIZKSUnD092M4/NtRFBWRpQroilQqxbSpk9G5U8dGbRRq' +
38
+ 'ampw4mQMrl6L513D17c9OgYHw9/PF05OjrC2tob8oVasSqUSfxw/gcTEZN61evYMxZhRI2Fj07g1alFRMfbs3WcS' +
39
+ 'TjgoKBATn50Ae3v7RterqqpwIjoGCQlJRrFr5IhheLJvn0b/7wEgJ+cmdv+0F3V1wibFit4Z71HWde6CHnb2vHI3' +
40
+ 'apSYk5YKMY0L6uSDu+FPEsl2O3YD1+JSBdNtZ2eHiHlzsPTlxfDQM3Sv0WgQcyoOn33xJa5cvSaQhY359pvVmDtn' +
41
+ 'VrP3tFotJk+bgeiYU03u9erVE3NmzcDI4cPg69ueV49arcawUeM4fwGfeKIHYo4fhYVF88/InJybCBs4FLUqFa++' +
42
+ 'R4m/fA5BQS2/PqekpmHA4GG867i4OCP+8nk4Ozffn6a+vh4jx0zAtfiEVtuoDy++MA3rfvyuxfu7du/F4peXCaZP' +
43
+ '1M54LbGjkCyJLdjaBgN5Ggjpi90wsu5prko1ks+nC6KTYRjMnTMLqYlXsPLD/+jtYIAHu4yRI4Yh5sRR7N29Hf7+' +
44
+ 'fgJY2pgpk55r8Z5EIsH0aZMbXQvt3g1HDu5HXPQxzAufTeRggAc7u7GjR3HKjB09qkUHAwCBgQEI6WrcmYUdg4Nb' +
45
+ 'dDAAIJPJsOyVJQa0CLC2ssKqjz/ilOnVq6fgeg3uZM6Wl+M6YSXtHC8f0ezw9/dApi//jgoAvC7mor6uaf1Sa/Hx' +
46
+ '9sav+/fg229Wc/4D1Icxo0fibNxJTqegC7a2tsT3Fy2cj9joPzBksG4TkK14egw9us1vDmsj9ylKSExEVRV3wuaE' +
47
+ 'p8fC28twxcFTp0yCi4szp8zpM+cE12twJ8MC2ElYWNjN1pboDEcXXEZ2BUsQKXes1SA1Vv9dTEiXzog+cRT/HvqU' +
48
+ '3mvx4eDggMhN6/DRB++LrutR3n/vHaz+/FPIZDKD6zYlVKo6HDz0G6eMTCZD+JyZBrLogfPn4+f9vwiu1yjptdHl' +
49
+ 'ZchVkbVImCVCi05vb2dkBpA5L7+reVDpWR3eq1dPHDt6CO18DNtudPmrS/HJyv81mL45s2bg7TeXG0yfqbN+02Ze' +
50
+ 'mfA5Mw3ikAcN7I/Q7t04ZeLjE3Hh4iXBdRulIlHLstiRX4AVHTrwyj5p74BQWztBx6f4jOyGUoJG07b1WqTH6nfY' +
51
+ '287HGz/t2taqBtTJKam4Fp+A7Owc3L9fAa1WCwcHB/j7++GJnqHo07sXUQQKAJYtXQKFohjf/bBG149AhJ+fLz5f' +
52
+ 'tVKQterq2kanwYSEJFy6fAX9nuzbooy3lxfGjxuDXw4eFtUWkl3M2g2bRNFttLLn30uLMdfHB14EXfFmennhnWxh' +
53
+ 'wsdubvbI7ORKJBuUUIjL1a2PUDQgl1tiz85t8CLoqVNXV4+NmyOxKXIrsrO5E/68vbww48Xn8eorS+DoyO+8PvjP' +
54
+ 'Cpy/cBGXr1wltr219AjtLsg6Wq0WJ6ObRqnMlfUbIzmdDAAsiJgnqpNp374dnh47hlOmUKHAgV9+FUW/0ZyMmmWx' +
55
+ 'u7AAy335IyGDnJwFG5/SYWQokgleEq3ULLJidJtA2MDyV19Bz56hvHIJCUmYu2Axr3NpIL+gAF9+/S0it2zDd998' +
56
+ 'iWcmPM0pL5PJELlxLfr1H4IaI3XyKykpxaXLV1BUXIzS0jKwzWQ1KpVKnDgZY/CwrpgcPHQYqz75EJ4eTRtsNTBo' +
57
+ 'YH90DemCtPQMUWxYMH8uZzQOACKjtgmeH9OAURu4HCpSYLa3N1wtuN9JG8anfHBTv5R+JwcbZIWQlSx0SlXg8n2y' +
58
+ 'KFhzBAcF4fXl/PkGhw7/hoiFS3TK6SgtLcOs8Ai8+/YbWPHOm5yy/v5+WLwoAt98+0Or9eiKWq3Gvp8PYM36jUhO' +
59
+ 'ToVWq3+Eztyoq6tH1JbtePftNzjlIuaH4/U33xVcv7WVFebMmsEpo1LVYXPkVsF1N2DU8YeGHp/SaWQoai34z2Jk' +
60
+ 'WhY5J9P00vU/770NK55Q66nYOMxbsFgnB9MAy7L47Isv8dU3LSdYNfD6a6+IFjp/lJycmxj01AgsWrIMiYnJj6WD' +
61
+ 'aSBqy3bU8wQPpk+b0iQzWAhIwtb7D/wq6oxvo89YNdT4FFtbOW704D8bAYAuGaUoKanQWVdAQAc898x4TplChQIR' +
62
+ 'i14WbIv6yaov8Ofps5wyjo6OmBc+WxB9XFyLT8DQEWNE2/6bG/kFBTh05CinjJ2dHV6YPlVw3WQHvhsF1/swRncy' +
63
+ 'hhqf0m14KKpl/LsYCQvkxei3i3n5pUW80Z+PPl4laL2RRqPBq6+/xfvEnPnidJ1HuJJQVFSMGbPmorycrLXH48KG' +
64
+ 'jZG8MhHzwgX9bkjC1ufOXyCqFdMHozsZQPzxKXK5DDd7keWodM0uR16e7oWZUqkUE5+dwCmTk3MTu/fs01lHS2Rn' +
65
+ '52Dbjl2cMkFBgegf1k9w3Q28/8FK3MujnQMf5fyFi0hK5g4kdOncCYMHDRBMJ8kuZt16ccLWD2MSTqZhfAoJz7m7' +
66
+ 'w0nWuvPq0KHdUCHn/6gMCyii9dvFDBwQBnd37sPlrdt3QqPhd6q6QHKAN27saFF03759B/t+PiDK2m0Bkt3Mgoi5' +
67
+ 'gugiCVvn5t7FkaN/CKKPC5NwMsCD8Sl1Wv6a63vOlvhXf/LiNwuZBHlPkhXndb5Tidzb+h2AjR3DXdwHAPt/OaiX' +
68
+ 'Di5SUtOQnpHJKTNk0CBRdP9y8DDUav7ztceVfT8fQGlpGafM02PHCJIZThK23rg5yiDfl8k4Gb7xKVlOMnwY5oyI' +
69
+ '4R64NCIAtrZkkaaeg7qixIYsO7bypP41Sn379Oa8f+vWbdy5k6u3Hi5OnYrjvB8a2o0oia+18B08P+7U1NZi+87d' +
70
+ 'nDIWFhYIb6GlBikkYeuamhps2bZDLz2kmIyTAZofn5LsZon3Brhi4XB3xLWzBssASgsJQoZ15V3vwZgTsrYHnfKq' +
71
+ 'kZOt31mCTCZDjx7cyXcJSeIesgFAfCJ3MySpVIoeodwHgrqQni5MO4y2zMbNUbyvyuFzZsLSUvd6JpKw9a49ew12' +
72
+ 'OG9STqZhfArLAOe8rfDyv92x7Ck3nPdumm9yu48PrKy4v4gHY07Ivqy6U9yvGCQEBwXythi4cSNbbz18kOgIDCCb' +
73
+ 'ztAa+F4FKMCdO7k4dvwkp4ynhweeGc+dxc0F34Evy7JYv4G/eFMoTMrJAEBUsQIRwz3wPwNckObSsoOosJSi+5CW' +
74
+ 'dzOtGnNSVIvMVP1fYby9+d+li0vEbwtZVMx/iB4YKKyTqaurN1rJgrmxniScPT9cp7VJwtanYuOQkXldp/V1weSc' +
75
+ 'zK3KKliWk6Xz5/Xzhcyy+Y/QqjEnccKMOfH25k/2U1brXqpACl+zJADEnepI0bKPb0Zva4mN+xPXs7gLfgf0D0P3' +
76
+ 'bvxHAo9ClHxngLD1wxh3+HQLVEZnAvP4e++W2EgROqArrsU2zT9QDyJ7Ugs55oSrCK6BN19/VfSsW4mU/9lhb2cn' +
77
+ 'qg2UlmFZFhs2ReLLL1ZxykXMD8drr79NvC5J2PpGdjZOnIwhXlMITNLJ5NzIQ/c8JbJ8bHhli/r7QXo6vdFh2oMx' +
78
+ 'J9ZEuoQcc/Jo5/zm8PPzhZ+frzAK9YDEVop47Nq9Fx+8v4KzXumF56fiw5WfEh/QkoSt123YbPA6MpN7XWpAHUd2' +
79
+ 'EKuwlyG0X3Cja6RjTjwr1YKOOSHpPWsq2PH07KWIS1VVFW/Wt7W1NaY/T1bPRBK2rqiowK7de4ltFAqTdTIZyXcQ' +
80
+ 'oCDrH1M5OBANJR9BnXxww4vsKe127ha0GuG8ulzHuipjILUgyx2iiMeGTZHN9tV5mAXz5xLVM5GErXfs3EN0Xic0' +
81
+ 'JutkAMDiDFm4966TJbr2DgIA2A4PIfoZIcecNKAmqCY3FWhmrvG5nnUDsXF/csp0DA7C0CGDedfiO/DVarVYv4k/' +
82
+ 'qiUGJu1kUq9mw6+ErNeKekgw/P09cL092YGmUGNOHkalMp/etOfOXzC2CRSQhbP56pkGDgjjDVv/cewEbt681RrT' +
83
+ 'BMMkD34bYFnA5txNYAJ/rdItdyv4TO9j0DEnj6IiaD51LT4Bt0UuK+BCXV+PhMRkbDTSU43SmGPHT+L27TucA/nG' +
84
+ 'jhmF9u3b4e7de83eX7woglfP2vXi9ozhwqSdDAAkX8qC71NBKHDgz9zNcyQ7E/G7mocreo45aY6y8nJemagt27F1' +
85
+ '+07BdVPME41Gg02RW/DxRy2PrpFKpZgXPhsrP/msyT2SsHVqWjri/jyjt626YtKvSwCg1WjheuGOYOsJMeakJUoI' +
86
+ 'hry7urqIoptivmzdvhM1PE3yw2fPhFze9CFKErZeu854uxjADJwMACSdSYe7Upj+K0HxBajWY8wJF3n5/AWWPj7i' +
87
+ 'jd6lmCfl5fexj2dyo5ubK559pnEzNJKwdUlJqdF7/JiFk1GrNfC6pP85hpWaRdYpcXYxAHhTxQGgezey6Bfl8YKk' +
88
+ 'YHHB/PBGf582dTJv2Dpq63aj15SZhZMBgORTKXCq1W830ylVgXI9xpzwUVxcwtu394mePZrd9lIeb5JTUnH+wkVO' +
89
+ 'mX/1e7JRK5GFC+ZxytfX12Nz5BYhzNMLs3EyqnoNfOPzdP55IcackHDp8hXO+zY2NhgQFia6HRTzg6g95/xwAGRh' +
90
+ '60NHjppEv2WzcTIAkB6dBtt63QqN9B1zQsq589xPIwCYMmWi6HZQzI9DR44iv6CAU2balElwcnLEooUEYWsjH/g2' +
91
+ 'YFZOplpZi8BE7i+hOSQscE/PBuGk/HHsOK/M5InPwslJ+PaXFPOmvv7BtEkurK2t8e5bb2D8OO6w9dVr8by7akNh' +
92
+ 'Vk4GAK6fSIG1unWZul2zy5Gfr/uYk9aQdSMbySnch8s2NjZYtnSJKPqt5HJ8tfpzXL5wGknXLjb6c+3yWaz5/v9o' +
93
+ 'BbYJE7VlO+/AvyUvLeQPWxu4ZwwXZudkKiqVCE4jH4omxJiT1sI3+wgAXn5pIYKDggTX/cN3X2PB/HB07tQRHTr4' +
94
+ 'N/oTHBSEmTOmY9bMFwTXSxGGQoUCBw8d1muNgsJC/HrwkEAW6Y/ZORkAuHUyBTKC8SkA0OW2/mNOWsvOXT+hooL7' +
95
+ '/Mfa2hqbNvzIOy+7NbyxfBmmTZ3MK1dbQ9tkmjIk9UxcbI7cKtj4YyEwSydTXFyJzplkTasrog3fQb+qqgrffr+G' +
96
+ 'V653ryewJXIDZDLdO9M38MbyZfjgP+/xyqnVakTHnNJbH0U8Ll2+goQE7okTLVGrUiFyyzaBLdIPs3QyAHDvRAqk' +
97
+ 'PL04hBhzois//LgOubl3eeXGjR2NA/t2w9nZSSc9Tk6O2LF1M5GDAYCorTtw957uqQAUw7B+k27TBPbv/1XQGetC' +
98
+ 'YLZOpqCgDF1yuNsSCjHmRFdqamvx8rLlRK0OnxoyCBfPxWHqlEmQSMi+ErncEkteWoj4y+fxzASy8Rn5BQVY9fl/' +
99
+ 'iWQpxmX//l9RUtL6YIUxq61bwmydDAAojqe1+AECioUZc6IPsXGniV6bAMDL0xObN6xBwpXzWPHOmxg8aABcXV3A' +
100
+ 'MAwkEgnc3d0Q0qUzxo0djdWff4rUpKv4/NOVxAWXSqUSz784W6d/uBTDU6tStbpa/8zZ80hKbtpU39iYfKsHLu7m' +
101
+ 'FqHn7Qpk+Ds0uSeNFWbMib589PEqBAZ2wLMTxhPJd+jgjxXvvNnoGsuyRC0YW6JWpcLciMU6v+dTjMPmqK149ZUl' +
102
+ 'kErJWqWu22A6YeuHMeudDPDX+JRHEHLMib5otVrMX/ASfj10ROc19HEwZWXlmDj5efz+B3+SIMW0yM29i6O/HyOW' +
103
+ '/e3oHyJbpBtm72RybuShY151o2t2p4UbcyIEdXX1mBexGBs2RRlUb1JyCoaNGoez52irTXNlA2EHw/UbI3lnbBsL' +
104
+ 's3cyAKCO+2fkpmelGsmXhRtzIhRqtRpvvr0Cc+YuEP30X6lU4tPP/othI8ciO9s0dnSGxpQeMvqgUPDneCmVSmzb' +
105
+ 'YbrdFtuEk3l4fIrruZuCjjkRml8OHkbvfgPx49r1UCqFbTuhKCrCl19/i159B+CL1V8LmpB169ZtzvuGdGa3b3N3' +
106
+ 'StRqtcjN1e3Q/9Zt7s9JkpYgJBHzuZuIA8CuPXuJB8AZA6nc2u5DYxshBF5qgPF3wa2fLkCrMe3HmEqlQnRMLDZH' +
107
+ 'bUVJSSmcnZzg5eWp09mLSlWH02fO4ONPv8Cy195AzKk4UWbrpKVnYED/MDg5Nc7nYVkWGZnXsXTZ60SdAYUgPSMD' +
108
+ 'HTsGIzAgABaPzI8qL7+Pjz75DNExsTqtnZycirCwfnB3d2v0fbAsi7T0DLzx1gqD5aHY29tj/ZrvYMkxz4tlWSx6' +
109
+ '6RWUlJpm1JABc4Wxd/Y07d9IQhgG6NzdHxnJ3E8iU8XH2xv/6tcXffr0QmBAAPz8fOFgbw8HBwdIJBJUK5VQKpUo' +
110
+ 'LFTg3r17SEvPQEJiMi5euiz4johiGixcMI93XnZ0zClMnGK6tWgMmLVtxslQKG0JhmFw+cJpdOoYzCk3aeqLOBkd' +
111
+ 'YyCrWg8DZm2bOJOhUNoaQ58awutgsrNzEHMq1jAG6QF1MhSKCbKQZ2okAKxZt4GobMXYUCdDoZgY7du3w5jRIzll' +
112
+ '7t+/j1179hnIIv2gToZCMTEi5oXzlhJs27EL1dXVnDKmAnUyFIoJIZdbYtYM7miRRqPBxs1bDGOQAFAnQ6GYEJMn' +
113
+ 'PQd3dzdOmaO/H+NNjjQlqJOhUEyIhRHcA9sA0+wZwwV1MhSKidC3T2/07vUEp0xaeobZFbxSJ0OhmAgkYesf1qwD' +
114
+ 'a2bVnzTjl0IxAVxdXZCeEs85vaK4uARdQ3ujVqUyoGX6QTN+KRQTYe6cWbzjcSK3bDMrB9MAdTIUipGRSqUInz2T' +
115
+ 'U+bBCFvTGnVCCnUyFIqRGT1qBPz8fDllDh46gnt5xhnvoy/UyVAoRmb0qBG8MmvWmVfY+mGok6FQjAxft72YU7G4' +
116
+ 'cvWagawRHrMeiUKhtAW+/3Et7Ozs0KtXz0bXWa0W16/fwOervzKSZcJAQ9gUCkU0GkLY1MlQKBSR0LISALRBLIVC' +
117
+ 'EQUWqJIAKDC2IRQKpW3CMEyBBEC6sQ2hUChtFJbJkAA4a2w7KBRKm0QjYWvPS1iGOWxsSygUSpvkz/Ly8nJJVWlB' +
118
+ 'KoCLxraGQqG0LRiWjQL+yvhlWeZd45pDoVDaGBkV5YrdwF9Opqq8IJYFjhvXJgqF0oZ4C4AaeKh2SaLRLgVQbiyL' +
119
+ 'KBRK24AB9lSWFR5p+PvfTqaioihLwrDT8Jf3oVAolNbCgom3tkTEw9caTZBS1VTnyG3s8gGMA63QplAorYFlrmsk' +
120
+ '0rHlxfklD19u4kgqSws3SRh2HIAygxlHoVDMGhY4LmEtw2pK7zXpW9HsLExVTXWOlaXNAUgkHQEEi24hhUIxVyoB' +
121
+ 'rKwqK1yiUt1vtg6S4VvB1tFzuESCTwCECW0dhUIxT9gHhdWRqGdWVlUVFHHJ8jqZBuxcvUMYLTseYAcDCAHgAcBB' +
122
+ 'P1MpFIoZoAZQDhY3ASSyDKKtLbRHioqKqkh++P8BysulpNQJzTwAAAAASUVORK5CYII=';
@@ -0,0 +1,46 @@
1
+ import { type CodeProvider } from '../core/index.js';
2
+ /**
3
+ * One message for whatever sends this deployment's mail, written twice: as HTML, and as
4
+ * the plain text a reader without it is shown. Send both, as alternatives of one message.
5
+ */
6
+ export interface EmailMessage {
7
+ to: string;
8
+ subject: string;
9
+ text: string;
10
+ html: string;
11
+ /**
12
+ * Images the HTML shows, which travel inside the message and are attached inline under
13
+ * the id the HTML names each by, as `cid:<contentId>`. A sender that leaves them out
14
+ * still sends a whole message: the image's place reads "Verily" instead.
15
+ */
16
+ images: EmailImage[];
17
+ }
18
+ export interface EmailImage {
19
+ contentId: string;
20
+ filename: string;
21
+ contentType: string;
22
+ /** The image's bytes, in base 64. */
23
+ content: string;
24
+ }
25
+ export interface EmailProviderOptions {
26
+ /** Shown as "Verify with …". */
27
+ name?: string;
28
+ /**
29
+ * Hands one message to whatever sends this deployment's mail: an API, a relay, a queue.
30
+ * Rejecting fails the flow. Nothing here retries, since a second message would carry a
31
+ * code the holder was never shown a place to enter.
32
+ */
33
+ send(message: EmailMessage): Promise<void>;
34
+ }
35
+ /**
36
+ * Proves control of a mailbox by sending a code to it and having the holder read it back.
37
+ * No registration with anybody and nothing published: the proof is that the code arrived,
38
+ * so it says somebody could read that mailbox when the link was made, and nothing later.
39
+ * A domain can hand an address to somebody else, which is why the link expires and is
40
+ * renewed like any other.
41
+ *
42
+ * This sends mail to an address a visitor types, so the message carries the code, the
43
+ * site's name and nothing a visitor chose. How often it may be asked to send is the
44
+ * deployment's to limit, like every other request here.
45
+ */
46
+ export declare function emailProvider(options: EmailProviderOptions): CodeProvider;
@@ -0,0 +1,145 @@
1
+ import { Refused } from '../core/index.js';
2
+ import { emailLogo } from './email-logo.js';
3
+ import { escape } from './escape.js';
4
+ /** The logotype as the message carries it. */
5
+ const logo = {
6
+ contentId: 'verily-logo',
7
+ filename: 'verily.png',
8
+ contentType: 'image/png',
9
+ content: emailLogo,
10
+ };
11
+ /** Atoms and single dots, as an address is written without quoting. */
12
+ const local = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*$/;
13
+ const domain = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/;
14
+ /**
15
+ * Proves control of a mailbox by sending a code to it and having the holder read it back.
16
+ * No registration with anybody and nothing published: the proof is that the code arrived,
17
+ * so it says somebody could read that mailbox when the link was made, and nothing later.
18
+ * A domain can hand an address to somebody else, which is why the link expires and is
19
+ * renewed like any other.
20
+ *
21
+ * This sends mail to an address a visitor types, so the message carries the code, the
22
+ * site's name and nothing a visitor chose. How often it may be asked to send is the
23
+ * deployment's to limit, like every other request here.
24
+ */
25
+ export function emailProvider(options) {
26
+ return {
27
+ id: 'email',
28
+ name: options.name ?? 'Email',
29
+ method: 'code',
30
+ field: 'Your email address',
31
+ input: 'email',
32
+ account,
33
+ async deliver({ account, link, code, siteName, expiresAt }) {
34
+ // The name lands in a header, where a line break would start another one.
35
+ const site = siteName.replace(/\s+/g, ' ').trim();
36
+ const words = {
37
+ ask: `Press the button to show ${site} that this address is yours.`,
38
+ button: 'Confirm this address',
39
+ enter: 'Or enter this code on the page that asked for it:',
40
+ lasts: `Both work until ${new Date(expiresAt).toISOString().slice(11, 16)} UTC.`,
41
+ ignore: 'If you did not ask for this, ignore this message. Nothing is linked unless you confirm.',
42
+ };
43
+ await options.send({
44
+ to: account.id,
45
+ subject: `Confirm your address for ${site}`,
46
+ text: [
47
+ `Open this link to show ${site} that this address is yours:`,
48
+ link,
49
+ words.enter,
50
+ code,
51
+ words.lasts,
52
+ words.ignore,
53
+ ].join('\n\n'),
54
+ html: letter({ link, code, ...words }),
55
+ images: [logo],
56
+ });
57
+ },
58
+ };
59
+ }
60
+ /**
61
+ * The message as HTML, in the colours of the pages this library serves. Mail clients are
62
+ * not browsers: the layout is a table and every style is on its element, because that is
63
+ * what all of them keep, and the style block only adds a dark scheme where one is honoured.
64
+ * Nothing is fetched, so there is nothing to block and nothing to tell anyone the message
65
+ * was opened: the logotype is an image the message carries with it, on the plate it sits
66
+ * on everywhere else, and where a client will not show it the word stands in its place.
67
+ *
68
+ * Everything sits on the column's middle, said twice over, as an attribute and as a style,
69
+ * since clients differ on which they honour. The code's cell is padded three pixels more
70
+ * on the left: letter spacing follows every character, the last included, and would
71
+ * otherwise push the code that far off centre.
72
+ */
73
+ function letter(parts) {
74
+ const sans = "system-ui,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif";
75
+ const mono = "ui-monospace,SFMono-Regular,Menlo,Consolas,'Liberation Mono',monospace";
76
+ return `<!doctype html>
77
+ <html lang="en">
78
+ <head>
79
+ <meta charset="utf-8">
80
+ <meta name="viewport" content="width=device-width,initial-scale=1">
81
+ <meta name="color-scheme" content="light dark">
82
+ <meta name="supported-color-schemes" content="light dark">
83
+ <title>Verily</title>
84
+ <style>
85
+ @media (prefers-color-scheme: dark) {
86
+ .page { background: #161a18 !important; }
87
+ .ink { color: #dde5e0 !important; }
88
+ .muted { color: #96a39b !important; }
89
+ .button { background: #7fc4a2 !important; }
90
+ .button a { color: #10231a !important; }
91
+ .code { background: #1d2220 !important; border-color: #2f3b35 !important; color: #dde5e0 !important; }
92
+ .rule { border-color: #2f3b35 !important; }
93
+ }
94
+ </style>
95
+ </head>
96
+ <body class="page" style="margin:0;padding:0;background:#ffffff;">
97
+ <div style="display:none;max-height:0;overflow:hidden;opacity:0;">${escape(parts.ask)} ${escape(parts.lasts)}</div>
98
+ <table role="presentation" class="page" width="100%" cellpadding="0" cellspacing="0" border="0" style="background:#ffffff;">
99
+ <tr><td align="center" style="padding:40px 16px 48px;">
100
+ <table role="presentation" align="center" width="100%" cellpadding="0" cellspacing="0" border="0" style="max-width:440px;margin:0 auto;">
101
+ <tr><td align="center" style="padding:0 0 28px;">
102
+ <img src="cid:${logo.contentId}" width="94" height="40" alt="Verily" style="display:block;margin:0 auto;border:0;outline:none;font:700 20px/40px ${sans};color:#23312b;">
103
+ </td></tr>
104
+ <tr><td class="ink" align="center" style="padding:0 0 10px;font:650 22px/1.3 ${sans};color:#23312b;text-align:center;">Confirm your address</td></tr>
105
+ <tr><td class="ink" align="center" style="padding:0 0 24px;font:16px/1.6 ${sans};color:#23312b;text-align:center;">${escape(parts.ask)}</td></tr>
106
+ <tr><td align="center" style="padding:0 0 28px;">
107
+ <table role="presentation" align="center" cellpadding="0" cellspacing="0" border="0" style="margin:0 auto;"><tr><td class="button" align="center" style="background:#245f43;border-radius:10px;"><a href="${escape(parts.link)}" style="display:inline-block;padding:13px 26px;font:600 16px/1.2 ${sans};color:#ffffff;text-decoration:none;">${escape(parts.button)}</a></td></tr></table>
108
+ </td></tr>
109
+ <tr><td class="muted" align="center" style="padding:0 0 10px;font:14px/1.5 ${sans};color:#6b786f;text-align:center;">${escape(parts.enter)}</td></tr>
110
+ <tr><td class="code" align="center" style="padding:14px 12px 14px 15px;background:#f7f9f7;border:1px solid #dce2de;border-radius:10px;font:600 22px/1.2 ${mono};letter-spacing:.14em;color:#23312b;text-align:center;">${escape(parts.code)}</td></tr>
111
+ <tr><td class="muted" align="center" style="padding:12px 0 28px;font:14px/1.5 ${sans};color:#6b786f;text-align:center;">${escape(parts.lasts)}</td></tr>
112
+ <tr><td class="rule" style="border-top:1px solid #dce2de;font-size:0;line-height:0;">&nbsp;</td></tr>
113
+ <tr><td class="muted" align="center" style="padding:18px 0 0;font:13px/1.6 ${sans};color:#6b786f;text-align:center;">${escape(parts.ignore)}</td></tr>
114
+ </table>
115
+ </td></tr>
116
+ </table>
117
+ </body>
118
+ </html>`;
119
+ }
120
+ /**
121
+ * The mailbox an address names. Lowercased throughout: the part before the @ may be case
122
+ * sensitive by the letter of the standard and is not in any mailbox a person holds, and
123
+ * two spellings of one address must not be two records. Nothing else is folded, because
124
+ * whether a dot or a plus suffix names the same mailbox is each domain's own rule.
125
+ */
126
+ function account(address) {
127
+ const text = address.trim().toLowerCase();
128
+ const at = text.lastIndexOf('@');
129
+ const name = text.slice(0, at);
130
+ const host = text.slice(at + 1);
131
+ if (at < 1 ||
132
+ text.length > 254 ||
133
+ name.length > 64 ||
134
+ !local.test(name) ||
135
+ !domain.test(host) ||
136
+ // An address literal, or a name nobody could have registered.
137
+ /^[\d.]+$/.test(host))
138
+ throw new Refused('Not an email address this can send to');
139
+ return {
140
+ id: text,
141
+ kind: 'mailbox',
142
+ handle: text,
143
+ profileUrl: `mailto:${encodeURIComponent(name)}@${host}`,
144
+ };
145
+ }
@@ -0,0 +1,2 @@
1
+ /** Text as it is written into HTML, in an element or a quoted attribute, and read as text. */
2
+ export declare const escape: (value: unknown) => string;
@@ -0,0 +1,2 @@
1
+ /** Text as it is written into HTML, in an element or a quoted attribute, and read as text. */
2
+ export const escape = (value) => String(value).replace(/[&<>"']/g, (char) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' })[char]);
@@ -0,0 +1,11 @@
1
+ import { type ArtifactProvider } from '../core/index.js';
2
+ /**
3
+ * Proves control of a GitHub account by having its holder publish a given line in a public
4
+ * gist. No app registration, no client secret, and no token: the proof is a public document
5
+ * anyone can fetch, so a reader can repeat this check without trusting the backend that ran
6
+ * it. The unauthenticated API allows sixty requests an hour per address, which bounds how
7
+ * often connections using this method can be rechecked.
8
+ */
9
+ export declare function githubGistProvider(options?: {
10
+ fetch?: typeof fetch;
11
+ }): ArtifactProvider;
@@ -0,0 +1,68 @@
1
+ import { Refused } from '../core/index.js';
2
+ /**
3
+ * Proves control of a GitHub account by having its holder publish a given line in a public
4
+ * gist. No app registration, no client secret, and no token: the proof is a public document
5
+ * anyone can fetch, so a reader can repeat this check without trusting the backend that ran
6
+ * it. The unauthenticated API allows sixty requests an hour per address, which bounds how
7
+ * often connections using this method can be rechecked.
8
+ */
9
+ export function githubGistProvider(options = {}) {
10
+ const request = options.fetch ?? fetch;
11
+ return {
12
+ id: 'github',
13
+ name: 'GitHub',
14
+ method: 'gist',
15
+ artifact: 'location',
16
+ instructions: (expect) => [
17
+ [
18
+ 'Publish this line in a public gist at ',
19
+ { text: 'gist.github.com', href: 'https://gist.github.com/' },
20
+ ', then paste the gist address below.',
21
+ ],
22
+ { code: expect },
23
+ ],
24
+ async verify({ artifact, expect }) {
25
+ const url = URL.parse(artifact);
26
+ // The holder chooses this url, so nothing outside gist.github.com is ever fetched.
27
+ if (!url || url.protocol !== 'https:' || url.host !== 'gist.github.com')
28
+ throw new Refused('Not a gist address');
29
+ const id = url.pathname.split('/').filter(Boolean).at(-1) ?? '';
30
+ if (!/^[0-9a-f]{20,32}$/.test(id))
31
+ throw new Refused('Not a gist address');
32
+ const response = await request(`https://api.github.com/gists/${id}`, {
33
+ headers: { Accept: 'application/vnd.github+json', 'User-Agent': 'Verily-V0' },
34
+ signal: AbortSignal.timeout(15000),
35
+ });
36
+ const gist = await response.json();
37
+ if (!response.ok || !isRecord(gist))
38
+ throw new Refused('Gist unavailable');
39
+ // A secret gist proves nothing a reader could check for themselves.
40
+ if (gist.public !== true)
41
+ throw new Refused('Gist is not public');
42
+ const owner = gist.owner;
43
+ if (!isRecord(owner) ||
44
+ !Number.isSafeInteger(owner.id) ||
45
+ Number(owner.id) <= 0 ||
46
+ typeof owner.login !== 'string' ||
47
+ !/^[a-zA-Z0-9-]+$/.test(owner.login))
48
+ throw new Refused('Invalid gist owner');
49
+ if (!isRecord(gist.files) || !contains(gist.files, expect))
50
+ throw new Refused('Gist does not contain the expected line');
51
+ return {
52
+ id: String(owner.id),
53
+ handle: owner.login,
54
+ profileUrl: `https://github.com/${owner.login}`,
55
+ };
56
+ },
57
+ };
58
+ }
59
+ /** A truncated file is not proof: the part that would have matched may be the part omitted. */
60
+ function contains(files, expect) {
61
+ return Object.values(files).some((file) => isRecord(file) &&
62
+ file.truncated !== true &&
63
+ typeof file.content === 'string' &&
64
+ file.content.includes(expect));
65
+ }
66
+ function isRecord(value) {
67
+ return value !== null && typeof value === 'object';
68
+ }
@@ -0,0 +1,7 @@
1
+ import type { RedirectProvider } from '../core/index.js';
2
+ /** GitHub.com OAuth app, PKCE S256, no additional scopes. Tokens are never persisted. */
3
+ export declare function githubProvider(options: {
4
+ clientId: string;
5
+ clientSecret: string;
6
+ fetch?: typeof fetch;
7
+ }): RedirectProvider;
@@ -0,0 +1,65 @@
1
+ /** GitHub.com OAuth app, PKCE S256, no additional scopes. Tokens are never persisted. */
2
+ export function githubProvider(options) {
3
+ if (!options.clientId || !options.clientSecret)
4
+ throw new Error('GitHub credentials required');
5
+ const request = options.fetch ?? fetch;
6
+ return {
7
+ id: 'github',
8
+ name: 'GitHub',
9
+ method: 'oauth',
10
+ authorizationUrl({ state, challenge, redirectUri }) {
11
+ const url = new URL('https://github.com/login/oauth/authorize');
12
+ url.search = new URLSearchParams({
13
+ client_id: options.clientId,
14
+ redirect_uri: redirectUri,
15
+ state,
16
+ code_challenge: challenge,
17
+ code_challenge_method: 'S256',
18
+ scope: '',
19
+ prompt: 'select_account',
20
+ }).toString();
21
+ return url.href;
22
+ },
23
+ async authenticate({ code, verifier, redirectUri }) {
24
+ const response = await request('https://github.com/login/oauth/access_token', {
25
+ method: 'POST',
26
+ headers: { Accept: 'application/json' },
27
+ signal: AbortSignal.timeout(15000),
28
+ body: new URLSearchParams({
29
+ client_id: options.clientId,
30
+ client_secret: options.clientSecret,
31
+ code,
32
+ code_verifier: verifier,
33
+ redirect_uri: redirectUri,
34
+ }),
35
+ });
36
+ const token = await response.json();
37
+ if (!response.ok || !isRecord(token) || typeof token.access_token !== 'string' || token.error)
38
+ throw new Error('Provider authentication failed');
39
+ const identity = await request('https://api.github.com/user', {
40
+ headers: {
41
+ Authorization: `Bearer ${token.access_token}`,
42
+ Accept: 'application/vnd.github+json',
43
+ 'User-Agent': 'Verily-V0',
44
+ },
45
+ signal: AbortSignal.timeout(15000),
46
+ });
47
+ const user = await identity.json();
48
+ if (!identity.ok ||
49
+ !isRecord(user) ||
50
+ !Number.isSafeInteger(user.id) ||
51
+ Number(user.id) <= 0 ||
52
+ typeof user.login !== 'string' ||
53
+ !/^[a-zA-Z0-9-]+$/.test(user.login))
54
+ throw new Error('Invalid provider identity');
55
+ return {
56
+ id: String(user.id),
57
+ handle: user.login,
58
+ profileUrl: `https://github.com/${user.login}`,
59
+ };
60
+ },
61
+ };
62
+ }
63
+ function isRecord(value) {
64
+ return typeof value === 'object' && value !== null;
65
+ }
@@ -0,0 +1,70 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import { type FlowResult, type LocalAccount, type Visibility } from '../core/index.js';
3
+ import { VerilyService, type ServiceOptions } from './service.js';
4
+ export { VerilyService, Unavailable } from './service.js';
5
+ export { githubProvider } from './github.js';
6
+ export { discordProvider } from './discord.js';
7
+ export { youtubeProvider } from './youtube.js';
8
+ export { githubGistProvider } from './github-gist.js';
9
+ export { linkProvider, githubLinkProvider, type LinkProviderOptions } from './link.js';
10
+ export { pgpProvider } from './pgp.js';
11
+ export { generateSigningKey, signer } from './signing.js';
12
+ export { emailProvider, type EmailImage, type EmailMessage, type EmailProviderOptions, } from './email.js';
13
+ export { resendSender } from './resend.js';
14
+ export type { ServiceOptions } from './service.js';
15
+ export interface ServerOptions extends ServiceOptions {
16
+ /** Resolve identity exclusively from the adopting application's authenticated session. */
17
+ authenticate(request: Request): Promise<LocalAccount | undefined>;
18
+ reportUrl: string;
19
+ /**
20
+ * What to store on a flow when it is created, read from the request that creates it, and
21
+ * handed back to `finish`. Never called for removal from the external side, whatever the
22
+ * browser is signed into, since nothing local answers for that.
23
+ */
24
+ context?(request: Request): Promise<Record<string, string> | undefined>;
25
+ /**
26
+ * Where to send the holder once a flow has ended, each time its result page is served. It
27
+ * must depend on nothing but what it is given, so a page loaded again after a failure or
28
+ * a lost response sends the holder to the same place. Undefined shows the result page.
29
+ */
30
+ finish?(ended: Ended): Promise<string | undefined>;
31
+ /**
32
+ * Origins a form here may end up at, beyond this one and the sign-in providers': anywhere
33
+ * `finish` sends a holder, since an approval form's redirect is held to `form-action`.
34
+ */
35
+ formTargets?: string[];
36
+ /**
37
+ * The provider ids a subject may use, where not every subject gets every one: an
38
+ * instance serving several sites offers each site's subjects what that site chose.
39
+ * Undefined means all of them. Removal from the external side is never narrowed.
40
+ */
41
+ providersFor?(local: LocalAccount): string[] | undefined;
42
+ /**
43
+ * The visibilities a subject may choose, where a site does not offer both. Undefined
44
+ * means both. With one, the approval page states it and offers no choice, and there is
45
+ * nothing for a visibility flow to change. A record made before the choice was narrowed
46
+ * keeps the visibility it has.
47
+ */
48
+ visibilityFor?(local: LocalAccount): Visibility[] | undefined;
49
+ }
50
+ /** A flow that has ended, as `finish` is given it: all of it read from the stored flow. */
51
+ export interface Ended {
52
+ /** The flow's id, which names it and is no secret. */
53
+ id: string;
54
+ context?: Record<string, string>;
55
+ local?: LocalAccount;
56
+ result: FlowResult;
57
+ }
58
+ export declare function createVerily(options: ServerOptions): {
59
+ service: VerilyService;
60
+ handle: (request: Request) => Promise<Response>;
61
+ /**
62
+ * The flow binding, for a host that carries it some way other than this handler's own
63
+ * cookie: the cookie's name, to read a binding from a request or a response, and the
64
+ * header that sets it in a browser.
65
+ */
66
+ flowCookieName: string;
67
+ flowCookie: (binding: string) => string;
68
+ };
69
+ /** Mount on your chosen Node router. Public origin is configured, never inferred from Host. */
70
+ export declare function nodeHandler(handler: (request: Request) => Promise<Response>, origin: string): (req: IncomingMessage, res: ServerResponse) => Promise<void>;