Skip to content

Commit d358568

Browse files
authored
Merge pull request #1322 from Blazam-App/v1-Nightly
v1.5.0 Update
2 parents 18ef827 + 48358b2 commit d358568

File tree

5,910 files changed

+424666
-1660
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

5,910 files changed

+424666
-1660
lines changed

.github/workflows/deploy-demo.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ jobs:
3232
New-Item -Path C:\inetpub\wwwroot -Name "app_offline.htm" -ItemType "file" -ErrorAction Continue
3333
3434
- name: dotnet publish
35-
run: dotnet publish -c Release -o C:\inetpub\wwwroot BLAZAM/BLAZAM.csproj
35+
run: dotnet publish -c Release -o C:\inetpub\demo.blazam.org BLAZAM/BLAZAM.csproj
3636

3737
- name: Restart Demo Website
3838
shell: pwsh

BLAZAM.Tests/Gui/DirectoryTemplateTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,31 @@ public void ShouldHandleLengthGreaterThanValueLength()
240240
// Current implementation returns full string if length is greater than value length
241241
Assert.Equal("John", result);
242242
}
243+
[Fact]
244+
public void ShouldRemoveDiacritics()
245+
{
246+
var userWithDiacritics = new NewUserName
247+
{
248+
GivenName = "Jöhn",
249+
Surname = "Döe"
250+
};
251+
252+
var result = _template.ReplaceVariables("{fn:d}{ln:d}", userWithDiacritics);
253+
Assert.Equal("JohnDoe", result);
254+
}
255+
256+
[Fact]
257+
public void ShouldChainModifiers()
258+
{
259+
var userWithDiacritics = new NewUserName
260+
{
261+
GivenName = "Jöhn",
262+
Surname = "Döe"
263+
};
264+
265+
var result = _template.ReplaceVariables("{fn:du}", userWithDiacritics);
266+
Assert.Equal("JOHN", result);
267+
}
243268
}
244269

245270

BLAZAM.Tests/Mocks/MockApplicationUserState.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public class MockApplicationUserState : IApplicationUserState
7070
public bool ShowPluginPlaceholders { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
7171
public AppEvent OnSettingsChanged { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
7272
public AppEvent OnReadNewsSaved { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
73+
private string? _browser="Google Chrome";
74+
public string? Browser { get => _browser; set => _browser=value; }
7375

7476
public bool CanSearchDisabled(ActiveDirectoryObjectType objectType)
7577
{

BLAZAM.Tests/Session/SessionTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ public void MFARequest_Constructor_ShouldSetPropertiesCorrectly()
196196
var mfaRequest = new MFARequest(MfaType.CiscoDuo, expectedToken, expectedRedirectUrl, mockUser.Object);
197197

198198
// Assert
199-
Assert.Equal(expectedToken, mfaRequest.mfaToken);
200-
Assert.Equal(expectedRedirectUrl, mfaRequest.redirectUrl);
201-
Assert.Same(mockUser.Object, mfaRequest.user); // Check reference equality for the user object
199+
Assert.Equal(expectedToken, mfaRequest.MfaToken);
200+
Assert.Equal(expectedRedirectUrl, mfaRequest.RedirectUrl);
201+
Assert.Same(mockUser.Object, mfaRequest.User); // Check reference equality for the user object
202202
}
203203

204204
[Theory]
@@ -305,7 +305,7 @@ public void MFARequest_GetHashCode_ShouldLikelyBeDifferentForDifferentTokens()
305305
// Act & Assert
306306
// Note: Hash code collisions are possible but unlikely for simple string differences.
307307
// This test primarily checks that the hash code isn't a constant.
308-
if (requestA.mfaToken != requestB.mfaToken) // Ensure tokens are actually different
308+
if (requestA.MfaToken != requestB.MfaToken) // Ensure tokens are actually different
309309
{
310310
Assert.NotEqual(requestA.GetHashCode(), requestB.GetHashCode());
311311
}

BLAZAM/App.razor

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,7 @@
1919
<NotAuthorized>
2020
@if (context.User.Identity?.IsAuthenticated != true)
2121
{
22-
<LayoutView Layout="@typeof(LoginLayout)">
2322
<Login />
24-
</LayoutView>
2523
}
2624
else
2725
{

BLAZAM/BLAZAM.csproj

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<Nullable>enable</Nullable>
66
<ImplicitUsings>enable</ImplicitUsings>
77
<ServerGarbageCollection>false</ServerGarbageCollection>
8-
<AssemblyVersion>1.4.12</AssemblyVersion>
9-
<Version>2025.11.19.1604</Version>
8+
<AssemblyVersion>1.5.0</AssemblyVersion>
9+
<Version>2026.01.03.0043</Version>
1010
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
1111
<RootNamespace>BLAZAM</RootNamespace>
1212
<GenerateDocumentationFile>True</GenerateDocumentationFile>
@@ -24,6 +24,10 @@
2424
<None Remove="nssm.exe" />
2525
</ItemGroup>
2626

27+
<ItemGroup>
28+
<Compile Include="..\BLAZAMGui\UI\Inputs\ADAutoComplete.razor.cs" Link="ADAutoComplete.razor.cs" />
29+
</ItemGroup>
30+
2731

2832

2933

BLAZAM/Middleware/UserStateMiddleware.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,14 @@ public Task Invoke(HttpContext httpContext, ICurrentUserStateService currentUser
4747

4848

4949
currentUserStateService.State.IPAddress = httpContext.Connection.RemoteIpAddress.ToString();
50+
5051

5152
}
53+
if (currentUserStateService.State != null
54+
&& httpContext.Request.Headers.TryGetValue("User-Agent", out var userAgent))
55+
{
56+
currentUserStateService.State.Browser = userAgent.ToString();
57+
}
5258
}
5359

5460
return _next(httpContext);

BLAZAM/Pages/API/v1/ApiControllerBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ protected IActionResult FormatData(object data)
132132
/// <exception cref="DirectorySearchUniquenessException"></exception>
133133
protected IADGroup? FindGroupByIdentifier(string groupIdentifier)
134134
{
135-
var group = (IADGroup?)Directory.FindEntryBySid(groupIdentifier);
135+
var group = (IADGroup?)Directory.FindGlobalEntryBySid(groupIdentifier);
136136
group ??= (IADGroup?)Directory.GetDirectoryEntryByDN(groupIdentifier);
137137
if (group == null)
138138
{

BLAZAM/Pages/Audit.razor

Lines changed: 5 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
@page "/audit"
22
@page "/audit/{ActiveTab}"
3-
@using BLAZAM.Database.Models.Audit;
4-
@using BLAZAM.Global.Data
3+
4+
55

66

77
@attribute [Authorize(Roles = UserRoles.SuperAdmin)]
@@ -23,71 +23,7 @@
2323
<MudTabs @bind-ActivePanelIndex="@ActiveTab">
2424
<MudTabPanel>
2525
<ChildContent>
26-
<MudDataGrid Virtualize=true
27-
Height="600px"
28-
ColumnResizeMode="ResizeMode.Container"
29-
FixedHeader=true
30-
Hideable=true
31-
Items="@auditEntries.Where(ae => ae.Action != "Login" && ae.Action != "Logout").OrderByDescending(ae => ae.Timestamp)"
32-
Filterable="false"
33-
SortMode="@SortMode.Multiple"
34-
Groupable="false">
35-
<Columns>
36-
<PropertyColumn Property="x=>x.Timestamp" Title=@AppLocalization[Lang.Timestamp] Sortable="true">
37-
<CellTemplate>
38-
<MudText>
39-
@context.Item.Timestamp.ToLocalTime()
40-
</MudText>
41-
</CellTemplate>
42-
</PropertyColumn>
43-
<PropertyColumn Property="x => x.Username" Filterable="true" Title="@AppLocalization[Lang.Username]" />
44-
@if (!ApplicationInfo.InDemoMode)
45-
{
46-
<PropertyColumn Property="x => x.IpAddress" Title=@AppLocalization[Lang.IP_Address]
47-
Filterable="true">
48-
<CellTemplate>
49-
<IPAddress>
50-
@context.Item.IpAddress
51-
</IPAddress>
52-
</CellTemplate>
53-
</PropertyColumn>
54-
}
55-
else
56-
{
57-
<TemplateColumn Title=@AppLocalization[Lang.IP_Address]>
58-
<CellTemplate>
59-
<IPAddress>
60-
@context.Item.IpAddress
61-
</IPAddress>
62-
</CellTemplate>
63-
</TemplateColumn>
64-
}
65-
<PropertyColumn Property="x => x.Action"
66-
Filterable=true
67-
Title="@AppLocalization[Lang.Action]">
68-
<CellTemplate>
69-
<MudText>@AppLocalization[context.Item.Action]</MudText>
70-
</CellTemplate>
71-
</PropertyColumn>
72-
73-
<PropertyColumn Property="x => x.Target"
74-
Filterable=true
75-
Title="@AppLocalization[Lang.Target]">
76-
<CellTemplate>
77-
<MudLink Href="@("/view/" + context.Item.Target)">@context.Item.Target</MudLink>
78-
</CellTemplate>
79-
</PropertyColumn>
80-
81-
<PropertyColumn Property="x => x.BeforeAction"
82-
Filterable="true"
83-
Title="@AppLocalization[Lang.Before_Action]" />
84-
85-
<PropertyColumn Property="x => x.AfterAction"
86-
Filterable="true"
87-
Title="@AppLocalization[Lang.After_Action]" />
88-
89-
</Columns>
90-
</MudDataGrid>
26+
<MainAuditContent />
9127

9228

9329

@@ -99,43 +35,7 @@
9935
</MudTabPanel>
10036
<MudTabPanel>
10137
<ChildContent>
102-
<LoginHistoryChart />
103-
104-
105-
<MudDataGrid Virtualize=true
106-
Height="600px"
107-
FixedHeader=true
108-
ColumnResizeMode="ResizeMode.Container"
109-
Hideable=true
110-
Items="@logonEntries.OrderByDescending(ae => ae.Timestamp)"
111-
Filterable="false"
112-
SortMode="@SortMode.Multiple"
113-
Groupable="false">
114-
<Columns>
115-
<TemplateColumn Title=@AppLocalization[Lang.Timestamp] Sortable="true">
116-
<CellTemplate>
117-
<MudText>
118-
@context.Item.Timestamp.ToLocalTime()
119-
</MudText>
120-
</CellTemplate>
121-
</TemplateColumn>
122-
123-
<PropertyColumn Property="x => x.Username" Title="@AppLocalization[Lang.Username]" />
124-
125-
<TemplateColumn Title=@AppLocalization[Lang.IP_Address] Filterable="true">
126-
<CellTemplate>
127-
<IPAddress>
128-
@context.Item.IpAddress
129-
</IPAddress>
130-
</CellTemplate>
131-
</TemplateColumn>
132-
133-
<PropertyColumn Property="x => x.Action" Title="@AppLocalization[Lang.Action]" />
134-
135-
</Columns>
136-
</MudDataGrid>
137-
138-
38+
<LoginAuditContent />
13939

14040

14141
</ChildContent>
@@ -145,41 +45,7 @@
14545
</MudTabPanel>
14646
<MudTabPanel>
14747
<ChildContent>
148-
@if (ApplicationInfo.InDemoMode && CurrentUser.Username == "Demo")
149-
{
150-
<MudText>Disabled in demo</MudText>
151-
}
152-
else
153-
{
154-
<MudDataGrid Virtualize=true
155-
Height="600px"
156-
ColumnResizeMode="ResizeMode.Container"
157-
FixedHeader=true
158-
Hideable=true
159-
Items="@systemAuditEntries.OrderByDescending(ae => ae.Timestamp)"
160-
Filterable="false"
161-
SortMode="@SortMode.Multiple"
162-
Groupable="false">
163-
<Columns>
164-
<TemplateColumn Title=@AppLocalization[Lang.Timestamp] Sortable="true">
165-
<CellTemplate>
166-
<MudText>
167-
@context.Item.Timestamp.ToLocalTime()
168-
</MudText>
169-
</CellTemplate>
170-
</TemplateColumn>
171-
<PropertyColumn Property="x => x.Username" Title="@AppLocalization[Lang.Username]" />
172-
<PropertyColumn Property="x => x.IpAddress" Title="@AppLocalization[Lang.IP_Address]" />
173-
<PropertyColumn Property="x => x.Target" Title="@AppLocalization[Lang.Target]" />
174-
<PropertyColumn Property="x => x.BeforeAction" Title="@AppLocalization[Lang.Before_Action]" />
175-
<PropertyColumn Property="x => x.AfterAction" Title="@AppLocalization[Lang.After_Action]" />
176-
177-
</Columns>
178-
</MudDataGrid>
179-
}
180-
181-
182-
48+
<SystemAuditContent />
18349

18450
</ChildContent>
18551
<TabContent>
@@ -213,27 +79,11 @@
21379

21480

21581
@code {
216-
List<LogonAuditLog> logonEntries = new();
217-
List<DirectoryEntryAuditLog> auditEntries = new();
218-
List<SystemAuditLog> systemAuditEntries = new();
21982
protected override async Task OnInitializedAsync()
22083
{
22184

22285
await base.OnInitializedAsync();
22386
BaseUri = "/audit";
224-
using (var context = await DbFactory.CreateDbContextAsync())
225-
{
226-
auditEntries = await context.DirectoryEntryAuditLogs.ToListAsync();
227-
logonEntries = await context.LogonAuditLog.ToListAsync();
228-
229-
systemAuditEntries = await context.SystemAuditLog.ToListAsync();
230-
231-
232-
233-
234-
}
235-
236-
23787
}
23888

23989
}

BLAZAM/Pages/Configure/Templates.razor

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<SetSubHeader @ref=Header>
1010

11-
<EditDirectoryTemplateHeader TemplateSelected="SelectedTemplate"/>
11+
<EditDirectoryTemplateHeader OnTemplateChanged="TemplateChanged" TemplateSelected="SelectedTemplate"/>
1212

1313
</SetSubHeader>
1414

@@ -36,13 +36,13 @@
3636

3737
@code {
3838
IReadOnlyCollection<TreeItemData<DirectoryTemplate>> TemplateTreeItemData = new List<TreeItemData<DirectoryTemplate>>();
39-
39+
4040
protected override async Task OnInitializedAsync()
4141
{
4242
await base.OnInitializedAsync();
4343
await RefreshComponents();
4444

45-
45+
4646
if (Templates?.Any() == true)
4747
{
4848
TemplateTreeItemData = CreateTemplateTreeItemData();
@@ -52,8 +52,12 @@
5252
}
5353

5454

55-
56-
55+
56+
private async Task TemplateChanged(DirectoryTemplate template)
57+
{
58+
SelectedTemplate = template;
59+
await StateHasChangedAsync();
60+
}
5761

5862

5963
private IReadOnlyCollection<TreeItemData<DirectoryTemplate>> CreateTemplateTreeItemData()

0 commit comments

Comments
 (0)