Skip to content

Commit 342efe5

Browse files
authored
Merge pull request #5 from xskcdf/development
Add fixes for security warnings
2 parents 68c0556 + 52d3fc9 commit 342efe5

3 files changed

Lines changed: 41 additions & 18 deletions

File tree

‎4-Nine/Features/Administration/Users/View.razor‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,16 @@ else if (viewedUser == null)
4242
else if (!canViewUser)
4343
{
4444
<div class="alert alert-danger">
45-
<h4>Access Denied</h4>
46-
<p>You don't have permission to view this user's account.</p>
45+
@if (!string.IsNullOrEmpty(errorMessage))
46+
{
47+
<h4>Unable to Load User</h4>
48+
<p>@errorMessage</p>
49+
}
50+
else
51+
{
52+
<h4>Access Denied</h4>
53+
<p>You don't have permission to view this user's account.</p>
54+
}
4755
<a href="/admin/users" class="btn btn-primary">Back to User Management</a>
4856
</div>
4957
}
@@ -327,9 +335,15 @@ else
327335

328336
// Check permissions
329337
var currentOrgId = await UserContext.GetActiveOrganizationIdAsync();
330-
var currentUserRole = await OrganizationService.GetUserRoleForOrganizationAsync(currentUser.Id, currentOrgId.Value);
331-
isCurrentUserAdmin = currentUserRole == ApplicationConstants.OrganizationRoles.Owner ||
332-
currentUserRole == ApplicationConstants.OrganizationRoles.Administrator;
338+
if (!currentOrgId.HasValue)
339+
{
340+
errorMessage = "Unable to determine current organization context.";
341+
return;
342+
}
343+
344+
var actingUserRole = await OrganizationService.GetUserRoleForOrganizationAsync(currentUser.Id, currentOrgId.Value);
345+
isCurrentUserAdmin = actingUserRole == ApplicationConstants.OrganizationRoles.Owner ||
346+
actingUserRole == ApplicationConstants.OrganizationRoles.Administrator;
333347
isViewingOwnAccount = currentUser.Id == viewedUser.Id;
334348

335349
// Users can view their own account, admins can view any account in the same org
@@ -342,8 +356,8 @@ else
342356
// Load user's organization role
343357
var viewedUserRole = await OrganizationService.GetUserRoleForOrganizationAsync(viewedUser.Id, currentOrgId.Value);
344358
userRoles = viewedUserRole != null ? new List<string> { viewedUserRole } : new List<string>();
345-
currentUserRole = viewedUserRole ?? "No Role";
346-
selectedRole = currentUserRole;
359+
currentUserRole = viewedUserRole ?? "No role found";
360+
selectedRole = viewedUserRole ?? string.Empty;
347361
isLockedOut = await UserManager.IsLockedOutAsync(viewedUser);
348362

349363
// Load available roles for admins

‎4-Nine/Nine.csproj‎

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.1" />
7575
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlcipher" Version="2.1.11" />
7676
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="10.0.1" />
77+
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="9.0.21" />
7778
<PackageReference Include="QuestPDF" Version="2025.12.1" />
7879
</ItemGroup>
7980

@@ -103,7 +104,9 @@
103104
Linux/macOS: npm's allow-scripts policy and extract-zip failures prevent automatic download,
104105
so the cache (~/.cache/electron) is used directly via unzip.
105106
106-
Windows: PowerShell Expand-Archive extracts from %LOCALAPPDATA%\electron\Cache.
107+
Windows: the zip is located with an item glob in %LOCALAPPDATA%\electron\Cache and extracted
108+
with MSBuild's Unzip task. PowerShell is avoided because a Windows PowerShell 5.1 child
109+
process can inherit a PowerShell 7 PSModulePath and fail in Expand-Archive.
107110
108111
First-time setup (no cache): the build emits a warning with exact steps to seed the cache.
109112
-->
@@ -136,13 +139,16 @@
136139
<Output TaskParameter="ConsoleOutput" PropertyName="_ElectronZipPath" />
137140
</Exec>
138141

139-
<!-- Locate zip in cache (Windows) -->
140-
<Exec Command="powershell -NoProfile -Command &quot;(Get-ChildItem -Path '$(_ElectronCacheDir)' -Filter '$(_ElectronZipName)' -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1).FullName&quot;"
141-
ConsoleToMSBuild="true"
142-
EchoOff="true"
143-
Condition="!Exists('$(_ElectronBinaryPath)') And $([MSBuild]::IsOSPlatform('Windows'))">
144-
<Output TaskParameter="ConsoleOutput" PropertyName="_ElectronZipPath" />
145-
</Exec>
142+
<!-- Locate zip in cache (Windows) with an item glob; no shell involved -->
143+
<ItemGroup Condition="!Exists('$(_ElectronBinaryPath)') And $([MSBuild]::IsOSPlatform('Windows'))">
144+
<_ElectronZipCandidate Include="$(_ElectronCacheDir)\**\$(_ElectronZipName)" />
145+
</ItemGroup>
146+
147+
<!-- Keep only the first match; the cache can hold the same zip in several folders -->
148+
<PropertyGroup Condition="!Exists('$(_ElectronBinaryPath)') And $([MSBuild]::IsOSPlatform('Windows'))">
149+
<_ElectronZipPath>@(_ElectronZipCandidate)</_ElectronZipPath>
150+
<_ElectronZipPath Condition="$(_ElectronZipPath.Contains(';'))">$(_ElectronZipPath.Substring(0, $(_ElectronZipPath.IndexOf(';'))))</_ElectronZipPath>
151+
</PropertyGroup>
146152

147153
<Message Text="[ElectronRestore] Binary missing — restoring from cache: $(_ElectronZipPath)"
148154
Importance="high"
@@ -152,9 +158,11 @@
152158
<Exec Command="rm -rf &quot;$(_ElectronDistPath)&quot; &amp;&amp; unzip -q &quot;$(_ElectronZipPath)&quot; -d &quot;$(_ElectronDistPath)&quot; &amp;&amp; chmod -R a+x &quot;$(_ElectronDistPath)&quot;"
153159
Condition="!Exists('$(_ElectronBinaryPath)') And '$(_ElectronZipPath)' != '' And $([MSBuild]::IsOSPlatform('Linux'))" />
154160

155-
<!-- Extract (Windows) -->
156-
<Exec Command="powershell -NoProfile -Command &quot;if (Test-Path '$(_ElectronDistPath)') { Remove-Item -Path '$(_ElectronDistPath)' -Recurse -Force }; Expand-Archive -Path '$(_ElectronZipPath)' -DestinationPath '$(_ElectronDistPath)' -Force&quot;"
157-
Condition="!Exists('$(_ElectronBinaryPath)') And '$(_ElectronZipPath)' != '' And $([MSBuild]::IsOSPlatform('Windows'))" />
161+
<!-- Extract (Windows) — overwrites any partial dist without deleting it first -->
162+
<Unzip SourceFiles="$(_ElectronZipPath)"
163+
DestinationFolder="$(_ElectronDistPath)"
164+
OverwriteReadOnlyFiles="true"
165+
Condition="!Exists('$(_ElectronBinaryPath)') And '$(_ElectronZipPath)' != '' And $([MSBuild]::IsOSPlatform('Windows'))" />
158166

159167
<!--
160168
No cache found — first-time setup. Instruct the developer to run npm install once

‎6-Tests/Nine.Shared.UI.Tests/Nine.Shared.UI.Tests.csproj‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11+
<PackageReference Include="AngleSharp" Version="1.5.0" />
1112
<PackageReference Include="bunit" Version="2.7.2" />
1213
<PackageReference Include="coverlet.collector" Version="6.0.4" />
1314
<PackageReference Include="FluentAssertions" Version="8.8.0" />

0 commit comments

Comments
 (0)