This commit is contained in:
awesome-manuel
2026-04-15 09:52:24 +00:00
parent 0418eddd37
commit 7b687eb56e
44 changed files with 468 additions and 381 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -1,5 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 94.05%">
<title>coverage: 94.05%</title>
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 94.11%">
<title>coverage: 94.11%</title>
<linearGradient id="smooth" x2="0" y2="100%">
<stop offset="0" stop-color="#fff" stop-opacity=".7"/>
<stop offset=".1" stop-color="#aaa" stop-opacity=".1"/>
@@ -17,7 +17,7 @@
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11">
<text x="31" y="15" fill="#010101" fill-opacity=".3">coverage</text>
<text x="31" y="14">coverage</text>
<text x="88" y="15" fill="#010101" fill-opacity=".3">94.05%</text>
<text x="88" y="14">94.05%</text>
<text x="88" y="15" fill="#010101" fill-opacity=".3">94.11%</text>
<text x="88" y="14">94.11%</text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

+3 -3
View File
@@ -1,4 +1,4 @@
{"total": {"lines":{"total":875,"covered":823,"skipped":0,"pct":94.05},"statements":{"total":936,"covered":871,"skipped":0,"pct":93.05},"functions":{"total":289,"covered":258,"skipped":0,"pct":89.27},"branches":{"total":387,"covered":316,"skipped":0,"pct":81.65},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
{"total": {"lines":{"total":884,"covered":832,"skipped":0,"pct":94.11},"statements":{"total":945,"covered":880,"skipped":0,"pct":93.12},"functions":{"total":290,"covered":259,"skipped":0,"pct":89.31},"branches":{"total":389,"covered":318,"skipped":0,"pct":81.74},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/home/runner/work/synapse-admin/synapse-admin/src/App.tsx": {"lines":{"total":8,"covered":8,"skipped":0,"pct":100},"functions":{"total":2,"covered":2,"skipped":0,"pct":100},"statements":{"total":8,"covered":8,"skipped":0,"pct":100},"branches":{"total":4,"covered":2,"skipped":0,"pct":50}}
,"/home/runner/work/synapse-admin/synapse-admin/src/AppContext.tsx": {"lines":{"total":2,"covered":2,"skipped":0,"pct":100},"functions":{"total":1,"covered":1,"skipped":0,"pct":100},"statements":{"total":2,"covered":2,"skipped":0,"pct":100},"branches":{"total":0,"covered":0,"skipped":0,"pct":100}}
,"/home/runner/work/synapse-admin/synapse-admin/src/bootstrap.tsx": {"lines":{"total":25,"covered":25,"skipped":0,"pct":100},"functions":{"total":4,"covered":4,"skipped":0,"pct":100},"statements":{"total":25,"covered":25,"skipped":0,"pct":100},"branches":{"total":14,"covered":11,"skipped":0,"pct":78.57}}
@@ -28,7 +28,7 @@
,"/home/runner/work/synapse-admin/synapse-admin/src/resources/rooms.tsx": {"lines":{"total":26,"covered":26,"skipped":0,"pct":100},"functions":{"total":10,"covered":9,"skipped":0,"pct":90},"statements":{"total":27,"covered":26,"skipped":0,"pct":96.29},"branches":{"total":12,"covered":10,"skipped":0,"pct":83.33}}
,"/home/runner/work/synapse-admin/synapse-admin/src/resources/user_media_statistics.tsx": {"lines":{"total":11,"covered":11,"skipped":0,"pct":100},"functions":{"total":5,"covered":5,"skipped":0,"pct":100},"statements":{"total":12,"covered":12,"skipped":0,"pct":100},"branches":{"total":4,"covered":4,"skipped":0,"pct":100}}
,"/home/runner/work/synapse-admin/synapse-admin/src/resources/users.tsx": {"lines":{"total":30,"covered":30,"skipped":0,"pct":100},"functions":{"total":10,"covered":10,"skipped":0,"pct":100},"statements":{"total":31,"covered":31,"skipped":0,"pct":100},"branches":{"total":8,"covered":7,"skipped":0,"pct":87.5}}
,"/home/runner/work/synapse-admin/synapse-admin/src/synapse/authProvider.ts": {"lines":{"total":29,"covered":28,"skipped":0,"pct":96.55},"functions":{"total":9,"covered":9,"skipped":0,"pct":100},"statements":{"total":32,"covered":30,"skipped":0,"pct":93.75},"branches":{"total":20,"covered":17,"skipped":0,"pct":85}}
,"/home/runner/work/synapse-admin/synapse-admin/src/synapse/authProvider.ts": {"lines":{"total":37,"covered":36,"skipped":0,"pct":97.29},"functions":{"total":10,"covered":10,"skipped":0,"pct":100},"statements":{"total":40,"covered":38,"skipped":0,"pct":95},"branches":{"total":22,"covered":19,"skipped":0,"pct":86.36}}
,"/home/runner/work/synapse-admin/synapse-admin/src/synapse/dataProvider.ts": {"lines":{"total":188,"covered":171,"skipped":0,"pct":90.95},"functions":{"total":97,"covered":81,"skipped":0,"pct":83.5},"statements":{"total":197,"covered":180,"skipped":0,"pct":91.37},"branches":{"total":52,"covered":48,"skipped":0,"pct":92.3}}
,"/home/runner/work/synapse-admin/synapse-admin/src/synapse/synapse.ts": {"lines":{"total":65,"covered":63,"skipped":0,"pct":96.92},"functions":{"total":24,"covered":24,"skipped":0,"pct":100},"statements":{"total":71,"covered":69,"skipped":0,"pct":97.18},"branches":{"total":26,"covered":22,"skipped":0,"pct":84.61}}
,"/home/runner/work/synapse-admin/synapse-admin/src/synapse/synapse.ts": {"lines":{"total":66,"covered":64,"skipped":0,"pct":96.96},"functions":{"total":24,"covered":24,"skipped":0,"pct":100},"statements":{"total":72,"covered":70,"skipped":0,"pct":97.22},"branches":{"total":26,"covered":22,"skipped":0,"pct":84.61}}
}
+18 -18
View File
@@ -23,30 +23,30 @@
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">93.05% </span>
<span class="strong">93.12% </span>
<span class="quiet">Statements</span>
<span class='fraction'>871/936</span>
<span class='fraction'>880/945</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">81.65% </span>
<span class="strong">81.74% </span>
<span class="quiet">Branches</span>
<span class='fraction'>316/387</span>
<span class='fraction'>318/389</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">89.27% </span>
<span class="strong">89.31% </span>
<span class="quiet">Functions</span>
<span class='fraction'>258/289</span>
<span class='fraction'>259/290</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">94.05% </span>
<span class="strong">94.11% </span>
<span class="quiet">Lines</span>
<span class='fraction'>823/875</span>
<span class='fraction'>832/884</span>
</div>
@@ -155,17 +155,17 @@
<tr>
<td class="file high" data-value="src/synapse"><a href="src/synapse/index.html">src/synapse</a></td>
<td data-value="93" class="pic high">
<td data-value="93.2" class="pic high">
<div class="chart"><div class="cover-fill" style="width: 93%"></div><div class="cover-empty" style="width: 7%"></div></div>
</td>
<td data-value="93" class="pct high">93%</td>
<td data-value="300" class="abs high">279/300</td>
<td data-value="88.77" class="pct high">88.77%</td>
<td data-value="98" class="abs high">87/98</td>
<td data-value="87.69" class="pct high">87.69%</td>
<td data-value="130" class="abs high">114/130</td>
<td data-value="92.9" class="pct high">92.9%</td>
<td data-value="282" class="abs high">262/282</td>
<td data-value="93.2" class="pct high">93.2%</td>
<td data-value="309" class="abs high">288/309</td>
<td data-value="89" class="pct high">89%</td>
<td data-value="100" class="abs high">89/100</td>
<td data-value="87.78" class="pct high">87.78%</td>
<td data-value="131" class="abs high">115/131</td>
<td data-value="93.12" class="pct high">93.12%</td>
<td data-value="291" class="abs high">271/291</td>
</tr>
</tbody>
@@ -176,7 +176,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="prettify.js"></script>
<script>
+1 -1
View File
@@ -355,7 +355,7 @@ export default App;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../prettify.js"></script>
<script>
+1 -1
View File
@@ -97,7 +97,7 @@ export const useAppContext = () =&gt; useContext(AppContext) as AppContextType;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../prettify.js"></script>
<script>
+1 -1
View File
@@ -265,7 +265,7 @@ export const Bootstrap = () =&gt; {
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../prettify.js"></script>
<script>
+1 -1
View File
@@ -109,7 +109,7 @@ export default AvatarField;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
@@ -1672,7 +1672,7 @@ export const ImportFeature = FilePicker;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
@@ -463,7 +463,7 @@ export const ServerNoticeBulkButton = () =&gt; {
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -166,7 +166,7 @@ export const dateFormatter = (v: string | number | Date | undefined | null): str
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -133,7 +133,7 @@ export const DeviceRemoveButton = (props: DeleteWithConfirmButtonProps) =&gt; {
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -176,7 +176,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1162,7 +1162,7 @@ export const MXCField = ({ source }) =&gt; {
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
@@ -700,7 +700,7 @@ export default baseChineseMessages;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -733,7 +733,7 @@ export default baseGermanMessages;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1279,7 +1279,7 @@ export default de;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1252,7 +1252,7 @@ export default en;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1198,7 +1198,7 @@ export default fa;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1174,7 +1174,7 @@ export default fr;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1246,7 +1246,7 @@ interface SynapseTranslationMessages extends TranslationMessages {
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -236,7 +236,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1201,7 +1201,7 @@ export default it;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1312,7 +1312,7 @@ export default ru;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -913,7 +913,7 @@ export default zh;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -161,7 +161,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../prettify.js"></script>
<script>
+1 -1
View File
@@ -121,7 +121,7 @@ createRoot(rootElement).render(
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../prettify.js"></script>
<script>
+1 -1
View File
@@ -1024,7 +1024,7 @@ export default LoginPage;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -101,7 +101,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -640,7 +640,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -191,7 +191,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
@@ -364,7 +364,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -409,7 +409,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
@@ -595,7 +595,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -847,7 +847,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
@@ -259,7 +259,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -1102,7 +1102,7 @@ export default resource;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -79,7 +79,7 @@ export default storage;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../prettify.js"></script>
<script>
+137 -53
View File
@@ -23,30 +23,30 @@
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">93.75% </span>
<span class="strong">95% </span>
<span class="quiet">Statements</span>
<span class='fraction'>30/32</span>
<span class='fraction'>38/40</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">85% </span>
<span class="strong">86.36% </span>
<span class="quiet">Branches</span>
<span class='fraction'>17/20</span>
<span class='fraction'>19/22</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">100% </span>
<span class="quiet">Functions</span>
<span class='fraction'>9/9</span>
<span class='fraction'>10/10</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">96.55% </span>
<span class="strong">97.29% </span>
<span class="quiet">Lines</span>
<span class='fraction'>28/29</span>
<span class='fraction'>36/37</span>
</div>
@@ -171,7 +171,35 @@
<a name='L106'></a><a href='#L106'>106</a>
<a name='L107'></a><a href='#L107'>107</a>
<a name='L108'></a><a href='#L108'>108</a>
<a name='L109'></a><a href='#L109'>109</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<a name='L109'></a><a href='#L109'>109</a>
<a name='L110'></a><a href='#L110'>110</a>
<a name='L111'></a><a href='#L111'>111</a>
<a name='L112'></a><a href='#L112'>112</a>
<a name='L113'></a><a href='#L113'>113</a>
<a name='L114'></a><a href='#L114'>114</a>
<a name='L115'></a><a href='#L115'>115</a>
<a name='L116'></a><a href='#L116'>116</a>
<a name='L117'></a><a href='#L117'>117</a>
<a name='L118'></a><a href='#L118'>118</a>
<a name='L119'></a><a href='#L119'>119</a>
<a name='L120'></a><a href='#L120'>120</a>
<a name='L121'></a><a href='#L121'>121</a>
<a name='L122'></a><a href='#L122'>122</a>
<a name='L123'></a><a href='#L123'>123</a>
<a name='L124'></a><a href='#L124'>124</a>
<a name='L125'></a><a href='#L125'>125</a>
<a name='L126'></a><a href='#L126'>126</a>
<a name='L127'></a><a href='#L127'>127</a>
<a name='L128'></a><a href='#L128'>128</a>
<a name='L129'></a><a href='#L129'>129</a>
<a name='L130'></a><a href='#L130'>130</a>
<a name='L131'></a><a href='#L131'>131</a>
<a name='L132'></a><a href='#L132'>132</a>
<a name='L133'></a><a href='#L133'>133</a>
<a name='L134'></a><a href='#L134'>134</a>
<a name='L135'></a><a href='#L135'>135</a>
<a name='L136'></a><a href='#L136'>136</a>
<a name='L137'></a><a href='#L137'>137</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -207,9 +235,7 @@
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">9x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -233,19 +259,48 @@
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">1x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">6x</span>
<span class="cline-any cline-yes">6x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">6x</span>
<span class="cline-any cline-yes">6x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">6x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-yes">4x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -264,6 +319,7 @@
<span class="cline-any cline-no">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">3x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">2x</span>
@@ -308,48 +364,75 @@ const getStoredIdentity = () =&gt; {
};
};
&nbsp;
/** Build the login request body for a given device_id and credential set. */
const buildLoginBody = (
deviceId: string | null,
loginToken: string | null | undefined,
username: string | null | undefined,
password: string | null | undefined
): string =&gt;
JSON.stringify(
Object.assign(
{
device_id: deviceId,
initial_device_display_name: "Synapse Admin",
},
loginToken
? {
type: "m.login.token",
token: loginToken,
}
: {
type: "m.login.password",
user: username,
password: password,
identifier: {
type: "m.id.user",
user: username,
},
}
)
);
&nbsp;
/** React-admin auth provider backed by Synapse password login and token-based SSO callbacks. */
const authProvider: AuthProvider = {
/** Exchange credentials for an access token and persist the resulting session locally. */
login: async ({
base_url,
username,
password,
loginToken,
}: LoginParams) =&gt; {
const options: Options = {
method: "POST",
body: JSON.stringify(
Object.assign(
{
device_id: storage.getItem("device_id"),
initial_device_display_name: "Synapse Admin",
},
loginToken
? {
type: "m.login.token",
token: loginToken,
}
: {
type: "m.login.password",
user: username,
password: password,
identifier: {
type: "m.id.user",
user: username,
},
}
)
),
};
&nbsp;
login: async ({ base_url, username, password, loginToken }: LoginParams) =&gt; {
// use the base_url from login instead of the well_known entry from the
// server, since the admin might want to access the admin API via some
// private address
const normalizedBaseUrl = normalizeBaseUrl(base_url);
storage.setItem("base_url", normalizedBaseUrl);
&nbsp;
const { json } = await fetchJson(buildUrl(normalizedBaseUrl, "/_matrix/client/r0/login"), options);
const loginUrl = buildUrl(normalizedBaseUrl, "/_matrix/client/r0/login");
const storedDeviceId = storage.getItem("device_id");
&nbsp;
let json: Record&lt;string, string&gt;;
&nbsp;
// When a stored device_id exists, the server may reject the login if the
// device was externally revoked (e.g. via Element "Remove Device"). In
// that case, retry without the stale device_id so the server assigns a
// fresh one. See https://github.com/Awesome-Technologies/synapse-admin/issues/757
if (storedDeviceId) {
try {
({ json } = await fetchJson(loginUrl, {
method: "POST",
body: buildLoginBody(storedDeviceId, loginToken, username, password),
}));
} catch {
storage.removeItem("device_id");
({ json } = await fetchJson(loginUrl, {
method: "POST",
body: buildLoginBody(null, loginToken, username, password),
}));
}
} else {
({ json } = await fetchJson(loginUrl, {
method: "POST",
body: buildLoginBody(null, loginToken, username, password),
}));
}
&nbsp;
storage.setItem("home_server", json.home_server);
storage.setItem("user_id", json.user_id);
storage.setItem("access_token", json.access_token);
@@ -372,7 +455,8 @@ const authProvider: AuthProvider = {
<span class="cstat-no" title="statement not covered" > clearStoredAuth();</span>
},
/** Treat 401/403 responses as an expired or invalid session. */
checkError: ({ status }: { status: number }) =&gt; ((status === 401 || status === 403) ? Promise.reject() : Promise.resolve()),
checkError: ({ status }: { status: number }) =&gt;
status === 401 || status === 403 ? Promise.reject() : Promise.resolve(),
/** Guard protected routes by checking whether a session token is cached locally. */
checkAuth: async () =&gt; (hasAccessToken() ? Promise.resolve() : Promise.reject()),
/** Synapse Admin currently does not model separate permission payloads. */
@@ -394,7 +478,7 @@ export default authProvider;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -2611,7 +2611,7 @@ export default dataProvider;
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+23 -23
View File
@@ -23,30 +23,30 @@
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">93% </span>
<span class="strong">93.2% </span>
<span class="quiet">Statements</span>
<span class='fraction'>279/300</span>
<span class='fraction'>288/309</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">88.77% </span>
<span class="strong">89% </span>
<span class="quiet">Branches</span>
<span class='fraction'>87/98</span>
<span class='fraction'>89/100</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">87.69% </span>
<span class="strong">87.78% </span>
<span class="quiet">Functions</span>
<span class='fraction'>114/130</span>
<span class='fraction'>115/131</span>
</div>
<div class='fl pad1y space-right2'>
<span class="strong">92.9% </span>
<span class="strong">93.12% </span>
<span class="quiet">Lines</span>
<span class='fraction'>262/282</span>
<span class='fraction'>271/291</span>
</div>
@@ -80,17 +80,17 @@
</thead>
<tbody><tr>
<td class="file high" data-value="authProvider.ts"><a href="authProvider.ts.html">authProvider.ts</a></td>
<td data-value="93.75" class="pic high">
<div class="chart"><div class="cover-fill" style="width: 93%"></div><div class="cover-empty" style="width: 7%"></div></div>
<td data-value="95" class="pic high">
<div class="chart"><div class="cover-fill" style="width: 95%"></div><div class="cover-empty" style="width: 5%"></div></div>
</td>
<td data-value="93.75" class="pct high">93.75%</td>
<td data-value="32" class="abs high">30/32</td>
<td data-value="85" class="pct high">85%</td>
<td data-value="20" class="abs high">17/20</td>
<td data-value="95" class="pct high">95%</td>
<td data-value="40" class="abs high">38/40</td>
<td data-value="86.36" class="pct high">86.36%</td>
<td data-value="22" class="abs high">19/22</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="9" class="abs high">9/9</td>
<td data-value="96.55" class="pct high">96.55%</td>
<td data-value="29" class="abs high">28/29</td>
<td data-value="10" class="abs high">10/10</td>
<td data-value="97.29" class="pct high">97.29%</td>
<td data-value="37" class="abs high">36/37</td>
</tr>
<tr>
@@ -110,17 +110,17 @@
<tr>
<td class="file high" data-value="synapse.ts"><a href="synapse.ts.html">synapse.ts</a></td>
<td data-value="97.18" class="pic high">
<td data-value="97.22" class="pic high">
<div class="chart"><div class="cover-fill" style="width: 97%"></div><div class="cover-empty" style="width: 3%"></div></div>
</td>
<td data-value="97.18" class="pct high">97.18%</td>
<td data-value="71" class="abs high">69/71</td>
<td data-value="97.22" class="pct high">97.22%</td>
<td data-value="72" class="abs high">70/72</td>
<td data-value="84.61" class="pct high">84.61%</td>
<td data-value="26" class="abs high">22/26</td>
<td data-value="100" class="pct high">100%</td>
<td data-value="24" class="abs high">24/24</td>
<td data-value="96.92" class="pct high">96.92%</td>
<td data-value="65" class="abs high">63/65</td>
<td data-value="96.96" class="pct high">96.96%</td>
<td data-value="66" class="abs high">64/66</td>
</tr>
</tbody>
@@ -131,7 +131,7 @@
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+12 -9
View File
@@ -23,9 +23,9 @@
<div class='clearfix'>
<div class='fl pad1y space-right2'>
<span class="strong">97.18% </span>
<span class="strong">97.22% </span>
<span class="quiet">Statements</span>
<span class='fraction'>69/71</span>
<span class='fraction'>70/72</span>
</div>
@@ -44,9 +44,9 @@
<div class='fl pad1y space-right2'>
<span class="strong">96.92% </span>
<span class="strong">96.96% </span>
<span class="quiet">Lines</span>
<span class='fraction'>63/65</span>
<span class='fraction'>64/66</span>
</div>
@@ -259,7 +259,8 @@
<a name='L194'></a><a href='#L194'>194</a>
<a name='L195'></a><a href='#L195'>195</a>
<a name='L196'></a><a href='#L196'>196</a>
<a name='L197'></a><a href='#L197'>197</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<a name='L197'></a><a href='#L197'>197</a>
<a name='L198'></a><a href='#L198'>198</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -311,10 +312,10 @@
<span class="cline-any cline-yes">14x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">56x</span>
<span class="cline-any cline-yes">64x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">53x</span>
<span class="cline-any cline-yes">57x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">7x</span>
@@ -335,7 +336,7 @@
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">48x</span>
<span class="cline-any cline-yes">55x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">39x</span>
@@ -430,6 +431,7 @@
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-yes">7x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-yes">2x</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
<span class="cline-any cline-neutral">&nbsp;</span>
@@ -626,6 +628,7 @@ export const fetchJsonWithoutAuth = (baseUrl: string, endpoint: string, options:
/** Clear credentials that should not survive logout or failed auth recovery. */
export const clearStoredAuth = (): void =&gt; {
storage.removeItem("access_token");
storage.removeItem("device_id");
};
&nbsp;
/**
@@ -658,7 +661,7 @@ export function generateRandomPassword(length = 20): string {
<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-03-23T19:48:32.137Z
at 2026-04-15T09:52:20.033Z
</div>
<script src="../../prettify.js"></script>
<script>
+1 -1
View File
@@ -111,7 +111,7 @@
}
}
</style>
<script type="module" crossorigin src="/synapse-admin/assets/index-DyMNSlr3.js"></script>
<script type="module" crossorigin src="/synapse-admin/assets/index-Dvgg_4ob.js"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>