Sergei 3f0fe56e02 Add protected route middleware and auth store for web app
- Implement Next.js middleware for route protection
- Create Zustand auth store for web (similar to mobile)
- Add comprehensive tests for middleware and auth store
- Protect authenticated routes (/dashboard, /profile)
- Redirect unauthenticated users to /login
- Redirect authenticated users from auth routes to /dashboard
- Handle session expiration with 401 callback
- Set access token cookie for middleware
- All tests passing (105 tests total)
2026-01-31 17:49:21 -08:00

371 lines
16 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for All files</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="prettify.css" />
<link rel="stylesheet" href="base.css" />
<link rel="shortcut icon" type="image/x-icon" href="favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type='text/css'>
.coverage-summary .sorter {
background-image: url(sort-arrow-sprite.png);
}
</style>
</head>
<body>
<div class='wrapper'>
<div class='pad1'>
<h1>All files</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/5919</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/4100</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/1183</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/5589</span>
</div>
</div>
<p class="quiet">
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.
</p>
<template id="filterTemplate">
<div class="quiet">
Filter:
<input type="search" id="fileSearch">
</div>
</template>
</div>
<div class='status-line low'></div>
<div class="pad1">
<table class="coverage-summary">
<thead>
<tr>
<th data-col="file" data-fmt="html" data-html="true" class="file">File</th>
<th data-col="pic" data-type="number" data-fmt="html" data-html="true" class="pic"></th>
<th data-col="statements" data-type="number" data-fmt="pct" class="pct">Statements</th>
<th data-col="statements_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="branches" data-type="number" data-fmt="pct" class="pct">Branches</th>
<th data-col="branches_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="functions" data-type="number" data-fmt="pct" class="pct">Functions</th>
<th data-col="functions_raw" data-type="number" data-fmt="html" class="abs"></th>
<th data-col="lines" data-type="number" data-fmt="pct" class="pct">Lines</th>
<th data-col="lines_raw" data-type="number" data-fmt="html" class="abs"></th>
</tr>
</thead>
<tbody><tr>
<td class="file low" data-value="app"><a href="app/index.html">app</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="37" class="abs low">0/37</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="16" class="abs low">0/16</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="10" class="abs low">0/10</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="36" class="abs low">0/36</td>
</tr>
<tr>
<td class="file low" data-value="app/(auth)"><a href="app/(auth)/index.html">app/(auth)</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="587" class="abs low">0/587</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="413" class="abs low">0/413</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="103" class="abs low">0/103</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="574" class="abs low">0/574</td>
</tr>
<tr>
<td class="file low" data-value="app/(tabs)"><a href="app/(tabs)/index.html">app/(tabs)</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="312" class="abs low">0/312</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="247" class="abs low">0/247</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="67" class="abs low">0/67</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="298" class="abs low">0/298</td>
</tr>
<tr>
<td class="file low" data-value="app/(tabs)/beneficiaries"><a href="app/(tabs)/beneficiaries/index.html">app/(tabs)/beneficiaries</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="0" class="abs high">0/0</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1" class="abs low">0/1</td>
</tr>
<tr>
<td class="file low" data-value="app/(tabs)/beneficiaries/[id]"><a href="app/(tabs)/beneficiaries/[id]/index.html">app/(tabs)/beneficiaries/[id]</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1163" class="abs low">0/1163</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="881" class="abs low">0/881</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="210" class="abs low">0/210</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1072" class="abs low">0/1072</td>
</tr>
<tr>
<td class="file low" data-value="app/(tabs)/beneficiaries/[id]/device-settings"><a href="app/(tabs)/beneficiaries/[id]/device-settings/index.html">app/(tabs)/beneficiaries/[id]/device-settings</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="140" class="abs low">0/140</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="116" class="abs low">0/116</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="26" class="abs low">0/26</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="123" class="abs low">0/123</td>
</tr>
<tr>
<td class="file low" data-value="app/(tabs)/profile"><a href="app/(tabs)/profile/index.html">app/(tabs)/profile</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="374" class="abs low">0/374</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="233" class="abs low">0/233</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="115" class="abs low">0/115</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="367" class="abs low">0/367</td>
</tr>
<tr>
<td class="file low" data-value="components"><a href="components/index.html">components</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="307" class="abs low">0/307</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="332" class="abs low">0/332</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="84" class="abs low">0/84</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="282" class="abs low">0/282</td>
</tr>
<tr>
<td class="file low" data-value="components/examples"><a href="components/examples/index.html">components/examples</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="24" class="abs low">0/24</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="24" class="abs low">0/24</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="9" class="abs low">0/9</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="24" class="abs low">0/24</td>
</tr>
<tr>
<td class="file low" data-value="components/layout"><a href="components/layout/index.html">components/layout</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="59" class="abs low">0/59</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="42" class="abs low">0/42</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="10" class="abs low">0/10</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="57" class="abs low">0/57</td>
</tr>
<tr>
<td class="file low" data-value="components/screens/auth-purchase"><a href="components/screens/auth-purchase/index.html">components/screens/auth-purchase</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="115" class="abs low">0/115</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="78" class="abs low">0/78</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="14" class="abs low">0/14</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="115" class="abs low">0/115</td>
</tr>
<tr>
<td class="file low" data-value="components/screens/purchase"><a href="components/screens/purchase/index.html">components/screens/purchase</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="105" class="abs low">0/105</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="78" class="abs low">0/78</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="12" class="abs low">0/12</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="102" class="abs low">0/102</td>
</tr>
<tr>
<td class="file low" data-value="components/screens/subscription"><a href="components/screens/subscription/index.html">components/screens/subscription</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="230" class="abs low">0/230</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="199" class="abs low">0/199</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="39" class="abs low">0/39</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="217" class="abs low">0/217</td>
</tr>
<tr>
<td class="file low" data-value="components/sensors"><a href="components/sensors/index.html">components/sensors</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="33" class="abs low">0/33</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="32" class="abs low">0/32</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="5" class="abs low">0/5</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="33" class="abs low">0/33</td>
</tr>
<tr>
<td class="file low" data-value="components/ui"><a href="components/ui/index.html">components/ui</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="131" class="abs low">0/131</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="147" class="abs low">0/147</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="43" class="abs low">0/43</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="125" class="abs low">0/125</td>
</tr>
<tr>
<td class="file low" data-value="contexts"><a href="contexts/index.html">contexts</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="333" class="abs low">0/333</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="96" class="abs low">0/96</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="78" class="abs low">0/78</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="303" class="abs low">0/303</td>
</tr>
<tr>
<td class="file low" data-value="services"><a href="services/index.html">services</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1408" class="abs low">0/1408</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="851" class="abs low">0/851</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="264" class="abs low">0/264</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="1313" class="abs low">0/1313</td>
</tr>
<tr>
<td class="file low" data-value="services/ble"><a href="services/ble/index.html">services/ble</a></td>
<td data-value="0" class="pic low">
<div class="chart"><div class="cover-fill" style="width: 0%"></div><div class="cover-empty" style="width: 100%"></div></div>
</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="560" class="abs low">0/560</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="315" class="abs low">0/315</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="93" class="abs low">0/93</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="547" class="abs low">0/547</td>
</tr>
</tbody>
</table>
</div>
<div class='push'></div><!-- for sticky footer -->
</div><!-- /wrapper -->
<div class='footer quiet pad2 space-top1 center small'>
Code coverage generated by
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
at 2026-02-01T00:54:53.932Z
</div>
<script src="prettify.js"></script>
<script>
window.onload = function () {
prettyPrint();
};
</script>
<script src="sorter.js"></script>
<script src="block-navigation.js"></script>
</body>
</html>