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

221 lines
8.9 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<title>Code coverage report for app/(tabs)/beneficiaries/[id]</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><a href="../../../../index.html">All files</a> app/(tabs)/beneficiaries/[id]</h1>
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Statements</span>
<span class='fraction'>0/1163</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Branches</span>
<span class='fraction'>0/881</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Functions</span>
<span class='fraction'>0/210</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">0% </span>
<span class="quiet">Lines</span>
<span class='fraction'>0/1072</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="add-sensor.tsx"><a href="add-sensor.tsx.html">add-sensor.tsx</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="71" class="abs low">0/71</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="74" class="abs low">0/74</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="19" class="abs low">0/19</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="62" class="abs low">0/62</td>
</tr>
<tr>
<td class="file low" data-value="equipment-status.tsx"><a href="equipment-status.tsx.html">equipment-status.tsx</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="89" class="abs low">0/89</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="88" class="abs low">0/88</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="13" class="abs low">0/13</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="85" class="abs low">0/85</td>
</tr>
<tr>
<td class="file low" data-value="equipment.tsx"><a href="equipment.tsx.html">equipment.tsx</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="134" class="abs low">0/134</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="74" class="abs low">0/74</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="124" class="abs low">0/124</td>
</tr>
<tr>
<td class="file low" data-value="index.tsx"><a href="index.tsx.html">index.tsx</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="186" class="abs low">0/186</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="168" class="abs low">0/168</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="178" class="abs low">0/178</td>
</tr>
<tr>
<td class="file low" data-value="purchase.tsx"><a href="purchase.tsx.html">purchase.tsx</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="64" class="abs low">0/64</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="50" class="abs low">0/50</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="6" class="abs low">0/6</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="62" class="abs low">0/62</td>
</tr>
<tr>
<td class="file low" data-value="setup-wifi.tsx"><a href="setup-wifi.tsx.html">setup-wifi.tsx</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="298" class="abs low">0/298</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="178" class="abs low">0/178</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="62" class="abs low">0/62</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="258" class="abs low">0/258</td>
</tr>
<tr>
<td class="file low" data-value="share.tsx"><a href="share.tsx.html">share.tsx</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="144" class="abs low">0/144</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="100" class="abs low">0/100</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="25" class="abs low">0/25</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="136" class="abs low">0/136</td>
</tr>
<tr>
<td class="file low" data-value="subscription.tsx"><a href="subscription.tsx.html">subscription.tsx</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="177" class="abs low">0/177</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="149" class="abs low">0/149</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="21" class="abs low">0/21</td>
<td data-value="0" class="pct low">0%</td>
<td data-value="167" class="abs low">0/167</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>