@nocios/crudify-components 2.0.36 → 2.0.38

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 (134) hide show
  1. package/coverage/components/CrudiaAutoGenerate.tsx.html +583 -0
  2. package/coverage/components/CrudiaFileField/CrudiaFileField.tsx.html +1276 -0
  3. package/coverage/components/CrudiaFileField/components/DeleteConfirmationDialog.tsx.html +355 -0
  4. package/coverage/components/CrudiaFileField/components/DropZone.tsx.html +433 -0
  5. package/coverage/components/CrudiaFileField/components/FileItemRow.tsx.html +751 -0
  6. package/coverage/components/CrudiaFileField/components/FileThumbnail.tsx.html +1195 -0
  7. package/coverage/components/CrudiaFileField/components/index.html +176 -0
  8. package/coverage/components/CrudiaFileField/components/index.ts.html +115 -0
  9. package/coverage/components/CrudiaFileField/hooks/index.html +146 -0
  10. package/coverage/components/CrudiaFileField/hooks/index.ts.html +112 -0
  11. package/coverage/components/CrudiaFileField/hooks/useDeleteConfirmation.ts.html +421 -0
  12. package/coverage/components/CrudiaFileField/hooks/useDragDrop.ts.html +403 -0
  13. package/coverage/components/CrudiaFileField/index.html +131 -0
  14. package/coverage/components/CrudiaFileField/index.ts.html +112 -0
  15. package/coverage/components/CrudiaFileField/utils/formatters.ts.html +163 -0
  16. package/coverage/components/CrudiaFileField/utils/icons.tsx.html +253 -0
  17. package/coverage/components/CrudiaFileField/utils/index.html +131 -0
  18. package/coverage/components/CrudiaMarkdownField.tsx.html +619 -0
  19. package/coverage/components/CrudifyLogin/Forms/CheckCodeForm.tsx.html +586 -0
  20. package/coverage/components/CrudifyLogin/Forms/ForgotPasswordForm.tsx.html +694 -0
  21. package/coverage/components/CrudifyLogin/Forms/LoginForm.tsx.html +835 -0
  22. package/coverage/components/CrudifyLogin/Forms/ResetPasswordForm.tsx.html +1180 -0
  23. package/coverage/components/CrudifyLogin/Forms/components/CodeInput.tsx.html +283 -0
  24. package/coverage/components/CrudifyLogin/Forms/components/FormAlert.tsx.html +202 -0
  25. package/coverage/components/CrudifyLogin/Forms/components/PasswordInput.tsx.html +340 -0
  26. package/coverage/components/CrudifyLogin/Forms/components/index.html +161 -0
  27. package/coverage/components/CrudifyLogin/Forms/components/index.ts.html +106 -0
  28. package/coverage/components/CrudifyLogin/Forms/index.html +161 -0
  29. package/coverage/components/CrudifyLogin/Forms/utils/errorTranslation.ts.html +268 -0
  30. package/coverage/components/CrudifyLogin/Forms/utils/index.html +161 -0
  31. package/coverage/components/CrudifyLogin/Forms/utils/index.ts.html +106 -0
  32. package/coverage/components/CrudifyLogin/Forms/utils/paramUtils.ts.html +478 -0
  33. package/coverage/components/CrudifyLogin/Forms/utils/validation.ts.html +289 -0
  34. package/coverage/components/CrudifyLogin/components/CrudifyInitializer.tsx.html +262 -0
  35. package/coverage/components/CrudifyLogin/components/index.html +116 -0
  36. package/coverage/components/CrudifyLogin/context/CrudifyProvider.tsx.html +382 -0
  37. package/coverage/components/CrudifyLogin/context/I18nProvider.tsx.html +397 -0
  38. package/coverage/components/CrudifyLogin/context/LoginStateProvider.tsx.html +1249 -0
  39. package/coverage/components/CrudifyLogin/context/index.html +146 -0
  40. package/coverage/components/CrudifyLogin/hooks/index.html +116 -0
  41. package/coverage/components/CrudifyLogin/hooks/useTranslationsFromUrl.ts.html +292 -0
  42. package/coverage/components/CrudifyLogin/index.html +116 -0
  43. package/coverage/components/CrudifyLogin/index.tsx.html +475 -0
  44. package/coverage/components/GlobalNotificationProvider.tsx.html +781 -0
  45. package/coverage/components/LoginComponent.tsx.html +727 -0
  46. package/coverage/components/PasswordRequirements/index.html +116 -0
  47. package/coverage/components/PasswordRequirements/index.tsx.html +226 -0
  48. package/coverage/components/PublicPolicies/FieldSelector/FieldSelector.tsx.html +982 -0
  49. package/coverage/components/PublicPolicies/FieldSelector/index.html +131 -0
  50. package/coverage/components/PublicPolicies/FieldSelector/index.ts.html +85 -0
  51. package/coverage/components/PublicPolicies/Policies.tsx.html +610 -0
  52. package/coverage/components/PublicPolicies/PolicyItem/PolicyItem.tsx.html +856 -0
  53. package/coverage/components/PublicPolicies/PolicyItem/index.html +131 -0
  54. package/coverage/components/PublicPolicies/PolicyItem/index.ts.html +85 -0
  55. package/coverage/components/PublicPolicies/constants.ts.html +127 -0
  56. package/coverage/components/PublicPolicies/index.html +131 -0
  57. package/coverage/components/SessionTimeIndicator/index.html +116 -0
  58. package/coverage/components/SessionTimeIndicator/index.tsx.html +505 -0
  59. package/coverage/components/UserProfile/UserProfileDisplay.tsx.html +826 -0
  60. package/coverage/components/UserProfile/index.html +131 -0
  61. package/coverage/components/UserProfile/index.ts.html +85 -0
  62. package/coverage/components/index.html +176 -0
  63. package/coverage/components/index.ts.html +160 -0
  64. package/coverage/core/CrossTabSyncManager.ts.html +814 -0
  65. package/coverage/core/CrudifyInitializationManager.ts.html +1132 -0
  66. package/coverage/core/SessionManager.ts.html +2764 -0
  67. package/coverage/core/index.html +146 -0
  68. package/coverage/coverage-final.json +52 -85
  69. package/coverage/hooks/index.html +131 -0
  70. package/coverage/hooks/useAutoGenerate.ts.html +562 -0
  71. package/coverage/hooks/useFileUpload/index.html +131 -0
  72. package/coverage/hooks/useFileUpload/index.ts.html +112 -0
  73. package/coverage/hooks/useFileUpload/services/index.html +116 -0
  74. package/coverage/hooks/useFileUpload/services/uploadService.ts.html +610 -0
  75. package/coverage/hooks/useFileUpload/useFileUpload.ts.html +1870 -0
  76. package/coverage/hooks/useFileUpload/utils/fileUtils.ts.html +271 -0
  77. package/coverage/hooks/useFileUpload/utils/index.html +146 -0
  78. package/coverage/hooks/useFileUpload/utils/mimeTypes.ts.html +235 -0
  79. package/coverage/hooks/useFileUpload/utils/validation.ts.html +379 -0
  80. package/coverage/hooks/useSession/constants.ts.html +217 -0
  81. package/coverage/hooks/useSession/hooks/index.html +176 -0
  82. package/coverage/hooks/useSession/hooks/useAuthEventSubscriber.ts.html +331 -0
  83. package/coverage/hooks/useSession/hooks/useCrossTabSync.ts.html +433 -0
  84. package/coverage/hooks/useSession/hooks/useSessionActions.ts.html +664 -0
  85. package/coverage/hooks/useSession/hooks/useSessionState.ts.html +295 -0
  86. package/coverage/hooks/useSession/hooks/useTokenRefreshScheduler.ts.html +490 -0
  87. package/coverage/hooks/useSession/index.html +161 -0
  88. package/coverage/hooks/useSession/index.ts.html +127 -0
  89. package/coverage/hooks/useSession/types.ts.html +427 -0
  90. package/coverage/hooks/useSession/useSession.ts.html +526 -0
  91. package/coverage/hooks/useSession/utils/index.html +131 -0
  92. package/coverage/hooks/useSession/utils/initializeSession.ts.html +424 -0
  93. package/coverage/hooks/useSession/utils/tokenUtils.ts.html +280 -0
  94. package/coverage/hooks/useUserProfile.ts.html +658 -0
  95. package/coverage/index.html +237 -357
  96. package/coverage/providers/SessionProvider.tsx.html +1150 -0
  97. package/coverage/providers/TranslationsProvider.tsx.html +1450 -0
  98. package/coverage/providers/index.html +131 -0
  99. package/coverage/services/credentialsEventBus.ts.html +310 -0
  100. package/coverage/services/index.html +131 -0
  101. package/coverage/services/translationService.ts.html +1318 -0
  102. package/coverage/translations/critical.ts.html +1195 -0
  103. package/coverage/translations/index.html +116 -0
  104. package/coverage/types/index.html +116 -0
  105. package/coverage/types/password.ts.html +178 -0
  106. package/coverage/utils/authEventBus.ts.html +454 -0
  107. package/coverage/utils/configResolver.ts.html +460 -0
  108. package/coverage/utils/cookieSync.ts.html +580 -0
  109. package/coverage/utils/errorHandler.ts.html +1264 -0
  110. package/coverage/utils/errorTranslation.ts.html +862 -0
  111. package/coverage/utils/index.html +296 -0
  112. package/coverage/utils/jwtUtils.ts.html +301 -0
  113. package/coverage/utils/logger.ts.html +901 -0
  114. package/coverage/utils/navigationTracker.ts.html +565 -0
  115. package/coverage/utils/passwordValidation.ts.html +259 -0
  116. package/coverage/utils/redirectSecurity.ts.html +715 -0
  117. package/coverage/utils/tenantConfig.ts.html +700 -0
  118. package/coverage/utils/tokenStorage.ts.html +1768 -0
  119. package/coverage/utils/webCrypto.ts.html +472 -0
  120. package/dist/{CrudiaMarkdownField-Bxl08sRG.d.mts → CrudiaMarkdownField-BvJn2GL8.d.mts} +5 -0
  121. package/dist/{CrudiaMarkdownField-DUJNOOzP.d.ts → CrudiaMarkdownField-CggOpcBM.d.ts} +5 -0
  122. package/dist/chunk-SYHNHKFA.mjs +1 -0
  123. package/dist/chunk-W4ZYKPOK.js +1 -0
  124. package/dist/components.d.mts +1 -1
  125. package/dist/components.d.ts +1 -1
  126. package/dist/components.js +1 -1
  127. package/dist/components.mjs +1 -1
  128. package/dist/index.d.mts +6 -2
  129. package/dist/index.d.ts +6 -2
  130. package/dist/index.js +2 -2
  131. package/dist/index.mjs +1 -1
  132. package/package.json +1 -1
  133. package/dist/chunk-QFACMV2I.mjs +0 -1
  134. package/dist/chunk-QZH3KSJZ.js +0 -1
@@ -0,0 +1,727 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for components/LoginComponent.tsx</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">components</a> LoginComponent.tsx</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">8.83% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>19/215</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">100% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/0</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">0% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/2</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">8.83% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>19/215</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 type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line low'></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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
281
+ <span class="cline-any cline-yes">1x</span>
282
+ <span class="cline-any cline-yes">1x</span>
283
+ <span class="cline-any cline-yes">1x</span>
284
+ <span class="cline-any cline-yes">1x</span>
285
+ <span class="cline-any cline-yes">1x</span>
286
+ <span class="cline-any cline-yes">1x</span>
287
+ <span class="cline-any cline-yes">1x</span>
288
+ <span class="cline-any cline-yes">1x</span>
289
+ <span class="cline-any cline-yes">1x</span>
290
+ <span class="cline-any cline-yes">1x</span>
291
+ <span class="cline-any cline-yes">1x</span>
292
+ <span class="cline-any cline-yes">1x</span>
293
+ <span class="cline-any cline-yes">1x</span>
294
+ <span class="cline-any cline-no">&nbsp;</span>
295
+ <span class="cline-any cline-no">&nbsp;</span>
296
+ <span class="cline-any cline-no">&nbsp;</span>
297
+ <span class="cline-any cline-no">&nbsp;</span>
298
+ <span class="cline-any cline-no">&nbsp;</span>
299
+ <span class="cline-any cline-no">&nbsp;</span>
300
+ <span class="cline-any cline-no">&nbsp;</span>
301
+ <span class="cline-any cline-no">&nbsp;</span>
302
+ <span class="cline-any cline-no">&nbsp;</span>
303
+ <span class="cline-any cline-no">&nbsp;</span>
304
+ <span class="cline-any cline-no">&nbsp;</span>
305
+ <span class="cline-any cline-no">&nbsp;</span>
306
+ <span class="cline-any cline-no">&nbsp;</span>
307
+ <span class="cline-any cline-no">&nbsp;</span>
308
+ <span class="cline-any cline-no">&nbsp;</span>
309
+ <span class="cline-any cline-no">&nbsp;</span>
310
+ <span class="cline-any cline-no">&nbsp;</span>
311
+ <span class="cline-any cline-no">&nbsp;</span>
312
+ <span class="cline-any cline-no">&nbsp;</span>
313
+ <span class="cline-any cline-no">&nbsp;</span>
314
+ <span class="cline-any cline-no">&nbsp;</span>
315
+ <span class="cline-any cline-no">&nbsp;</span>
316
+ <span class="cline-any cline-no">&nbsp;</span>
317
+ <span class="cline-any cline-no">&nbsp;</span>
318
+ <span class="cline-any cline-no">&nbsp;</span>
319
+ <span class="cline-any cline-no">&nbsp;</span>
320
+ <span class="cline-any cline-no">&nbsp;</span>
321
+ <span class="cline-any cline-no">&nbsp;</span>
322
+ <span class="cline-any cline-no">&nbsp;</span>
323
+ <span class="cline-any cline-no">&nbsp;</span>
324
+ <span class="cline-any cline-no">&nbsp;</span>
325
+ <span class="cline-any cline-no">&nbsp;</span>
326
+ <span class="cline-any cline-no">&nbsp;</span>
327
+ <span class="cline-any cline-no">&nbsp;</span>
328
+ <span class="cline-any cline-no">&nbsp;</span>
329
+ <span class="cline-any cline-no">&nbsp;</span>
330
+ <span class="cline-any cline-no">&nbsp;</span>
331
+ <span class="cline-any cline-no">&nbsp;</span>
332
+ <span class="cline-any cline-no">&nbsp;</span>
333
+ <span class="cline-any cline-no">&nbsp;</span>
334
+ <span class="cline-any cline-no">&nbsp;</span>
335
+ <span class="cline-any cline-no">&nbsp;</span>
336
+ <span class="cline-any cline-no">&nbsp;</span>
337
+ <span class="cline-any cline-no">&nbsp;</span>
338
+ <span class="cline-any cline-no">&nbsp;</span>
339
+ <span class="cline-any cline-no">&nbsp;</span>
340
+ <span class="cline-any cline-no">&nbsp;</span>
341
+ <span class="cline-any cline-no">&nbsp;</span>
342
+ <span class="cline-any cline-no">&nbsp;</span>
343
+ <span class="cline-any cline-no">&nbsp;</span>
344
+ <span class="cline-any cline-no">&nbsp;</span>
345
+ <span class="cline-any cline-no">&nbsp;</span>
346
+ <span class="cline-any cline-no">&nbsp;</span>
347
+ <span class="cline-any cline-no">&nbsp;</span>
348
+ <span class="cline-any cline-no">&nbsp;</span>
349
+ <span class="cline-any cline-no">&nbsp;</span>
350
+ <span class="cline-any cline-no">&nbsp;</span>
351
+ <span class="cline-any cline-no">&nbsp;</span>
352
+ <span class="cline-any cline-no">&nbsp;</span>
353
+ <span class="cline-any cline-no">&nbsp;</span>
354
+ <span class="cline-any cline-no">&nbsp;</span>
355
+ <span class="cline-any cline-no">&nbsp;</span>
356
+ <span class="cline-any cline-no">&nbsp;</span>
357
+ <span class="cline-any cline-no">&nbsp;</span>
358
+ <span class="cline-any cline-no">&nbsp;</span>
359
+ <span class="cline-any cline-no">&nbsp;</span>
360
+ <span class="cline-any cline-no">&nbsp;</span>
361
+ <span class="cline-any cline-no">&nbsp;</span>
362
+ <span class="cline-any cline-no">&nbsp;</span>
363
+ <span class="cline-any cline-no">&nbsp;</span>
364
+ <span class="cline-any cline-no">&nbsp;</span>
365
+ <span class="cline-any cline-no">&nbsp;</span>
366
+ <span class="cline-any cline-no">&nbsp;</span>
367
+ <span class="cline-any cline-no">&nbsp;</span>
368
+ <span class="cline-any cline-no">&nbsp;</span>
369
+ <span class="cline-any cline-no">&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-no">&nbsp;</span>
373
+ <span class="cline-any cline-no">&nbsp;</span>
374
+ <span class="cline-any cline-no">&nbsp;</span>
375
+ <span class="cline-any cline-no">&nbsp;</span>
376
+ <span class="cline-any cline-no">&nbsp;</span>
377
+ <span class="cline-any cline-no">&nbsp;</span>
378
+ <span class="cline-any cline-no">&nbsp;</span>
379
+ <span class="cline-any cline-no">&nbsp;</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-no">&nbsp;</span>
385
+ <span class="cline-any cline-no">&nbsp;</span>
386
+ <span class="cline-any cline-no">&nbsp;</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-no">&nbsp;</span>
390
+ <span class="cline-any cline-no">&nbsp;</span>
391
+ <span class="cline-any cline-no">&nbsp;</span>
392
+ <span class="cline-any cline-no">&nbsp;</span>
393
+ <span class="cline-any cline-no">&nbsp;</span>
394
+ <span class="cline-any cline-no">&nbsp;</span>
395
+ <span class="cline-any cline-no">&nbsp;</span>
396
+ <span class="cline-any cline-no">&nbsp;</span>
397
+ <span class="cline-any cline-no">&nbsp;</span>
398
+ <span class="cline-any cline-no">&nbsp;</span>
399
+ <span class="cline-any cline-no">&nbsp;</span>
400
+ <span class="cline-any cline-no">&nbsp;</span>
401
+ <span class="cline-any cline-no">&nbsp;</span>
402
+ <span class="cline-any cline-no">&nbsp;</span>
403
+ <span class="cline-any cline-no">&nbsp;</span>
404
+ <span class="cline-any cline-no">&nbsp;</span>
405
+ <span class="cline-any cline-no">&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-no">&nbsp;</span>
410
+ <span class="cline-any cline-no">&nbsp;</span>
411
+ <span class="cline-any cline-no">&nbsp;</span>
412
+ <span class="cline-any cline-no">&nbsp;</span>
413
+ <span class="cline-any cline-no">&nbsp;</span>
414
+ <span class="cline-any cline-no">&nbsp;</span>
415
+ <span class="cline-any cline-no">&nbsp;</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-no">&nbsp;</span>
420
+ <span class="cline-any cline-no">&nbsp;</span>
421
+ <span class="cline-any cline-no">&nbsp;</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-no">&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-no">&nbsp;</span>
428
+ <span class="cline-any cline-no">&nbsp;</span>
429
+ <span class="cline-any cline-no">&nbsp;</span>
430
+ <span class="cline-any cline-no">&nbsp;</span>
431
+ <span class="cline-any cline-no">&nbsp;</span>
432
+ <span class="cline-any cline-no">&nbsp;</span>
433
+ <span class="cline-any cline-no">&nbsp;</span>
434
+ <span class="cline-any cline-no">&nbsp;</span>
435
+ <span class="cline-any cline-no">&nbsp;</span>
436
+ <span class="cline-any cline-no">&nbsp;</span>
437
+ <span class="cline-any cline-no">&nbsp;</span>
438
+ <span class="cline-any cline-no">&nbsp;</span>
439
+ <span class="cline-any cline-no">&nbsp;</span>
440
+ <span class="cline-any cline-no">&nbsp;</span>
441
+ <span class="cline-any cline-no">&nbsp;</span>
442
+ <span class="cline-any cline-no">&nbsp;</span>
443
+ <span class="cline-any cline-no">&nbsp;</span>
444
+ <span class="cline-any cline-no">&nbsp;</span>
445
+ <span class="cline-any cline-no">&nbsp;</span>
446
+ <span class="cline-any cline-no">&nbsp;</span>
447
+ <span class="cline-any cline-no">&nbsp;</span>
448
+ <span class="cline-any cline-no">&nbsp;</span>
449
+ <span class="cline-any cline-no">&nbsp;</span>
450
+ <span class="cline-any cline-no">&nbsp;</span>
451
+ <span class="cline-any cline-no">&nbsp;</span>
452
+ <span class="cline-any cline-no">&nbsp;</span>
453
+ <span class="cline-any cline-no">&nbsp;</span>
454
+ <span class="cline-any cline-no">&nbsp;</span>
455
+ <span class="cline-any cline-no">&nbsp;</span>
456
+ <span class="cline-any cline-no">&nbsp;</span>
457
+ <span class="cline-any cline-no">&nbsp;</span>
458
+ <span class="cline-any cline-yes">1x</span>
459
+ <span class="cline-any cline-yes">1x</span>
460
+ <span class="cline-any cline-yes">1x</span>
461
+ <span class="cline-any cline-yes">1x</span>
462
+ <span class="cline-any cline-yes">1x</span>
463
+ <span class="cline-any cline-no">&nbsp;</span>
464
+ <span class="cline-any cline-no">&nbsp;</span>
465
+ <span class="cline-any cline-no">&nbsp;</span>
466
+ <span class="cline-any cline-no">&nbsp;</span>
467
+ <span class="cline-any cline-no">&nbsp;</span>
468
+ <span class="cline-any cline-no">&nbsp;</span>
469
+ <span class="cline-any cline-no">&nbsp;</span>
470
+ <span class="cline-any cline-no">&nbsp;</span>
471
+ <span class="cline-any cline-no">&nbsp;</span>
472
+ <span class="cline-any cline-no">&nbsp;</span>
473
+ <span class="cline-any cline-no">&nbsp;</span>
474
+ <span class="cline-any cline-no">&nbsp;</span>
475
+ <span class="cline-any cline-no">&nbsp;</span>
476
+ <span class="cline-any cline-no">&nbsp;</span>
477
+ <span class="cline-any cline-no">&nbsp;</span>
478
+ <span class="cline-any cline-no">&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-no">&nbsp;</span>
482
+ <span class="cline-any cline-no">&nbsp;</span>
483
+ <span class="cline-any cline-no">&nbsp;</span>
484
+ <span class="cline-any cline-no">&nbsp;</span>
485
+ <span class="cline-any cline-no">&nbsp;</span>
486
+ <span class="cline-any cline-no">&nbsp;</span>
487
+ <span class="cline-any cline-no">&nbsp;</span>
488
+ <span class="cline-any cline-no">&nbsp;</span>
489
+ <span class="cline-any cline-no">&nbsp;</span>
490
+ <span class="cline-any cline-no">&nbsp;</span>
491
+ <span class="cline-any cline-no">&nbsp;</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></td><td class="text"><pre class="prettyprint lang-js">// =============================
495
+ // LOGIN COMPONENT
496
+ // =============================
497
+ &nbsp;
498
+ /**
499
+ * Componente de ejemplo que demuestra el uso del Refresh Token Pattern
500
+ * Incluye login, logout y manejo automático de sesiones
501
+ */
502
+ &nbsp;
503
+ import React, { useState } from 'react';
504
+ import { Button, TextField, Box, Alert, Typography, CircularProgress } from '@mui/material';
505
+ import { useSessionContext } from '../providers/SessionProvider';
506
+ &nbsp;
507
+ export <span class="fstat-no" title="function not covered" >function LoginComponent() {</span>
508
+ <span class="cstat-no" title="statement not covered" > const [email, setEmail] = useState('');</span>
509
+ <span class="cstat-no" title="statement not covered" > const [password, setPassword] = useState('');</span>
510
+ <span class="cstat-no" title="statement not covered" > const [showForm, setShowForm] = useState(false);</span>
511
+ <span class="cstat-no" title="statement not covered" ></span>
512
+ <span class="cstat-no" title="statement not covered" > const {</span>
513
+ <span class="cstat-no" title="statement not covered" > isAuthenticated,</span>
514
+ <span class="cstat-no" title="statement not covered" > isLoading,</span>
515
+ <span class="cstat-no" title="statement not covered" > error,</span>
516
+ <span class="cstat-no" title="statement not covered" > login,</span>
517
+ <span class="cstat-no" title="statement not covered" > logout,</span>
518
+ <span class="cstat-no" title="statement not covered" > refreshTokens,</span>
519
+ <span class="cstat-no" title="statement not covered" > clearError,</span>
520
+ <span class="cstat-no" title="statement not covered" > isExpiringSoon,</span>
521
+ <span class="cstat-no" title="statement not covered" > expiresIn</span>
522
+ <span class="cstat-no" title="statement not covered" > } = useSessionContext();</span>
523
+ <span class="cstat-no" title="statement not covered" ></span>
524
+ <span class="cstat-no" title="statement not covered" > const handleLogin = async (e: React.FormEvent) =&gt; {</span>
525
+ <span class="cstat-no" title="statement not covered" > e.preventDefault();</span>
526
+ <span class="cstat-no" title="statement not covered" ></span>
527
+ <span class="cstat-no" title="statement not covered" > if (!email || !password) {</span>
528
+ <span class="cstat-no" title="statement not covered" > return;</span>
529
+ <span class="cstat-no" title="statement not covered" > }</span>
530
+ <span class="cstat-no" title="statement not covered" ></span>
531
+ <span class="cstat-no" title="statement not covered" > const result = await login(email, password);</span>
532
+ <span class="cstat-no" title="statement not covered" ></span>
533
+ <span class="cstat-no" title="statement not covered" > if (result.success) {</span>
534
+ <span class="cstat-no" title="statement not covered" > setEmail('');</span>
535
+ <span class="cstat-no" title="statement not covered" > setPassword('');</span>
536
+ <span class="cstat-no" title="statement not covered" > setShowForm(false);</span>
537
+ <span class="cstat-no" title="statement not covered" > }</span>
538
+ <span class="cstat-no" title="statement not covered" > };</span>
539
+ <span class="cstat-no" title="statement not covered" ></span>
540
+ <span class="cstat-no" title="statement not covered" > const handleLogout = async () =&gt; {</span>
541
+ <span class="cstat-no" title="statement not covered" > await logout();</span>
542
+ <span class="cstat-no" title="statement not covered" > };</span>
543
+ <span class="cstat-no" title="statement not covered" ></span>
544
+ <span class="cstat-no" title="statement not covered" > const handleRefreshTokens = async () =&gt; {</span>
545
+ <span class="cstat-no" title="statement not covered" > await refreshTokens();</span>
546
+ <span class="cstat-no" title="statement not covered" > };</span>
547
+ <span class="cstat-no" title="statement not covered" ></span>
548
+ <span class="cstat-no" title="statement not covered" > // Si está autenticado, mostrar dashboard</span>
549
+ <span class="cstat-no" title="statement not covered" > if (isAuthenticated) {</span>
550
+ <span class="cstat-no" title="statement not covered" > return (</span>
551
+ <span class="cstat-no" title="statement not covered" > &lt;Box sx={{ maxWidth: 600, mx: 'auto', p: 3 }}&gt;</span>
552
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="h4" gutterBottom&gt;</span>
553
+ <span class="cstat-no" title="statement not covered" > Welcome! 🎉</span>
554
+ <span class="cstat-no" title="statement not covered" > &lt;/Typography&gt;</span>
555
+ <span class="cstat-no" title="statement not covered" ></span>
556
+ <span class="cstat-no" title="statement not covered" > &lt;Alert severity="success" sx={{ mb: 3 }}&gt;</span>
557
+ <span class="cstat-no" title="statement not covered" > You are successfully logged in with Refresh Token Pattern enabled</span>
558
+ <span class="cstat-no" title="statement not covered" > &lt;/Alert&gt;</span>
559
+ <span class="cstat-no" title="statement not covered" ></span>
560
+ <span class="cstat-no" title="statement not covered" > {/* Token Status */}</span>
561
+ <span class="cstat-no" title="statement not covered" > &lt;Box sx={{ mb: 3, p: 2, bgcolor: 'background.paper', border: 1, borderColor: 'divider', borderRadius: 1 }}&gt;</span>
562
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="h6" gutterBottom&gt;Token Status&lt;/Typography&gt;</span>
563
+ <span class="cstat-no" title="statement not covered" ></span>
564
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="body2" color="text.secondary"&gt;</span>
565
+ <span class="cstat-no" title="statement not covered" > Access Token expires in: {Math.round(expiresIn / 1000 / 60)} minutes</span>
566
+ <span class="cstat-no" title="statement not covered" > &lt;/Typography&gt;</span>
567
+ <span class="cstat-no" title="statement not covered" ></span>
568
+ <span class="cstat-no" title="statement not covered" > {isExpiringSoon &amp;&amp; (</span>
569
+ <span class="cstat-no" title="statement not covered" > &lt;Alert severity="warning" sx={{ mt: 1 }}&gt;</span>
570
+ <span class="cstat-no" title="statement not covered" > Token expires soon - automatic refresh will happen</span>
571
+ <span class="cstat-no" title="statement not covered" > &lt;/Alert&gt;</span>
572
+ <span class="cstat-no" title="statement not covered" > )}</span>
573
+ <span class="cstat-no" title="statement not covered" > &lt;/Box&gt;</span>
574
+ <span class="cstat-no" title="statement not covered" ></span>
575
+ <span class="cstat-no" title="statement not covered" > {/* Actions */}</span>
576
+ <span class="cstat-no" title="statement not covered" > &lt;Box sx={{ display: 'flex', gap: 2, flexWrap: 'wrap' }}&gt;</span>
577
+ <span class="cstat-no" title="statement not covered" > &lt;Button</span>
578
+ <span class="cstat-no" title="statement not covered" > variant="contained"</span>
579
+ <span class="cstat-no" title="statement not covered" > onClick={handleRefreshTokens}</span>
580
+ <span class="cstat-no" title="statement not covered" > disabled={isLoading}</span>
581
+ <span class="cstat-no" title="statement not covered" > startIcon={isLoading ? &lt;CircularProgress size={16} /&gt; : null}</span>
582
+ <span class="cstat-no" title="statement not covered" > &gt;</span>
583
+ <span class="cstat-no" title="statement not covered" > Refresh Tokens</span>
584
+ <span class="cstat-no" title="statement not covered" > &lt;/Button&gt;</span>
585
+ <span class="cstat-no" title="statement not covered" ></span>
586
+ <span class="cstat-no" title="statement not covered" > &lt;Button</span>
587
+ <span class="cstat-no" title="statement not covered" > variant="outlined"</span>
588
+ <span class="cstat-no" title="statement not covered" > color="error"</span>
589
+ <span class="cstat-no" title="statement not covered" > onClick={handleLogout}</span>
590
+ <span class="cstat-no" title="statement not covered" > disabled={isLoading}</span>
591
+ <span class="cstat-no" title="statement not covered" > &gt;</span>
592
+ <span class="cstat-no" title="statement not covered" > Logout</span>
593
+ <span class="cstat-no" title="statement not covered" > &lt;/Button&gt;</span>
594
+ <span class="cstat-no" title="statement not covered" > &lt;/Box&gt;</span>
595
+ <span class="cstat-no" title="statement not covered" ></span>
596
+ <span class="cstat-no" title="statement not covered" > {error &amp;&amp; (</span>
597
+ <span class="cstat-no" title="statement not covered" > &lt;Alert severity="error" sx={{ mt: 2 }} onClose={clearError}&gt;</span>
598
+ <span class="cstat-no" title="statement not covered" > {error}</span>
599
+ <span class="cstat-no" title="statement not covered" > &lt;/Alert&gt;</span>
600
+ <span class="cstat-no" title="statement not covered" > )}</span>
601
+ <span class="cstat-no" title="statement not covered" > &lt;/Box&gt;</span>
602
+ <span class="cstat-no" title="statement not covered" > );</span>
603
+ <span class="cstat-no" title="statement not covered" > }</span>
604
+ <span class="cstat-no" title="statement not covered" ></span>
605
+ <span class="cstat-no" title="statement not covered" > // Si no está autenticado, mostrar formulario de login</span>
606
+ <span class="cstat-no" title="statement not covered" > return (</span>
607
+ <span class="cstat-no" title="statement not covered" > &lt;Box sx={{ maxWidth: 400, mx: 'auto', p: 3 }}&gt;</span>
608
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="h4" gutterBottom align="center"&gt;</span>
609
+ <span class="cstat-no" title="statement not covered" > Login with Refresh Tokens</span>
610
+ <span class="cstat-no" title="statement not covered" > &lt;/Typography&gt;</span>
611
+ <span class="cstat-no" title="statement not covered" ></span>
612
+ <span class="cstat-no" title="statement not covered" > &lt;Alert severity="info" sx={{ mb: 3 }}&gt;</span>
613
+ <span class="cstat-no" title="statement not covered" > This demo shows the new Refresh Token Pattern with automatic session management</span>
614
+ <span class="cstat-no" title="statement not covered" > &lt;/Alert&gt;</span>
615
+ <span class="cstat-no" title="statement not covered" ></span>
616
+ <span class="cstat-no" title="statement not covered" > {!showForm ? (</span>
617
+ <span class="cstat-no" title="statement not covered" > &lt;Button</span>
618
+ <span class="cstat-no" title="statement not covered" > fullWidth</span>
619
+ <span class="cstat-no" title="statement not covered" > variant="contained"</span>
620
+ <span class="cstat-no" title="statement not covered" > size="large"</span>
621
+ <span class="cstat-no" title="statement not covered" > onClick={() =&gt; setShowForm(true)}</span>
622
+ <span class="cstat-no" title="statement not covered" > sx={{ mt: 2 }}</span>
623
+ <span class="cstat-no" title="statement not covered" > &gt;</span>
624
+ <span class="cstat-no" title="statement not covered" > Show Login Form</span>
625
+ <span class="cstat-no" title="statement not covered" > &lt;/Button&gt;</span>
626
+ <span class="cstat-no" title="statement not covered" > ) : (</span>
627
+ <span class="cstat-no" title="statement not covered" > &lt;form onSubmit={handleLogin}&gt;</span>
628
+ <span class="cstat-no" title="statement not covered" > &lt;TextField</span>
629
+ <span class="cstat-no" title="statement not covered" > fullWidth</span>
630
+ <span class="cstat-no" title="statement not covered" > label="Email"</span>
631
+ <span class="cstat-no" title="statement not covered" > type="email"</span>
632
+ <span class="cstat-no" title="statement not covered" > value={email}</span>
633
+ <span class="cstat-no" title="statement not covered" > onChange={(e) =&gt; setEmail(e.target.value)}</span>
634
+ <span class="cstat-no" title="statement not covered" > margin="normal"</span>
635
+ <span class="cstat-no" title="statement not covered" > required</span>
636
+ <span class="cstat-no" title="statement not covered" > autoComplete="email"</span>
637
+ <span class="cstat-no" title="statement not covered" > /&gt;</span>
638
+ <span class="cstat-no" title="statement not covered" ></span>
639
+ <span class="cstat-no" title="statement not covered" > &lt;TextField</span>
640
+ <span class="cstat-no" title="statement not covered" > fullWidth</span>
641
+ <span class="cstat-no" title="statement not covered" > label="Password"</span>
642
+ <span class="cstat-no" title="statement not covered" > type="password"</span>
643
+ <span class="cstat-no" title="statement not covered" > value={password}</span>
644
+ <span class="cstat-no" title="statement not covered" > onChange={(e) =&gt; setPassword(e.target.value)}</span>
645
+ <span class="cstat-no" title="statement not covered" > margin="normal"</span>
646
+ <span class="cstat-no" title="statement not covered" > required</span>
647
+ <span class="cstat-no" title="statement not covered" > autoComplete="current-password"</span>
648
+ <span class="cstat-no" title="statement not covered" > /&gt;</span>
649
+ <span class="cstat-no" title="statement not covered" ></span>
650
+ <span class="cstat-no" title="statement not covered" > &lt;Button</span>
651
+ <span class="cstat-no" title="statement not covered" > type="submit"</span>
652
+ <span class="cstat-no" title="statement not covered" > fullWidth</span>
653
+ <span class="cstat-no" title="statement not covered" > variant="contained"</span>
654
+ <span class="cstat-no" title="statement not covered" > size="large"</span>
655
+ <span class="cstat-no" title="statement not covered" > disabled={isLoading}</span>
656
+ <span class="cstat-no" title="statement not covered" > startIcon={isLoading ? &lt;CircularProgress size={16} /&gt; : null}</span>
657
+ <span class="cstat-no" title="statement not covered" > sx={{ mt: 3, mb: 2 }}</span>
658
+ <span class="cstat-no" title="statement not covered" > &gt;</span>
659
+ <span class="cstat-no" title="statement not covered" > {isLoading ? 'Logging in...' : 'Login'}</span>
660
+ <span class="cstat-no" title="statement not covered" > &lt;/Button&gt;</span>
661
+ <span class="cstat-no" title="statement not covered" > &lt;/form&gt;</span>
662
+ <span class="cstat-no" title="statement not covered" > )}</span>
663
+ <span class="cstat-no" title="statement not covered" ></span>
664
+ <span class="cstat-no" title="statement not covered" > {error &amp;&amp; (</span>
665
+ <span class="cstat-no" title="statement not covered" > &lt;Alert severity="error" sx={{ mt: 2 }} onClose={clearError}&gt;</span>
666
+ <span class="cstat-no" title="statement not covered" > {error}</span>
667
+ <span class="cstat-no" title="statement not covered" > &lt;/Alert&gt;</span>
668
+ <span class="cstat-no" title="statement not covered" > )}</span>
669
+ <span class="cstat-no" title="statement not covered" > &lt;/Box&gt;</span>
670
+ <span class="cstat-no" title="statement not covered" > );</span>
671
+ <span class="cstat-no" title="statement not covered" >}</span>
672
+ &nbsp;
673
+ /**
674
+ * Componente simple de estado de sesión para mostrar en cualquier lugar
675
+ */
676
+ export <span class="fstat-no" title="function not covered" >function SessionStatus() {</span>
677
+ <span class="cstat-no" title="statement not covered" > const { isAuthenticated, isLoading, isExpiringSoon, expiresIn } = useSessionContext();</span>
678
+ <span class="cstat-no" title="statement not covered" ></span>
679
+ <span class="cstat-no" title="statement not covered" > if (isLoading) {</span>
680
+ <span class="cstat-no" title="statement not covered" > return (</span>
681
+ <span class="cstat-no" title="statement not covered" > &lt;Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}&gt;</span>
682
+ <span class="cstat-no" title="statement not covered" > &lt;CircularProgress size={16} /&gt;</span>
683
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="caption"&gt;Loading session...&lt;/Typography&gt;</span>
684
+ <span class="cstat-no" title="statement not covered" > &lt;/Box&gt;</span>
685
+ <span class="cstat-no" title="statement not covered" > );</span>
686
+ <span class="cstat-no" title="statement not covered" > }</span>
687
+ <span class="cstat-no" title="statement not covered" ></span>
688
+ <span class="cstat-no" title="statement not covered" > if (!isAuthenticated) {</span>
689
+ <span class="cstat-no" title="statement not covered" > return (</span>
690
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="caption" color="text.secondary"&gt;</span>
691
+ <span class="cstat-no" title="statement not covered" > Not logged in</span>
692
+ <span class="cstat-no" title="statement not covered" > &lt;/Typography&gt;</span>
693
+ <span class="cstat-no" title="statement not covered" > );</span>
694
+ <span class="cstat-no" title="statement not covered" > }</span>
695
+ <span class="cstat-no" title="statement not covered" ></span>
696
+ <span class="cstat-no" title="statement not covered" > return (</span>
697
+ <span class="cstat-no" title="statement not covered" > &lt;Box&gt;</span>
698
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="caption" color="success.main"&gt;</span>
699
+ <span class="cstat-no" title="statement not covered" > ✓ Authenticated</span>
700
+ <span class="cstat-no" title="statement not covered" > &lt;/Typography&gt;</span>
701
+ <span class="cstat-no" title="statement not covered" > {isExpiringSoon &amp;&amp; (</span>
702
+ <span class="cstat-no" title="statement not covered" > &lt;Typography variant="caption" color="warning.main" display="block"&gt;</span>
703
+ <span class="cstat-no" title="statement not covered" > ⚠ Token expires in {Math.round(expiresIn / 1000 / 60)} min</span>
704
+ <span class="cstat-no" title="statement not covered" > &lt;/Typography&gt;</span>
705
+ <span class="cstat-no" title="statement not covered" > )}</span>
706
+ <span class="cstat-no" title="statement not covered" > &lt;/Box&gt;</span>
707
+ <span class="cstat-no" title="statement not covered" > );</span>
708
+ <span class="cstat-no" title="statement not covered" >}</span></pre></td></tr></table></pre>
709
+
710
+ <div class='push'></div><!-- for sticky footer -->
711
+ </div><!-- /wrapper -->
712
+ <div class='footer quiet pad2 space-top1 center small'>
713
+ Code coverage generated by
714
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
715
+ at 2026-01-28T06:22:15.683Z
716
+ </div>
717
+ <script src="../prettify.js"></script>
718
+ <script>
719
+ window.onload = function () {
720
+ prettyPrint();
721
+ };
722
+ </script>
723
+ <script src="../sorter.js"></script>
724
+ <script src="../block-navigation.js"></script>
725
+ </body>
726
+ </html>
727
+