@budibase/worker 2.3.17 → 2.3.18-alpha.1

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 (167) hide show
  1. package/__mocks__/node-fetch.ts +23 -0
  2. package/jest-testcontainers-config.js +8 -0
  3. package/jest.config.ts +13 -17
  4. package/package.json +11 -8
  5. package/scripts/dev/manage.js +1 -0
  6. package/src/api/controllers/global/auth.ts +77 -70
  7. package/src/api/controllers/global/self.ts +28 -44
  8. package/src/api/controllers/global/users.ts +65 -25
  9. package/src/api/controllers/system/accounts.ts +7 -5
  10. package/src/api/controllers/system/tenants.ts +4 -8
  11. package/src/api/index.ts +4 -20
  12. package/src/api/routes/global/auth.ts +10 -7
  13. package/src/api/routes/global/tests/auth.spec.ts +226 -17
  14. package/src/api/routes/global/tests/configs.spec.ts +5 -5
  15. package/src/api/routes/global/tests/roles.spec.ts +20 -14
  16. package/src/api/routes/global/tests/self.spec.ts +3 -4
  17. package/src/api/routes/global/tests/users.spec.ts +24 -27
  18. package/src/api/routes/system/tenants.ts +1 -1
  19. package/src/api/routes/system/tests/accounts.spec.ts +4 -4
  20. package/src/api/routes/system/tests/migrations.spec.ts +2 -2
  21. package/src/api/routes/system/tests/restore.spec.ts +2 -2
  22. package/src/api/routes/system/tests/status.spec.ts +5 -5
  23. package/src/ddApm.ts +7 -0
  24. package/src/elasticApm.ts +10 -0
  25. package/src/environment.ts +15 -1
  26. package/src/index.ts +12 -7
  27. package/src/middleware/tests/tenancy.spec.ts +4 -4
  28. package/src/migrations/functions/globalInfoSyncUsers.ts +4 -3
  29. package/src/sdk/accounts/index.ts +2 -1
  30. package/src/sdk/accounts/{accounts.ts → metadata.ts} +0 -1
  31. package/src/sdk/auth/auth.ts +86 -0
  32. package/src/sdk/auth/index.ts +1 -0
  33. package/src/sdk/tenants/index.ts +1 -0
  34. package/src/sdk/tenants/tenants.ts +76 -0
  35. package/src/sdk/users/events.ts +4 -0
  36. package/src/sdk/users/index.ts +1 -0
  37. package/src/sdk/users/tests/users.spec.ts +52 -0
  38. package/src/sdk/users/users.ts +53 -46
  39. package/src/tests/TestConfiguration.ts +41 -62
  40. package/src/tests/api/auth.ts +42 -14
  41. package/src/tests/api/base.ts +2 -1
  42. package/src/tests/api/configs.ts +2 -2
  43. package/src/tests/api/restore.ts +1 -0
  44. package/src/tests/api/users.ts +2 -2
  45. package/src/tests/jestEnv.ts +2 -1
  46. package/src/tests/jestSetup.ts +10 -6
  47. package/src/tests/logging.ts +34 -0
  48. package/src/tests/structures/index.ts +0 -4
  49. package/src/utilities/email.ts +3 -3
  50. package/src/utilities/redis.ts +2 -0
  51. package/coverage/clover.xml +0 -2199
  52. package/coverage/coverage-final.json +0 -84
  53. package/coverage/lcov-report/base.css +0 -224
  54. package/coverage/lcov-report/block-navigation.js +0 -87
  55. package/coverage/lcov-report/favicon.png +0 -0
  56. package/coverage/lcov-report/index.html +0 -431
  57. package/coverage/lcov-report/prettify.css +0 -1
  58. package/coverage/lcov-report/prettify.js +0 -2
  59. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  60. package/coverage/lcov-report/sorter.js +0 -196
  61. package/coverage/lcov-report/src/api/controllers/global/auth.ts.html +0 -934
  62. package/coverage/lcov-report/src/api/controllers/global/configs.ts.html +0 -1348
  63. package/coverage/lcov-report/src/api/controllers/global/email.ts.html +0 -196
  64. package/coverage/lcov-report/src/api/controllers/global/events.ts.html +0 -136
  65. package/coverage/lcov-report/src/api/controllers/global/index.html +0 -251
  66. package/coverage/lcov-report/src/api/controllers/global/license.ts.html +0 -187
  67. package/coverage/lcov-report/src/api/controllers/global/roles.ts.html +0 -283
  68. package/coverage/lcov-report/src/api/controllers/global/self.ts.html +0 -577
  69. package/coverage/lcov-report/src/api/controllers/global/templates.ts.html +0 -316
  70. package/coverage/lcov-report/src/api/controllers/global/users.ts.html +0 -838
  71. package/coverage/lcov-report/src/api/controllers/global/workspaces.ts.html +0 -244
  72. package/coverage/lcov-report/src/api/controllers/system/accounts.ts.html +0 -148
  73. package/coverage/lcov-report/src/api/controllers/system/environment.ts.html +0 -124
  74. package/coverage/lcov-report/src/api/controllers/system/index.html +0 -191
  75. package/coverage/lcov-report/src/api/controllers/system/migrations.ts.html +0 -124
  76. package/coverage/lcov-report/src/api/controllers/system/restore.ts.html +0 -124
  77. package/coverage/lcov-report/src/api/controllers/system/status.ts.html +0 -133
  78. package/coverage/lcov-report/src/api/controllers/system/tenants.ts.html +0 -154
  79. package/coverage/lcov-report/src/api/index.html +0 -116
  80. package/coverage/lcov-report/src/api/index.ts.html +0 -595
  81. package/coverage/lcov-report/src/api/routes/global/auth.ts.html +0 -349
  82. package/coverage/lcov-report/src/api/routes/global/configs.ts.html +0 -457
  83. package/coverage/lcov-report/src/api/routes/global/email.ts.html +0 -193
  84. package/coverage/lcov-report/src/api/routes/global/events.ts.html +0 -109
  85. package/coverage/lcov-report/src/api/routes/global/index.html +0 -251
  86. package/coverage/lcov-report/src/api/routes/global/license.ts.html +0 -124
  87. package/coverage/lcov-report/src/api/routes/global/roles.ts.html +0 -133
  88. package/coverage/lcov-report/src/api/routes/global/self.ts.html +0 -139
  89. package/coverage/lcov-report/src/api/routes/global/templates.ts.html +0 -196
  90. package/coverage/lcov-report/src/api/routes/global/users.ts.html +0 -475
  91. package/coverage/lcov-report/src/api/routes/global/workspaces.ts.html +0 -196
  92. package/coverage/lcov-report/src/api/routes/index.html +0 -116
  93. package/coverage/lcov-report/src/api/routes/index.ts.html +0 -202
  94. package/coverage/lcov-report/src/api/routes/system/accounts.ts.html +0 -142
  95. package/coverage/lcov-report/src/api/routes/system/environment.ts.html +0 -109
  96. package/coverage/lcov-report/src/api/routes/system/index.html +0 -191
  97. package/coverage/lcov-report/src/api/routes/system/migrations.ts.html +0 -142
  98. package/coverage/lcov-report/src/api/routes/system/restore.ts.html +0 -109
  99. package/coverage/lcov-report/src/api/routes/system/status.ts.html +0 -109
  100. package/coverage/lcov-report/src/api/routes/system/tenants.ts.html +0 -124
  101. package/coverage/lcov-report/src/api/routes/validation/index.html +0 -131
  102. package/coverage/lcov-report/src/api/routes/validation/index.ts.html +0 -88
  103. package/coverage/lcov-report/src/api/routes/validation/users.ts.html +0 -235
  104. package/coverage/lcov-report/src/constants/index.html +0 -116
  105. package/coverage/lcov-report/src/constants/index.ts.html +0 -637
  106. package/coverage/lcov-report/src/constants/templates/index.html +0 -116
  107. package/coverage/lcov-report/src/constants/templates/index.ts.html +0 -316
  108. package/coverage/lcov-report/src/db/index.html +0 -116
  109. package/coverage/lcov-report/src/db/index.ts.html +0 -115
  110. package/coverage/lcov-report/src/environment.ts.html +0 -388
  111. package/coverage/lcov-report/src/index.html +0 -131
  112. package/coverage/lcov-report/src/index.ts.html +0 -394
  113. package/coverage/lcov-report/src/middleware/cloudRestricted.ts.html +0 -139
  114. package/coverage/lcov-report/src/middleware/index.html +0 -116
  115. package/coverage/lcov-report/src/migrations/functions/globalInfoSyncUsers.ts.html +0 -145
  116. package/coverage/lcov-report/src/migrations/functions/index.html +0 -116
  117. package/coverage/lcov-report/src/migrations/index.html +0 -116
  118. package/coverage/lcov-report/src/migrations/index.ts.html +0 -271
  119. package/coverage/lcov-report/src/sdk/accounts/accounts.ts.html +0 -262
  120. package/coverage/lcov-report/src/sdk/accounts/index.html +0 -131
  121. package/coverage/lcov-report/src/sdk/accounts/index.ts.html +0 -88
  122. package/coverage/lcov-report/src/sdk/index.html +0 -116
  123. package/coverage/lcov-report/src/sdk/index.ts.html +0 -106
  124. package/coverage/lcov-report/src/sdk/users/events.ts.html +0 -601
  125. package/coverage/lcov-report/src/sdk/users/index.html +0 -146
  126. package/coverage/lcov-report/src/sdk/users/index.ts.html +0 -88
  127. package/coverage/lcov-report/src/sdk/users/users.ts.html +0 -1999
  128. package/coverage/lcov-report/src/tests/TestConfiguration.ts.html +0 -1075
  129. package/coverage/lcov-report/src/tests/api/accounts.ts.html +0 -160
  130. package/coverage/lcov-report/src/tests/api/auth.ts.html +0 -220
  131. package/coverage/lcov-report/src/tests/api/base.ts.html +0 -133
  132. package/coverage/lcov-report/src/tests/api/configs.ts.html +0 -226
  133. package/coverage/lcov-report/src/tests/api/email.ts.html +0 -148
  134. package/coverage/lcov-report/src/tests/api/environment.ts.html +0 -130
  135. package/coverage/lcov-report/src/tests/api/groups.ts.html +0 -163
  136. package/coverage/lcov-report/src/tests/api/index.html +0 -356
  137. package/coverage/lcov-report/src/tests/api/index.ts.html +0 -238
  138. package/coverage/lcov-report/src/tests/api/license.ts.html +0 -136
  139. package/coverage/lcov-report/src/tests/api/migrations.ts.html +0 -151
  140. package/coverage/lcov-report/src/tests/api/restore.ts.html +0 -127
  141. package/coverage/lcov-report/src/tests/api/roles.ts.html +0 -181
  142. package/coverage/lcov-report/src/tests/api/self.ts.html +0 -163
  143. package/coverage/lcov-report/src/tests/api/status.ts.html +0 -121
  144. package/coverage/lcov-report/src/tests/api/templates.ts.html +0 -175
  145. package/coverage/lcov-report/src/tests/api/tenants.ts.html +0 -130
  146. package/coverage/lcov-report/src/tests/api/users.ts.html +0 -514
  147. package/coverage/lcov-report/src/tests/controllers.ts.html +0 -100
  148. package/coverage/lcov-report/src/tests/index.html +0 -146
  149. package/coverage/lcov-report/src/tests/index.ts.html +0 -103
  150. package/coverage/lcov-report/src/tests/mocks/email.ts.html +0 -115
  151. package/coverage/lcov-report/src/tests/mocks/index.html +0 -131
  152. package/coverage/lcov-report/src/tests/mocks/index.ts.html +0 -106
  153. package/coverage/lcov-report/src/tests/structures/configs.ts.html +0 -313
  154. package/coverage/lcov-report/src/tests/structures/groups.ts.html +0 -118
  155. package/coverage/lcov-report/src/tests/structures/index.html +0 -161
  156. package/coverage/lcov-report/src/tests/structures/index.ts.html +0 -151
  157. package/coverage/lcov-report/src/tests/structures/users.ts.html +0 -196
  158. package/coverage/lcov-report/src/utilities/appService.ts.html +0 -208
  159. package/coverage/lcov-report/src/utilities/email.ts.html +0 -850
  160. package/coverage/lcov-report/src/utilities/fileSystem.ts.html +0 -100
  161. package/coverage/lcov-report/src/utilities/index.html +0 -206
  162. package/coverage/lcov-report/src/utilities/index.ts.html +0 -112
  163. package/coverage/lcov-report/src/utilities/redis.ts.html +0 -424
  164. package/coverage/lcov-report/src/utilities/templates.ts.html +0 -232
  165. package/coverage/lcov-report/src/utilities/users.ts.html +0 -133
  166. package/coverage/lcov.info +0 -4187
  167. package/src/tests/structures/users.ts +0 -37
@@ -1,934 +0,0 @@
1
-
2
- <!doctype html>
3
- <html lang="en">
4
-
5
- <head>
6
- <title>Code coverage report for src/api/controllers/global/auth.ts</title>
7
- <meta charset="utf-8" />
8
- <link rel="stylesheet" href="../../../../prettify.css" />
9
- <link rel="stylesheet" href="../../../../base.css" />
10
- <link rel="shortcut icon" type="image/x-icon" href="../../../../favicon.png" />
11
- <meta name="viewport" content="width=device-width, initial-scale=1" />
12
- <style type='text/css'>
13
- .coverage-summary .sorter {
14
- background-image: url(../../../../sort-arrow-sprite.png);
15
- }
16
- </style>
17
- </head>
18
-
19
- <body>
20
- <div class='wrapper'>
21
- <div class='pad1'>
22
- <h1><a href="../../../../index.html">All files</a> / <a href="index.html">src/api/controllers/global</a> auth.ts</h1>
23
- <div class='clearfix'>
24
-
25
- <div class='fl pad1y space-right2'>
26
- <span class="strong">62.77% </span>
27
- <span class="quiet">Statements</span>
28
- <span class='fraction'>86/137</span>
29
- </div>
30
-
31
-
32
- <div class='fl pad1y space-right2'>
33
- <span class="strong">27.77% </span>
34
- <span class="quiet">Branches</span>
35
- <span class='fraction'>5/18</span>
36
- </div>
37
-
38
-
39
- <div class='fl pad1y space-right2'>
40
- <span class="strong">61.53% </span>
41
- <span class="quiet">Functions</span>
42
- <span class='fraction'>24/39</span>
43
- </div>
44
-
45
-
46
- <div class='fl pad1y space-right2'>
47
- <span class="strong">59.01% </span>
48
- <span class="quiet">Lines</span>
49
- <span class='fraction'>72/122</span>
50
- </div>
51
-
52
-
53
- </div>
54
- <p class="quiet">
55
- Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
- </p>
57
- <template id="filterTemplate">
58
- <div class="quiet">
59
- Filter:
60
- <input oninput="onInput()" type="search" id="fileSearch">
61
- </div>
62
- </template>
63
- </div>
64
- <div class='status-line medium'></div>
65
- <pre><table class="coverage">
66
- <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
- <a name='L2'></a><a href='#L2'>2</a>
68
- <a name='L3'></a><a href='#L3'>3</a>
69
- <a name='L4'></a><a href='#L4'>4</a>
70
- <a name='L5'></a><a href='#L5'>5</a>
71
- <a name='L6'></a><a href='#L6'>6</a>
72
- <a name='L7'></a><a href='#L7'>7</a>
73
- <a name='L8'></a><a href='#L8'>8</a>
74
- <a name='L9'></a><a href='#L9'>9</a>
75
- <a name='L10'></a><a href='#L10'>10</a>
76
- <a name='L11'></a><a href='#L11'>11</a>
77
- <a name='L12'></a><a href='#L12'>12</a>
78
- <a name='L13'></a><a href='#L13'>13</a>
79
- <a name='L14'></a><a href='#L14'>14</a>
80
- <a name='L15'></a><a href='#L15'>15</a>
81
- <a name='L16'></a><a href='#L16'>16</a>
82
- <a name='L17'></a><a href='#L17'>17</a>
83
- <a name='L18'></a><a href='#L18'>18</a>
84
- <a name='L19'></a><a href='#L19'>19</a>
85
- <a name='L20'></a><a href='#L20'>20</a>
86
- <a name='L21'></a><a href='#L21'>21</a>
87
- <a name='L22'></a><a href='#L22'>22</a>
88
- <a name='L23'></a><a href='#L23'>23</a>
89
- <a name='L24'></a><a href='#L24'>24</a>
90
- <a name='L25'></a><a href='#L25'>25</a>
91
- <a name='L26'></a><a href='#L26'>26</a>
92
- <a name='L27'></a><a href='#L27'>27</a>
93
- <a name='L28'></a><a href='#L28'>28</a>
94
- <a name='L29'></a><a href='#L29'>29</a>
95
- <a name='L30'></a><a href='#L30'>30</a>
96
- <a name='L31'></a><a href='#L31'>31</a>
97
- <a name='L32'></a><a href='#L32'>32</a>
98
- <a name='L33'></a><a href='#L33'>33</a>
99
- <a name='L34'></a><a href='#L34'>34</a>
100
- <a name='L35'></a><a href='#L35'>35</a>
101
- <a name='L36'></a><a href='#L36'>36</a>
102
- <a name='L37'></a><a href='#L37'>37</a>
103
- <a name='L38'></a><a href='#L38'>38</a>
104
- <a name='L39'></a><a href='#L39'>39</a>
105
- <a name='L40'></a><a href='#L40'>40</a>
106
- <a name='L41'></a><a href='#L41'>41</a>
107
- <a name='L42'></a><a href='#L42'>42</a>
108
- <a name='L43'></a><a href='#L43'>43</a>
109
- <a name='L44'></a><a href='#L44'>44</a>
110
- <a name='L45'></a><a href='#L45'>45</a>
111
- <a name='L46'></a><a href='#L46'>46</a>
112
- <a name='L47'></a><a href='#L47'>47</a>
113
- <a name='L48'></a><a href='#L48'>48</a>
114
- <a name='L49'></a><a href='#L49'>49</a>
115
- <a name='L50'></a><a href='#L50'>50</a>
116
- <a name='L51'></a><a href='#L51'>51</a>
117
- <a name='L52'></a><a href='#L52'>52</a>
118
- <a name='L53'></a><a href='#L53'>53</a>
119
- <a name='L54'></a><a href='#L54'>54</a>
120
- <a name='L55'></a><a href='#L55'>55</a>
121
- <a name='L56'></a><a href='#L56'>56</a>
122
- <a name='L57'></a><a href='#L57'>57</a>
123
- <a name='L58'></a><a href='#L58'>58</a>
124
- <a name='L59'></a><a href='#L59'>59</a>
125
- <a name='L60'></a><a href='#L60'>60</a>
126
- <a name='L61'></a><a href='#L61'>61</a>
127
- <a name='L62'></a><a href='#L62'>62</a>
128
- <a name='L63'></a><a href='#L63'>63</a>
129
- <a name='L64'></a><a href='#L64'>64</a>
130
- <a name='L65'></a><a href='#L65'>65</a>
131
- <a name='L66'></a><a href='#L66'>66</a>
132
- <a name='L67'></a><a href='#L67'>67</a>
133
- <a name='L68'></a><a href='#L68'>68</a>
134
- <a name='L69'></a><a href='#L69'>69</a>
135
- <a name='L70'></a><a href='#L70'>70</a>
136
- <a name='L71'></a><a href='#L71'>71</a>
137
- <a name='L72'></a><a href='#L72'>72</a>
138
- <a name='L73'></a><a href='#L73'>73</a>
139
- <a name='L74'></a><a href='#L74'>74</a>
140
- <a name='L75'></a><a href='#L75'>75</a>
141
- <a name='L76'></a><a href='#L76'>76</a>
142
- <a name='L77'></a><a href='#L77'>77</a>
143
- <a name='L78'></a><a href='#L78'>78</a>
144
- <a name='L79'></a><a href='#L79'>79</a>
145
- <a name='L80'></a><a href='#L80'>80</a>
146
- <a name='L81'></a><a href='#L81'>81</a>
147
- <a name='L82'></a><a href='#L82'>82</a>
148
- <a name='L83'></a><a href='#L83'>83</a>
149
- <a name='L84'></a><a href='#L84'>84</a>
150
- <a name='L85'></a><a href='#L85'>85</a>
151
- <a name='L86'></a><a href='#L86'>86</a>
152
- <a name='L87'></a><a href='#L87'>87</a>
153
- <a name='L88'></a><a href='#L88'>88</a>
154
- <a name='L89'></a><a href='#L89'>89</a>
155
- <a name='L90'></a><a href='#L90'>90</a>
156
- <a name='L91'></a><a href='#L91'>91</a>
157
- <a name='L92'></a><a href='#L92'>92</a>
158
- <a name='L93'></a><a href='#L93'>93</a>
159
- <a name='L94'></a><a href='#L94'>94</a>
160
- <a name='L95'></a><a href='#L95'>95</a>
161
- <a name='L96'></a><a href='#L96'>96</a>
162
- <a name='L97'></a><a href='#L97'>97</a>
163
- <a name='L98'></a><a href='#L98'>98</a>
164
- <a name='L99'></a><a href='#L99'>99</a>
165
- <a name='L100'></a><a href='#L100'>100</a>
166
- <a name='L101'></a><a href='#L101'>101</a>
167
- <a name='L102'></a><a href='#L102'>102</a>
168
- <a name='L103'></a><a href='#L103'>103</a>
169
- <a name='L104'></a><a href='#L104'>104</a>
170
- <a name='L105'></a><a href='#L105'>105</a>
171
- <a name='L106'></a><a href='#L106'>106</a>
172
- <a name='L107'></a><a href='#L107'>107</a>
173
- <a name='L108'></a><a href='#L108'>108</a>
174
- <a name='L109'></a><a href='#L109'>109</a>
175
- <a name='L110'></a><a href='#L110'>110</a>
176
- <a name='L111'></a><a href='#L111'>111</a>
177
- <a name='L112'></a><a href='#L112'>112</a>
178
- <a name='L113'></a><a href='#L113'>113</a>
179
- <a name='L114'></a><a href='#L114'>114</a>
180
- <a name='L115'></a><a href='#L115'>115</a>
181
- <a name='L116'></a><a href='#L116'>116</a>
182
- <a name='L117'></a><a href='#L117'>117</a>
183
- <a name='L118'></a><a href='#L118'>118</a>
184
- <a name='L119'></a><a href='#L119'>119</a>
185
- <a name='L120'></a><a href='#L120'>120</a>
186
- <a name='L121'></a><a href='#L121'>121</a>
187
- <a name='L122'></a><a href='#L122'>122</a>
188
- <a name='L123'></a><a href='#L123'>123</a>
189
- <a name='L124'></a><a href='#L124'>124</a>
190
- <a name='L125'></a><a href='#L125'>125</a>
191
- <a name='L126'></a><a href='#L126'>126</a>
192
- <a name='L127'></a><a href='#L127'>127</a>
193
- <a name='L128'></a><a href='#L128'>128</a>
194
- <a name='L129'></a><a href='#L129'>129</a>
195
- <a name='L130'></a><a href='#L130'>130</a>
196
- <a name='L131'></a><a href='#L131'>131</a>
197
- <a name='L132'></a><a href='#L132'>132</a>
198
- <a name='L133'></a><a href='#L133'>133</a>
199
- <a name='L134'></a><a href='#L134'>134</a>
200
- <a name='L135'></a><a href='#L135'>135</a>
201
- <a name='L136'></a><a href='#L136'>136</a>
202
- <a name='L137'></a><a href='#L137'>137</a>
203
- <a name='L138'></a><a href='#L138'>138</a>
204
- <a name='L139'></a><a href='#L139'>139</a>
205
- <a name='L140'></a><a href='#L140'>140</a>
206
- <a name='L141'></a><a href='#L141'>141</a>
207
- <a name='L142'></a><a href='#L142'>142</a>
208
- <a name='L143'></a><a href='#L143'>143</a>
209
- <a name='L144'></a><a href='#L144'>144</a>
210
- <a name='L145'></a><a href='#L145'>145</a>
211
- <a name='L146'></a><a href='#L146'>146</a>
212
- <a name='L147'></a><a href='#L147'>147</a>
213
- <a name='L148'></a><a href='#L148'>148</a>
214
- <a name='L149'></a><a href='#L149'>149</a>
215
- <a name='L150'></a><a href='#L150'>150</a>
216
- <a name='L151'></a><a href='#L151'>151</a>
217
- <a name='L152'></a><a href='#L152'>152</a>
218
- <a name='L153'></a><a href='#L153'>153</a>
219
- <a name='L154'></a><a href='#L154'>154</a>
220
- <a name='L155'></a><a href='#L155'>155</a>
221
- <a name='L156'></a><a href='#L156'>156</a>
222
- <a name='L157'></a><a href='#L157'>157</a>
223
- <a name='L158'></a><a href='#L158'>158</a>
224
- <a name='L159'></a><a href='#L159'>159</a>
225
- <a name='L160'></a><a href='#L160'>160</a>
226
- <a name='L161'></a><a href='#L161'>161</a>
227
- <a name='L162'></a><a href='#L162'>162</a>
228
- <a name='L163'></a><a href='#L163'>163</a>
229
- <a name='L164'></a><a href='#L164'>164</a>
230
- <a name='L165'></a><a href='#L165'>165</a>
231
- <a name='L166'></a><a href='#L166'>166</a>
232
- <a name='L167'></a><a href='#L167'>167</a>
233
- <a name='L168'></a><a href='#L168'>168</a>
234
- <a name='L169'></a><a href='#L169'>169</a>
235
- <a name='L170'></a><a href='#L170'>170</a>
236
- <a name='L171'></a><a href='#L171'>171</a>
237
- <a name='L172'></a><a href='#L172'>172</a>
238
- <a name='L173'></a><a href='#L173'>173</a>
239
- <a name='L174'></a><a href='#L174'>174</a>
240
- <a name='L175'></a><a href='#L175'>175</a>
241
- <a name='L176'></a><a href='#L176'>176</a>
242
- <a name='L177'></a><a href='#L177'>177</a>
243
- <a name='L178'></a><a href='#L178'>178</a>
244
- <a name='L179'></a><a href='#L179'>179</a>
245
- <a name='L180'></a><a href='#L180'>180</a>
246
- <a name='L181'></a><a href='#L181'>181</a>
247
- <a name='L182'></a><a href='#L182'>182</a>
248
- <a name='L183'></a><a href='#L183'>183</a>
249
- <a name='L184'></a><a href='#L184'>184</a>
250
- <a name='L185'></a><a href='#L185'>185</a>
251
- <a name='L186'></a><a href='#L186'>186</a>
252
- <a name='L187'></a><a href='#L187'>187</a>
253
- <a name='L188'></a><a href='#L188'>188</a>
254
- <a name='L189'></a><a href='#L189'>189</a>
255
- <a name='L190'></a><a href='#L190'>190</a>
256
- <a name='L191'></a><a href='#L191'>191</a>
257
- <a name='L192'></a><a href='#L192'>192</a>
258
- <a name='L193'></a><a href='#L193'>193</a>
259
- <a name='L194'></a><a href='#L194'>194</a>
260
- <a name='L195'></a><a href='#L195'>195</a>
261
- <a name='L196'></a><a href='#L196'>196</a>
262
- <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a>
264
- <a name='L199'></a><a href='#L199'>199</a>
265
- <a name='L200'></a><a href='#L200'>200</a>
266
- <a name='L201'></a><a href='#L201'>201</a>
267
- <a name='L202'></a><a href='#L202'>202</a>
268
- <a name='L203'></a><a href='#L203'>203</a>
269
- <a name='L204'></a><a href='#L204'>204</a>
270
- <a name='L205'></a><a href='#L205'>205</a>
271
- <a name='L206'></a><a href='#L206'>206</a>
272
- <a name='L207'></a><a href='#L207'>207</a>
273
- <a name='L208'></a><a href='#L208'>208</a>
274
- <a name='L209'></a><a href='#L209'>209</a>
275
- <a name='L210'></a><a href='#L210'>210</a>
276
- <a name='L211'></a><a href='#L211'>211</a>
277
- <a name='L212'></a><a href='#L212'>212</a>
278
- <a name='L213'></a><a href='#L213'>213</a>
279
- <a name='L214'></a><a href='#L214'>214</a>
280
- <a name='L215'></a><a href='#L215'>215</a>
281
- <a name='L216'></a><a href='#L216'>216</a>
282
- <a name='L217'></a><a href='#L217'>217</a>
283
- <a name='L218'></a><a href='#L218'>218</a>
284
- <a name='L219'></a><a href='#L219'>219</a>
285
- <a name='L220'></a><a href='#L220'>220</a>
286
- <a name='L221'></a><a href='#L221'>221</a>
287
- <a name='L222'></a><a href='#L222'>222</a>
288
- <a name='L223'></a><a href='#L223'>223</a>
289
- <a name='L224'></a><a href='#L224'>224</a>
290
- <a name='L225'></a><a href='#L225'>225</a>
291
- <a name='L226'></a><a href='#L226'>226</a>
292
- <a name='L227'></a><a href='#L227'>227</a>
293
- <a name='L228'></a><a href='#L228'>228</a>
294
- <a name='L229'></a><a href='#L229'>229</a>
295
- <a name='L230'></a><a href='#L230'>230</a>
296
- <a name='L231'></a><a href='#L231'>231</a>
297
- <a name='L232'></a><a href='#L232'>232</a>
298
- <a name='L233'></a><a href='#L233'>233</a>
299
- <a name='L234'></a><a href='#L234'>234</a>
300
- <a name='L235'></a><a href='#L235'>235</a>
301
- <a name='L236'></a><a href='#L236'>236</a>
302
- <a name='L237'></a><a href='#L237'>237</a>
303
- <a name='L238'></a><a href='#L238'>238</a>
304
- <a name='L239'></a><a href='#L239'>239</a>
305
- <a name='L240'></a><a href='#L240'>240</a>
306
- <a name='L241'></a><a href='#L241'>241</a>
307
- <a name='L242'></a><a href='#L242'>242</a>
308
- <a name='L243'></a><a href='#L243'>243</a>
309
- <a name='L244'></a><a href='#L244'>244</a>
310
- <a name='L245'></a><a href='#L245'>245</a>
311
- <a name='L246'></a><a href='#L246'>246</a>
312
- <a name='L247'></a><a href='#L247'>247</a>
313
- <a name='L248'></a><a href='#L248'>248</a>
314
- <a name='L249'></a><a href='#L249'>249</a>
315
- <a name='L250'></a><a href='#L250'>250</a>
316
- <a name='L251'></a><a href='#L251'>251</a>
317
- <a name='L252'></a><a href='#L252'>252</a>
318
- <a name='L253'></a><a href='#L253'>253</a>
319
- <a name='L254'></a><a href='#L254'>254</a>
320
- <a name='L255'></a><a href='#L255'>255</a>
321
- <a name='L256'></a><a href='#L256'>256</a>
322
- <a name='L257'></a><a href='#L257'>257</a>
323
- <a name='L258'></a><a href='#L258'>258</a>
324
- <a name='L259'></a><a href='#L259'>259</a>
325
- <a name='L260'></a><a href='#L260'>260</a>
326
- <a name='L261'></a><a href='#L261'>261</a>
327
- <a name='L262'></a><a href='#L262'>262</a>
328
- <a name='L263'></a><a href='#L263'>263</a>
329
- <a name='L264'></a><a href='#L264'>264</a>
330
- <a name='L265'></a><a href='#L265'>265</a>
331
- <a name='L266'></a><a href='#L266'>266</a>
332
- <a name='L267'></a><a href='#L267'>267</a>
333
- <a name='L268'></a><a href='#L268'>268</a>
334
- <a name='L269'></a><a href='#L269'>269</a>
335
- <a name='L270'></a><a href='#L270'>270</a>
336
- <a name='L271'></a><a href='#L271'>271</a>
337
- <a name='L272'></a><a href='#L272'>272</a>
338
- <a name='L273'></a><a href='#L273'>273</a>
339
- <a name='L274'></a><a href='#L274'>274</a>
340
- <a name='L275'></a><a href='#L275'>275</a>
341
- <a name='L276'></a><a href='#L276'>276</a>
342
- <a name='L277'></a><a href='#L277'>277</a>
343
- <a name='L278'></a><a href='#L278'>278</a>
344
- <a name='L279'></a><a href='#L279'>279</a>
345
- <a name='L280'></a><a href='#L280'>280</a>
346
- <a name='L281'></a><a href='#L281'>281</a>
347
- <a name='L282'></a><a href='#L282'>282</a>
348
- <a name='L283'></a><a href='#L283'>283</a>
349
- <a name='L284'></a><a href='#L284'>284</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
350
- <span class="cline-any cline-neutral">&nbsp;</span>
351
- <span class="cline-any cline-neutral">&nbsp;</span>
352
- <span class="cline-any cline-neutral">&nbsp;</span>
353
- <span class="cline-any cline-neutral">&nbsp;</span>
354
- <span class="cline-any cline-neutral">&nbsp;</span>
355
- <span class="cline-any cline-neutral">&nbsp;</span>
356
- <span class="cline-any cline-neutral">&nbsp;</span>
357
- <span class="cline-any cline-neutral">&nbsp;</span>
358
- <span class="cline-any cline-yes">18x</span>
359
- <span class="cline-any cline-yes">18x</span>
360
- <span class="cline-any cline-yes">18x</span>
361
- <span class="cline-any cline-yes">18x</span>
362
- <span class="cline-any cline-yes">18x</span>
363
- <span class="cline-any cline-yes">18x</span>
364
- <span class="cline-any cline-yes">18x</span>
365
- <span class="cline-any cline-neutral">&nbsp;</span>
366
- <span class="cline-any cline-yes">18x</span>
367
- <span class="cline-any cline-yes">18x</span>
368
- <span class="cline-any cline-yes">18x</span>
369
- <span class="cline-any cline-neutral">&nbsp;</span>
370
- <span class="cline-any cline-no">&nbsp;</span>
371
- <span class="cline-any cline-no">&nbsp;</span>
372
- <span class="cline-any cline-neutral">&nbsp;</span>
373
- <span class="cline-any cline-neutral">&nbsp;</span>
374
- <span class="cline-any cline-no">&nbsp;</span>
375
- <span class="cline-any cline-yes">3x</span>
376
- <span class="cline-any cline-neutral">&nbsp;</span>
377
- <span class="cline-any cline-neutral">&nbsp;</span>
378
- <span class="cline-any cline-neutral">&nbsp;</span>
379
- <span class="cline-any cline-yes">1x</span>
380
- <span class="cline-any cline-no">&nbsp;</span>
381
- <span class="cline-any cline-no">&nbsp;</span>
382
- <span class="cline-any cline-no">&nbsp;</span>
383
- <span class="cline-any cline-no">&nbsp;</span>
384
- <span class="cline-any cline-neutral">&nbsp;</span>
385
- <span class="cline-any cline-neutral">&nbsp;</span>
386
- <span class="cline-any cline-yes">1x</span>
387
- <span class="cline-any cline-no">&nbsp;</span>
388
- <span class="cline-any cline-no">&nbsp;</span>
389
- <span class="cline-any cline-neutral">&nbsp;</span>
390
- <span class="cline-any cline-neutral">&nbsp;</span>
391
- <span class="cline-any cline-neutral">&nbsp;</span>
392
- <span class="cline-any cline-yes">1x</span>
393
- <span class="cline-any cline-neutral">&nbsp;</span>
394
- <span class="cline-any cline-yes">1x</span>
395
- <span class="cline-any cline-neutral">&nbsp;</span>
396
- <span class="cline-any cline-neutral">&nbsp;</span>
397
- <span class="cline-any cline-yes">1x</span>
398
- <span class="cline-any cline-no">&nbsp;</span>
399
- <span class="cline-any cline-neutral">&nbsp;</span>
400
- <span class="cline-any cline-neutral">&nbsp;</span>
401
- <span class="cline-any cline-neutral">&nbsp;</span>
402
- <span class="cline-any cline-yes">18x</span>
403
- <span class="cline-any cline-no">&nbsp;</span>
404
- <span class="cline-any cline-neutral">&nbsp;</span>
405
- <span class="cline-any cline-neutral">&nbsp;</span>
406
- <span class="cline-any cline-no">&nbsp;</span>
407
- <span class="cline-any cline-no">&nbsp;</span>
408
- <span class="cline-any cline-no">&nbsp;</span>
409
- <span class="cline-any cline-neutral">&nbsp;</span>
410
- <span class="cline-any cline-no">&nbsp;</span>
411
- <span class="cline-any cline-neutral">&nbsp;</span>
412
- <span class="cline-any cline-neutral">&nbsp;</span>
413
- <span class="cline-any cline-neutral">&nbsp;</span>
414
- <span class="cline-any cline-neutral">&nbsp;</span>
415
- <span class="cline-any cline-yes">18x</span>
416
- <span class="cline-any cline-no">&nbsp;</span>
417
- <span class="cline-any cline-no">&nbsp;</span>
418
- <span class="cline-any cline-no">&nbsp;</span>
419
- <span class="cline-any cline-neutral">&nbsp;</span>
420
- <span class="cline-any cline-neutral">&nbsp;</span>
421
- <span class="cline-any cline-yes">18x</span>
422
- <span class="cline-any cline-no">&nbsp;</span>
423
- <span class="cline-any cline-no">&nbsp;</span>
424
- <span class="cline-any cline-neutral">&nbsp;</span>
425
- <span class="cline-any cline-no">&nbsp;</span>
426
- <span class="cline-any cline-no">&nbsp;</span>
427
- <span class="cline-any cline-neutral">&nbsp;</span>
428
- <span class="cline-any cline-neutral">&nbsp;</span>
429
- <span class="cline-any cline-neutral">&nbsp;</span>
430
- <span class="cline-any cline-neutral">&nbsp;</span>
431
- <span class="cline-any cline-neutral">&nbsp;</span>
432
- <span class="cline-any cline-neutral">&nbsp;</span>
433
- <span class="cline-any cline-yes">18x</span>
434
- <span class="cline-any cline-yes">2x</span>
435
- <span class="cline-any cline-yes">2x</span>
436
- <span class="cline-any cline-yes">2x</span>
437
- <span class="cline-any cline-no">&nbsp;</span>
438
- <span class="cline-any cline-neutral">&nbsp;</span>
439
- <span class="cline-any cline-neutral">&nbsp;</span>
440
- <span class="cline-any cline-neutral">&nbsp;</span>
441
- <span class="cline-any cline-neutral">&nbsp;</span>
442
- <span class="cline-any cline-yes">2x</span>
443
- <span class="cline-any cline-yes">2x</span>
444
- <span class="cline-any cline-neutral">&nbsp;</span>
445
- <span class="cline-any cline-yes">2x</span>
446
- <span class="cline-any cline-yes">2x</span>
447
- <span class="cline-any cline-neutral">&nbsp;</span>
448
- <span class="cline-any cline-neutral">&nbsp;</span>
449
- <span class="cline-any cline-neutral">&nbsp;</span>
450
- <span class="cline-any cline-yes">2x</span>
451
- <span class="cline-any cline-neutral">&nbsp;</span>
452
- <span class="cline-any cline-neutral">&nbsp;</span>
453
- <span class="cline-any cline-no">&nbsp;</span>
454
- <span class="cline-any cline-neutral">&nbsp;</span>
455
- <span class="cline-any cline-neutral">&nbsp;</span>
456
- <span class="cline-any cline-yes">2x</span>
457
- <span class="cline-any cline-neutral">&nbsp;</span>
458
- <span class="cline-any cline-neutral">&nbsp;</span>
459
- <span class="cline-any cline-neutral">&nbsp;</span>
460
- <span class="cline-any cline-neutral">&nbsp;</span>
461
- <span class="cline-any cline-neutral">&nbsp;</span>
462
- <span class="cline-any cline-neutral">&nbsp;</span>
463
- <span class="cline-any cline-neutral">&nbsp;</span>
464
- <span class="cline-any cline-yes">18x</span>
465
- <span class="cline-any cline-yes">1x</span>
466
- <span class="cline-any cline-yes">1x</span>
467
- <span class="cline-any cline-yes">1x</span>
468
- <span class="cline-any cline-yes">1x</span>
469
- <span class="cline-any cline-yes">1x</span>
470
- <span class="cline-any cline-yes">1x</span>
471
- <span class="cline-any cline-yes">1x</span>
472
- <span class="cline-any cline-yes">1x</span>
473
- <span class="cline-any cline-neutral">&nbsp;</span>
474
- <span class="cline-any cline-neutral">&nbsp;</span>
475
- <span class="cline-any cline-neutral">&nbsp;</span>
476
- <span class="cline-any cline-yes">1x</span>
477
- <span class="cline-any cline-yes">1x</span>
478
- <span class="cline-any cline-neutral">&nbsp;</span>
479
- <span class="cline-any cline-no">&nbsp;</span>
480
- <span class="cline-any cline-no">&nbsp;</span>
481
- <span class="cline-any cline-neutral">&nbsp;</span>
482
- <span class="cline-any cline-neutral">&nbsp;</span>
483
- <span class="cline-any cline-neutral">&nbsp;</span>
484
- <span class="cline-any cline-yes">18x</span>
485
- <span class="cline-any cline-yes">1x</span>
486
- <span class="cline-any cline-yes">1x</span>
487
- <span class="cline-any cline-neutral">&nbsp;</span>
488
- <span class="cline-any cline-yes">1x</span>
489
- <span class="cline-any cline-neutral">&nbsp;</span>
490
- <span class="cline-any cline-neutral">&nbsp;</span>
491
- <span class="cline-any cline-yes">18x</span>
492
- <span class="cline-any cline-no">&nbsp;</span>
493
- <span class="cline-any cline-no">&nbsp;</span>
494
- <span class="cline-any cline-no">&nbsp;</span>
495
- <span class="cline-any cline-neutral">&nbsp;</span>
496
- <span class="cline-any cline-no">&nbsp;</span>
497
- <span class="cline-any cline-neutral">&nbsp;</span>
498
- <span class="cline-any cline-neutral">&nbsp;</span>
499
- <span class="cline-any cline-neutral">&nbsp;</span>
500
- <span class="cline-any cline-neutral">&nbsp;</span>
501
- <span class="cline-any cline-neutral">&nbsp;</span>
502
- <span class="cline-any cline-neutral">&nbsp;</span>
503
- <span class="cline-any cline-neutral">&nbsp;</span>
504
- <span class="cline-any cline-neutral">&nbsp;</span>
505
- <span class="cline-any cline-neutral">&nbsp;</span>
506
- <span class="cline-any cline-no">&nbsp;</span>
507
- <span class="cline-any cline-neutral">&nbsp;</span>
508
- <span class="cline-any cline-neutral">&nbsp;</span>
509
- <span class="cline-any cline-yes">36x</span>
510
- <span class="cline-any cline-no">&nbsp;</span>
511
- <span class="cline-any cline-no">&nbsp;</span>
512
- <span class="cline-any cline-no">&nbsp;</span>
513
- <span class="cline-any cline-no">&nbsp;</span>
514
- <span class="cline-any cline-no">&nbsp;</span>
515
- <span class="cline-any cline-neutral">&nbsp;</span>
516
- <span class="cline-any cline-neutral">&nbsp;</span>
517
- <span class="cline-any cline-neutral">&nbsp;</span>
518
- <span class="cline-any cline-neutral">&nbsp;</span>
519
- <span class="cline-any cline-neutral">&nbsp;</span>
520
- <span class="cline-any cline-neutral">&nbsp;</span>
521
- <span class="cline-any cline-yes">18x</span>
522
- <span class="cline-any cline-no">&nbsp;</span>
523
- <span class="cline-any cline-neutral">&nbsp;</span>
524
- <span class="cline-any cline-no">&nbsp;</span>
525
- <span class="cline-any cline-neutral">&nbsp;</span>
526
- <span class="cline-any cline-neutral">&nbsp;</span>
527
- <span class="cline-any cline-neutral">&nbsp;</span>
528
- <span class="cline-any cline-no">&nbsp;</span>
529
- <span class="cline-any cline-no">&nbsp;</span>
530
- <span class="cline-any cline-neutral">&nbsp;</span>
531
- <span class="cline-any cline-neutral">&nbsp;</span>
532
- <span class="cline-any cline-neutral">&nbsp;</span>
533
- <span class="cline-any cline-neutral">&nbsp;</span>
534
- <span class="cline-any cline-neutral">&nbsp;</span>
535
- <span class="cline-any cline-no">&nbsp;</span>
536
- <span class="cline-any cline-neutral">&nbsp;</span>
537
- <span class="cline-any cline-neutral">&nbsp;</span>
538
- <span class="cline-any cline-neutral">&nbsp;</span>
539
- <span class="cline-any cline-neutral">&nbsp;</span>
540
- <span class="cline-any cline-neutral">&nbsp;</span>
541
- <span class="cline-any cline-neutral">&nbsp;</span>
542
- <span class="cline-any cline-yes">54x</span>
543
- <span class="cline-any cline-no">&nbsp;</span>
544
- <span class="cline-any cline-neutral">&nbsp;</span>
545
- <span class="cline-any cline-no">&nbsp;</span>
546
- <span class="cline-any cline-neutral">&nbsp;</span>
547
- <span class="cline-any cline-neutral">&nbsp;</span>
548
- <span class="cline-any cline-neutral">&nbsp;</span>
549
- <span class="cline-any cline-no">&nbsp;</span>
550
- <span class="cline-any cline-no">&nbsp;</span>
551
- <span class="cline-any cline-neutral">&nbsp;</span>
552
- <span class="cline-any cline-neutral">&nbsp;</span>
553
- <span class="cline-any cline-neutral">&nbsp;</span>
554
- <span class="cline-any cline-neutral">&nbsp;</span>
555
- <span class="cline-any cline-neutral">&nbsp;</span>
556
- <span class="cline-any cline-no">&nbsp;</span>
557
- <span class="cline-any cline-neutral">&nbsp;</span>
558
- <span class="cline-any cline-neutral">&nbsp;</span>
559
- <span class="cline-any cline-neutral">&nbsp;</span>
560
- <span class="cline-any cline-no">&nbsp;</span>
561
- <span class="cline-any cline-no">&nbsp;</span>
562
- <span class="cline-any cline-no">&nbsp;</span>
563
- <span class="cline-any cline-neutral">&nbsp;</span>
564
- <span class="cline-any cline-no">&nbsp;</span>
565
- <span class="cline-any cline-neutral">&nbsp;</span>
566
- <span class="cline-any cline-neutral">&nbsp;</span>
567
- <span class="cline-any cline-neutral">&nbsp;</span>
568
- <span class="cline-any cline-neutral">&nbsp;</span>
569
- <span class="cline-any cline-yes">18x</span>
570
- <span class="cline-any cline-yes">3x</span>
571
- <span class="cline-any cline-yes">3x</span>
572
- <span class="cline-any cline-neutral">&nbsp;</span>
573
- <span class="cline-any cline-neutral">&nbsp;</span>
574
- <span class="cline-any cline-neutral">&nbsp;</span>
575
- <span class="cline-any cline-neutral">&nbsp;</span>
576
- <span class="cline-any cline-yes">3x</span>
577
- <span class="cline-any cline-yes">3x</span>
578
- <span class="cline-any cline-neutral">&nbsp;</span>
579
- <span class="cline-any cline-neutral">&nbsp;</span>
580
- <span class="cline-any cline-yes">3x</span>
581
- <span class="cline-any cline-neutral">&nbsp;</span>
582
- <span class="cline-any cline-neutral">&nbsp;</span>
583
- <span class="cline-any cline-neutral">&nbsp;</span>
584
- <span class="cline-any cline-yes">3x</span>
585
- <span class="cline-any cline-neutral">&nbsp;</span>
586
- <span class="cline-any cline-neutral">&nbsp;</span>
587
- <span class="cline-any cline-neutral">&nbsp;</span>
588
- <span class="cline-any cline-neutral">&nbsp;</span>
589
- <span class="cline-any cline-neutral">&nbsp;</span>
590
- <span class="cline-any cline-neutral">&nbsp;</span>
591
- <span class="cline-any cline-yes">18x</span>
592
- <span class="cline-any cline-yes">2x</span>
593
- <span class="cline-any cline-yes">2x</span>
594
- <span class="cline-any cline-neutral">&nbsp;</span>
595
- <span class="cline-any cline-yes">2x</span>
596
- <span class="cline-any cline-neutral">&nbsp;</span>
597
- <span class="cline-any cline-yes">2x</span>
598
- <span class="cline-any cline-yes">2x</span>
599
- <span class="cline-any cline-neutral">&nbsp;</span>
600
- <span class="cline-any cline-neutral">&nbsp;</span>
601
- <span class="cline-any cline-neutral">&nbsp;</span>
602
- <span class="cline-any cline-neutral">&nbsp;</span>
603
- <span class="cline-any cline-yes">2x</span>
604
- <span class="cline-any cline-neutral">&nbsp;</span>
605
- <span class="cline-any cline-neutral">&nbsp;</span>
606
- <span class="cline-any cline-yes">2x</span>
607
- <span class="cline-any cline-neutral">&nbsp;</span>
608
- <span class="cline-any cline-neutral">&nbsp;</span>
609
- <span class="cline-any cline-neutral">&nbsp;</span>
610
- <span class="cline-any cline-yes">2x</span>
611
- <span class="cline-any cline-neutral">&nbsp;</span>
612
- <span class="cline-any cline-neutral">&nbsp;</span>
613
- <span class="cline-any cline-neutral">&nbsp;</span>
614
- <span class="cline-any cline-neutral">&nbsp;</span>
615
- <span class="cline-any cline-neutral">&nbsp;</span>
616
- <span class="cline-any cline-yes">54x</span>
617
- <span class="cline-any cline-yes">1x</span>
618
- <span class="cline-any cline-yes">1x</span>
619
- <span class="cline-any cline-neutral">&nbsp;</span>
620
- <span class="cline-any cline-yes">1x</span>
621
- <span class="cline-any cline-neutral">&nbsp;</span>
622
- <span class="cline-any cline-neutral">&nbsp;</span>
623
- <span class="cline-any cline-neutral">&nbsp;</span>
624
- <span class="cline-any cline-yes">1x</span>
625
- <span class="cline-any cline-yes">1x</span>
626
- <span class="cline-any cline-yes">1x</span>
627
- <span class="cline-any cline-neutral">&nbsp;</span>
628
- <span class="cline-any cline-yes">1x</span>
629
- <span class="cline-any cline-neutral">&nbsp;</span>
630
- <span class="cline-any cline-neutral">&nbsp;</span>
631
- <span class="cline-any cline-neutral">&nbsp;</span>
632
- <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import {
633
- auth,
634
- constants,
635
- context,
636
- db as dbCore,
637
- events,
638
- tenancy,
639
- users as usersCore,
640
- utils,
641
- } from "@budibase/backend-core"
642
- import { EmailTemplatePurpose } from "../../../constants"
643
- import { isEmailConfigured, sendEmail } from "../../../utilities/email"
644
- import { checkResetPasswordCode } from "../../../utilities/redis"
645
- import env from "../../../environment"
646
- import sdk from "../../../sdk"
647
- import { ConfigType, User } from "@budibase/types"
648
- &nbsp;
649
- const { setCookie, getCookie, clearCookie, hash, platformLogout } = utils
650
- const { Cookie, Header } = constants
651
- const { passport, ssoCallbackUrl, google, oidc } = auth
652
- &nbsp;
653
- export async function <span class="cstat-no" title="statement not covered" ><span class="fstat-no" title="function not covered" >googleCallbackUrl<span class="fstat-no" title="function not covered" >(</span></span>c</span>onfig?: { callbackURL?: string }) {
654
- <span class="cstat-no" title="statement not covered" > return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.GOOGLE)</span>
655
- }
656
- &nbsp;
657
- export async function <span class="cstat-no" title="statement not covered" >oidcCallbackUrl<span class="fstat-no" title="function not covered" >(</span>c</span>onfig?: { callbackURL?: string }) {
658
- return ssoCallbackUrl(tenancy.getGlobalDB(), config, ConfigType.OIDC)
659
- }
660
- &nbsp;
661
- async function authInternal(ctx: any, user: any, err: any = <span class="branch-0 cbranch-no" title="branch not covered" >null,</span> info = <span class="branch-0 cbranch-no" title="branch not covered" >null)</span> {
662
- <span class="missing-if-branch" title="if path not taken" >I</span>if (err) {
663
- <span class="cstat-no" title="statement not covered" > console.error("Authentication error")</span>
664
- <span class="cstat-no" title="statement not covered" > console.error(err)</span>
665
- <span class="cstat-no" title="statement not covered" > console.trace(err)</span>
666
- <span class="cstat-no" title="statement not covered" > return ctx.throw(403, info ? info : "Unauthorized")</span>
667
- }
668
- &nbsp;
669
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!user) {
670
- <span class="cstat-no" title="statement not covered" > console.error("Authentication error - no user provided")</span>
671
- <span class="cstat-no" title="statement not covered" > return ctx.throw(403, info ? info : "Unauthorized")</span>
672
- }
673
- &nbsp;
674
- // set a cookie for browser access
675
- setCookie(ctx, user.token, Cookie.Auth, { sign: false })
676
- // set the token in a header as well for APIs
677
- ctx.set(Header.TOKEN, user.token)
678
- // get rid of any app cookies on login
679
- // have to check test because this breaks cypress
680
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!env.isTest()) {
681
- <span class="cstat-no" title="statement not covered" > clearCookie(ctx, Cookie.CurrentApp)</span>
682
- }
683
- }
684
- &nbsp;
685
- export const authenticate = <span class="fstat-no" title="function not covered" >async (c</span>tx: any, next: any) =&gt; {
686
- <span class="cstat-no" title="statement not covered" > return passport.authenticate(</span>
687
- "local",
688
- <span class="fstat-no" title="function not covered" > async (e</span>rr: any, user: User, info: any) =&gt; {
689
- <span class="cstat-no" title="statement not covered" > await authInternal(ctx, user, err, info)</span>
690
- <span class="cstat-no" title="statement not covered" > await context.identity.doInUserContext(user, <span class="fstat-no" title="function not covered" >async () =&gt; {</span></span>
691
- <span class="cstat-no" title="statement not covered" > await events.auth.login("local")</span>
692
- })
693
- <span class="cstat-no" title="statement not covered" > ctx.status = 200</span>
694
- }
695
- )(ctx, next)
696
- }
697
- &nbsp;
698
- export const setInitInfo = <span class="fstat-no" title="function not covered" >(c</span>tx: any) =&gt; {
699
- const initInfo = <span class="cstat-no" title="statement not covered" >ctx.request.body</span>
700
- <span class="cstat-no" title="statement not covered" > setCookie(ctx, initInfo, Cookie.Init)</span>
701
- <span class="cstat-no" title="statement not covered" > ctx.status = 200</span>
702
- }
703
- &nbsp;
704
- export const getInitInfo = <span class="fstat-no" title="function not covered" >(c</span>tx: any) =&gt; {
705
- <span class="cstat-no" title="statement not covered" > try {</span>
706
- <span class="cstat-no" title="statement not covered" > ctx.body = getCookie(ctx, Cookie.Init) || {}</span>
707
- } catch (err) {
708
- <span class="cstat-no" title="statement not covered" > clearCookie(ctx, Cookie.Init)</span>
709
- <span class="cstat-no" title="statement not covered" > ctx.body = {}</span>
710
- }
711
- }
712
- &nbsp;
713
- /**
714
- * Reset the user password, used as part of a forgotten password flow.
715
- */
716
- export const reset = async (ctx: any) =&gt; {
717
- const { email } = ctx.request.body
718
- const configured = await isEmailConfigured()
719
- <span class="missing-if-branch" title="if path not taken" >I</span>if (!configured) {
720
- <span class="cstat-no" title="statement not covered" > ctx.throw(</span>
721
- 400,
722
- "Please contact your platform administrator, SMTP is not configured."
723
- )
724
- }
725
- try {
726
- const user = (await usersCore.getGlobalUserByEmail(email)) as User
727
- // only if user exists, don't error though if they don't
728
- if (user) {
729
- await sendEmail(email, EmailTemplatePurpose.PASSWORD_RECOVERY, {
730
- user,
731
- subject: "{{ company }} platform password reset",
732
- })
733
- await events.user.passwordResetRequested(user)
734
- }
735
- } catch (err) {
736
- <span class="cstat-no" title="statement not covered" > console.log(err)</span>
737
- // don't throw any kind of error to the user, this might give away something
738
- }
739
- ctx.body = {
740
- message: "Please check your email for a reset link.",
741
- }
742
- }
743
- &nbsp;
744
- /**
745
- * Perform the user password update if the provided reset code is valid.
746
- */
747
- export const resetUpdate = async (ctx: any) =&gt; {
748
- const { resetCode, password } = ctx.request.body
749
- try {
750
- const { userId } = await checkResetPasswordCode(resetCode)
751
- const db = tenancy.getGlobalDB()
752
- const user = await db.get(userId)
753
- user.password = await hash(password)
754
- await db.put(user)
755
- ctx.body = {
756
- message: "password reset successfully.",
757
- }
758
- // remove password from the user before sending events
759
- delete user.password
760
- await events.user.passwordReset(user)
761
- } catch (err) {
762
- <span class="cstat-no" title="statement not covered" > console.error(err)</span>
763
- <span class="cstat-no" title="statement not covered" > ctx.throw(400, "Cannot reset password.")</span>
764
- }
765
- }
766
- &nbsp;
767
- export const logout = async (ctx: any) =&gt; {
768
- if (ctx.user &amp;&amp; ctx.user._id) {
769
- await platformLogout({ ctx, userId: ctx.user._id })
770
- }
771
- ctx.body = { message: "User logged out." }
772
- }
773
- &nbsp;
774
- export const datasourcePreAuth = <span class="fstat-no" title="function not covered" >async (c</span>tx: any, next: any) =&gt; {
775
- const provider = <span class="cstat-no" title="statement not covered" >ctx.params.provider</span>
776
- const { middleware } = <span class="cstat-no" title="statement not covered" >require(`@budibase/backend-core`)</span>
777
- const handler = <span class="cstat-no" title="statement not covered" >middleware.datasource[provider]</span>
778
- &nbsp;
779
- <span class="cstat-no" title="statement not covered" > setCookie(</span>
780
- ctx,
781
- {
782
- provider,
783
- appId: ctx.query.appId,
784
- datasourceId: ctx.query.datasourceId,
785
- },
786
- Cookie.DatasourceAuth
787
- )
788
- &nbsp;
789
- <span class="cstat-no" title="statement not covered" > return handler.preAuth(passport, ctx, next)</span>
790
- }
791
- &nbsp;
792
- export const datasourceAuth = <span class="fstat-no" title="function not covered" >async (c</span>tx: any, next: any) =&gt; {
793
- const authStateCookie = <span class="cstat-no" title="statement not covered" >getCookie(ctx, Cookie.DatasourceAuth)</span>
794
- const provider = <span class="cstat-no" title="statement not covered" >authStateCookie.provider</span>
795
- const { middleware } = <span class="cstat-no" title="statement not covered" >require(`@budibase/backend-core`)</span>
796
- const handler = <span class="cstat-no" title="statement not covered" >middleware.datasource[provider]</span>
797
- <span class="cstat-no" title="statement not covered" > return handler.postAuth(passport, ctx, next)</span>
798
- }
799
- &nbsp;
800
- /**
801
- * The initial call that google authentication makes to take you to the google login screen.
802
- * On a successful login, you will be redirected to the googleAuth callback route.
803
- */
804
- export const googlePreAuth = <span class="fstat-no" title="function not covered" >async (c</span>tx: any, next: any) =&gt; {
805
- const db = <span class="cstat-no" title="statement not covered" >tenancy.getGlobalDB()</span>
806
- &nbsp;
807
- const config = <span class="cstat-no" title="statement not covered" >await dbCore.getScopedConfig(db, {</span>
808
- type: ConfigType.GOOGLE,
809
- workspace: ctx.query.workspace,
810
- })
811
- let callbackUrl = <span class="cstat-no" title="statement not covered" >await googleCallbackUrl(config)</span>
812
- const strategy = <span class="cstat-no" title="statement not covered" >await google.strategyFactory(</span>
813
- config,
814
- callbackUrl,
815
- sdk.users.save
816
- )
817
- &nbsp;
818
- <span class="cstat-no" title="statement not covered" > return passport.authenticate(strategy, {</span>
819
- scope: ["profile", "email"],
820
- accessType: "offline",
821
- prompt: "consent",
822
- })(ctx, next)
823
- }
824
- &nbsp;
825
- export const googleAuth = <span class="fstat-no" title="function not covered" >async (c</span>tx: any, next: any) =&gt; {
826
- const db = <span class="cstat-no" title="statement not covered" >tenancy.getGlobalDB()</span>
827
- &nbsp;
828
- const config = <span class="cstat-no" title="statement not covered" >await dbCore.getScopedConfig(db, {</span>
829
- type: ConfigType.GOOGLE,
830
- workspace: ctx.query.workspace,
831
- })
832
- const callbackUrl = <span class="cstat-no" title="statement not covered" >await googleCallbackUrl(config)</span>
833
- const strategy = <span class="cstat-no" title="statement not covered" >await google.strategyFactory(</span>
834
- config,
835
- callbackUrl,
836
- sdk.users.save
837
- )
838
- &nbsp;
839
- <span class="cstat-no" title="statement not covered" > return passport.authenticate(</span>
840
- strategy,
841
- { successRedirect: "/", failureRedirect: "/error" },
842
- <span class="fstat-no" title="function not covered" > async (e</span>rr: any, user: User, info: any) =&gt; {
843
- <span class="cstat-no" title="statement not covered" > await authInternal(ctx, user, err, info)</span>
844
- <span class="cstat-no" title="statement not covered" > await context.identity.doInUserContext(user, <span class="fstat-no" title="function not covered" >async () =&gt; {</span></span>
845
- <span class="cstat-no" title="statement not covered" > await events.auth.login("google-internal")</span>
846
- })
847
- <span class="cstat-no" title="statement not covered" > ctx.redirect("/")</span>
848
- }
849
- )(ctx, next)
850
- }
851
- &nbsp;
852
- export const <span class="cstat-no" title="statement not covered" >oidcStrategyFactory<span class="fstat-no" title="function not covered" > </span>= a</span>sync (ctx: any, configId: any) =&gt; {
853
- const db = tenancy.getGlobalDB()
854
- const config = await dbCore.getScopedConfig(db, {
855
- type: ConfigType.OIDC,
856
- group: ctx.query.group,
857
- })
858
- &nbsp;
859
- const chosenConfig = config.configs.filter((c: any) =&gt; c.uuid === configId)[0]
860
- let callbackUrl = await oidcCallbackUrl(chosenConfig)
861
- &nbsp;
862
- //Remote Config
863
- const enrichedConfig = await oidc.fetchStrategyConfig(
864
- chosenConfig,
865
- callbackUrl
866
- )
867
- return oidc.strategyFactory(enrichedConfig, sdk.users.save)
868
- }
869
- &nbsp;
870
- /**
871
- * The initial call that OIDC authentication makes to take you to the configured OIDC login screen.
872
- * On a successful login, you will be redirected to the oidcAuth callback route.
873
- */
874
- export const oidcPreAuth = async (ctx: any, next: any) =&gt; {
875
- const { configId } = ctx.params
876
- const strategy = await oidcStrategyFactory(ctx, configId)
877
- &nbsp;
878
- setCookie(ctx, configId, Cookie.OIDC_CONFIG)
879
- &nbsp;
880
- const db = tenancy.getGlobalDB()
881
- const config = await dbCore.getScopedConfig(db, {
882
- type: ConfigType.OIDC,
883
- group: ctx.query.group,
884
- })
885
- &nbsp;
886
- const chosenConfig = config.configs.filter((c: any) =&gt; c.uuid === configId)[0]
887
- &nbsp;
888
- let authScopes =
889
- chosenConfig.scopes?.length &gt; 0
890
- ? <span class="branch-0 cbranch-no" title="branch not covered" >chosenConfig.scopes</span>
891
- : ["profile", "email", "offline_access"]
892
- &nbsp;
893
- return passport.authenticate(strategy, {
894
- // required 'openid' scope is added by oidc strategy factory
895
- scope: authScopes,
896
- })(ctx, next)
897
- }
898
- &nbsp;
899
- export const oidcAuth = async (ctx: any, next: any) =&gt; {
900
- const configId = getCookie(ctx, Cookie.OIDC_CONFIG)
901
- const strategy = await oidcStrategyFactory(ctx, configId)
902
- &nbsp;
903
- return passport.authenticate(
904
- strategy,
905
- { successRedirect: "/", failureRedirect: "/error" },
906
- async (err: any, user: any, info: any) =&gt; {
907
- await authInternal(ctx, user, err, info)
908
- await context.identity.doInUserContext(user, async () =&gt; {
909
- await events.auth.login("oidc")
910
- })
911
- ctx.redirect("/")
912
- }
913
- )(ctx, next)
914
- }
915
- &nbsp;</pre></td></tr></table></pre>
916
-
917
- <div class='push'></div><!-- for sticky footer -->
918
- </div><!-- /wrapper -->
919
- <div class='footer quiet pad2 space-top1 center small'>
920
- Code coverage generated by
921
- <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
922
- at Thu Feb 16 2023 16:34:19 GMT+0000 (Coordinated Universal Time)
923
- </div>
924
- <script src="../../../../prettify.js"></script>
925
- <script>
926
- window.onload = function () {
927
- prettyPrint();
928
- };
929
- </script>
930
- <script src="../../../../sorter.js"></script>
931
- <script src="../../../../block-navigation.js"></script>
932
- </body>
933
- </html>
934
-