Skip to content

Commit 86057d2

Browse files
authored
Merge pull request #1368 from hargata/Hargata/165
1.6.5 Changes
2 parents c6289c4 + 9b4f37c commit 86057d2

41 files changed

Lines changed: 458 additions & 162 deletions

Some content is hidden

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

CarCareTracker.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
<ItemGroup>
1010
<PackageReference Include="CsvHelper" Version="33.1.0" />
1111
<PackageReference Include="LiteDB" Version="5.0.17" />
12-
<PackageReference Include="MailKit" Version="4.15.1" />
12+
<PackageReference Include="MailKit" Version="4.16.0" />
1313
<PackageReference Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.17.0" />
14-
<PackageReference Include="Npgsql" Version="9.0.4" />
14+
<PackageReference Include="Npgsql" Version="9.0.5" />
1515
</ItemGroup>
1616

1717
</Project>

Controllers/APIController.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using CarCareTracker.Models;
66
using Microsoft.AspNetCore.Authorization;
77
using Microsoft.AspNetCore.Mvc;
8+
using System.Globalization;
89
using System.Security.Claims;
910
using System.Text.Json;
1011

@@ -141,6 +142,21 @@ public IActionResult WhoAmI()
141142
}
142143
}
143144
[HttpGet]
145+
[Route("/api/info")]
146+
public async Task<IActionResult> GetServerInformation()
147+
{
148+
var currentCulture = CultureInfo.CurrentCulture;
149+
var viewModel = new ServerInformation
150+
{
151+
Locale = currentCulture.Name,
152+
CurrentVersion = StaticHelper.VersionNumber,
153+
CurrencySymbol = currentCulture.NumberFormat.CurrencySymbol,
154+
DecimalSeparator = currentCulture.NumberFormat.NumberDecimalSeparator,
155+
DateFormat = currentCulture.DateTimeFormat.ShortDatePattern
156+
};
157+
return Json(viewModel);
158+
}
159+
[HttpGet]
144160
[Route("/api/version")]
145161
public async Task<IActionResult> ServerVersion(bool checkForUpdate = false)
146162
{

Controllers/AdminController.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public IActionResult GetUserPartialView()
3737
var viewModel = _loginLogic.GetAllUsers().OrderBy(x => x.Id).ToList();
3838
return PartialView("_Users", viewModel);
3939
}
40-
public IActionResult GenerateNewToken(string emailAddress, bool autoNotify)
40+
public async Task<IActionResult> GenerateNewToken(string emailAddress, bool autoNotify)
4141
{
4242
if (emailAddress.Contains(","))
4343
{
@@ -47,7 +47,7 @@ public IActionResult GenerateNewToken(string emailAddress, bool autoNotify)
4747
var trimmedEmail = emailAdd.Trim();
4848
if (!string.IsNullOrWhiteSpace(trimmedEmail))
4949
{
50-
var result = _loginLogic.GenerateUserToken(emailAdd.Trim(), autoNotify);
50+
var result = await _loginLogic.GenerateUserToken(emailAdd.Trim(), autoNotify);
5151
if (!result.Success)
5252
{
5353
//if fail, return prematurely
@@ -59,7 +59,7 @@ public IActionResult GenerateNewToken(string emailAddress, bool autoNotify)
5959
return Json(successResponse);
6060
} else
6161
{
62-
var result = _loginLogic.GenerateUserToken(emailAddress, autoNotify);
62+
var result = await _loginLogic.GenerateUserToken(emailAddress, autoNotify);
6363
return Json(result);
6464
}
6565
}
@@ -94,7 +94,8 @@ public IActionResult GetUserHouseholdModal(int userId)
9494
{
9595
households = households.OrderBy(x => x.UserName).ToList();
9696
}
97-
var viewModel = new UserHouseholdAdminViewModel { Households = households, ParentUserId = userId };
97+
var userCanResetPassword = _loginLogic.GetUserCanResetPassword(userId);
98+
var viewModel = new UserHouseholdAdminViewModel { Households = households, ParentUserId = userId, UserCanResetPassword = userCanResetPassword };
9899
return PartialView("_AdminUserHouseholdModal", viewModel);
99100
}
100101
[HttpPost]
@@ -115,5 +116,17 @@ public IActionResult ModifyUserHouseholdPermissions(int parentUserId, int childU
115116
var result = _userLogic.UpdateUserHousehold(parentUserId, childUserId, permissions);
116117
return Json(result);
117118
}
119+
[HttpPost]
120+
public IActionResult RevokeUserPassword(int userId)
121+
{
122+
var result = _loginLogic.RevokeUserPassword(userId);
123+
return Json(result);
124+
}
125+
[HttpPost]
126+
public IActionResult ResetUserPassword(int userId)
127+
{
128+
var result = _loginLogic.ResetUserPassword(userId);
129+
return Json(result);
130+
}
118131
}
119132
}

Controllers/HomeController.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,15 +198,15 @@ public IActionResult UpdateExtraFields(RecordExtraField record)
198198
return PartialView("_ExtraFields", recordExtraFields);
199199
}
200200
[HttpPost]
201-
public IActionResult GenerateTokenForUser()
201+
public async Task<IActionResult> GenerateTokenForUser()
202202
{
203203
try
204204
{
205205
//get current user email address.
206206
var emailAddress = User.FindFirstValue(ClaimTypes.Email);
207207
if (!string.IsNullOrWhiteSpace(emailAddress))
208208
{
209-
var result = _loginLogic.GenerateTokenForEmailAddress(emailAddress, false);
209+
var result = await _loginLogic.GenerateTokenForEmailAddress(emailAddress, false);
210210
return Json(result);
211211
}
212212
return Json(false);
@@ -241,7 +241,8 @@ public IActionResult GetUserAccountInformationModal()
241241
{
242242
var emailAddress = User.FindFirstValue(ClaimTypes.Email) ?? string.Empty;
243243
var userName = User?.Identity?.Name ?? string.Empty;
244-
return PartialView("_AccountModal", new UserData() { EmailAddress = emailAddress, UserName = userName });
244+
bool userCanResetPassword = _loginLogic.GetUserCanResetPassword(GetUserID());
245+
return PartialView("_AccountModal", new UserDataViewModel() { EmailAddress = emailAddress, UserName = userName, CanResetPassword = userCanResetPassword });
245246
}
246247
[HttpGet]
247248
public IActionResult GetHouseholdModal()
@@ -661,6 +662,7 @@ public IActionResult Setup()
661662
CustomWidgetsEnabled = _config.GetCustomWidgetsEnabled(),
662663
InvariantAPIEnabled = _config.GetInvariantApi(),
663664
WebSocketEnabled = _config.GetWebSocketEnabled(),
665+
ResizeThumbnail = _config.GetResizeThumbnailEnabled(),
664666
SMTPConfig = _config.GetMailConfig(),
665667
Domain = _config.GetServerDomain(),
666668
OIDCConfig = _config.GetOpenIDConfig(),

Controllers/LoginController.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,15 +567,15 @@ public IActionResult RegisterOpenIdUser(LoginModel credentials)
567567
return Json(result);
568568
}
569569
[HttpPost]
570-
public IActionResult SendRegistrationToken(LoginModel credentials)
570+
public async Task<IActionResult> SendRegistrationToken(LoginModel credentials)
571571
{
572-
var result = _loginLogic.SendRegistrationToken(credentials);
572+
var result = await _loginLogic.SendRegistrationToken(credentials);
573573
return Json(result);
574574
}
575575
[HttpPost]
576-
public IActionResult RequestResetPassword(LoginModel credentials)
576+
public async Task<IActionResult> RequestResetPassword(LoginModel credentials)
577577
{
578-
var result = _loginLogic.RequestResetPassword(credentials);
578+
var result = await _loginLogic.RequestResetPassword(credentials);
579579
return Json(result);
580580
}
581581
[HttpPost]

Controllers/Vehicle/PlanController.cs

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,87 @@ public IActionResult ConvertPlanRecordTemplateToPlanRecord(int planRecordTemplat
178178
var result = _planRecordDataAccess.SavePlanRecordToVehicle(existingRecord.ToPlanRecord());
179179
return Json(OperationResponse.Conditional(result, "Plan Record Added", StaticHelper.GenericErrorMessage));
180180
}
181+
[HttpPost]
182+
public IActionResult ConvertPlanRecordToPlanRecordTemplate(int planRecordId)
183+
{
184+
var existingRecord = _planRecordDataAccess.GetPlanRecordById(planRecordId);
185+
if (existingRecord.Id == default)
186+
{
187+
return Json(OperationResponse.Failed("Unable to find plan record"));
188+
}
189+
//security check.
190+
if (!_userLogic.UserCanEditVehicle(GetUserID(), existingRecord.VehicleId, HouseholdPermission.Edit))
191+
{
192+
return Json(OperationResponse.Failed("Access Denied"));
193+
}
194+
//check if template name already taken.
195+
var existingTemplateRecord = _planRecordTemplateDataAccess.GetPlanRecordTemplatesByVehicleId(existingRecord.VehicleId).Any(x => x.Description == existingRecord.Description);
196+
if (existingTemplateRecord)
197+
{
198+
return Json(OperationResponse.Failed("A template with that description already exists for this vehicle"));
199+
}
200+
var planRecordTemplate = new PlanRecordInput()
201+
{
202+
VehicleId = existingRecord.VehicleId,
203+
Description = existingRecord.Description,
204+
Notes = existingRecord.Notes,
205+
Files = existingRecord.Files,
206+
ImportMode = existingRecord.ImportMode,
207+
Priority = existingRecord.Priority,
208+
Progress = existingRecord.Progress,
209+
Cost = existingRecord.Cost,
210+
ExtraFields = existingRecord.ExtraFields
211+
};
212+
if (existingRecord.ReminderRecordId != default)
213+
{
214+
//check if reminder still exists and is still recurring.
215+
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(existingRecord.ReminderRecordId);
216+
if (existingReminder is null || existingReminder.Id == default || !existingReminder.IsRecurring)
217+
{
218+
return Json(OperationResponse.Failed("Missing or Non-recurring Reminder, Unable to Create Template."));
219+
}
220+
planRecordTemplate.ReminderRecordId = existingRecord.ReminderRecordId;
221+
}
222+
else if (existingRecord.ReminderRecordIds.Any())
223+
{
224+
foreach (int reminderRecordId in existingRecord.ReminderRecordIds)
225+
{
226+
//check if reminder still exists and is still recurring.
227+
var existingReminder = _reminderRecordDataAccess.GetReminderRecordById(reminderRecordId);
228+
if (existingReminder is null || existingReminder.Id == default || !existingReminder.IsRecurring)
229+
{
230+
return Json(OperationResponse.Failed("Missing or Non-recurring Reminder, Unable to Create Template."));
231+
}
232+
planRecordTemplate.ReminderRecordIds = existingRecord.ReminderRecordIds;
233+
}
234+
}
235+
if (existingRecord.RequisitionHistory.Any())
236+
{
237+
foreach(SupplyUsageHistory supplyUsageHistory in existingRecord.RequisitionHistory)
238+
{
239+
//check if supply still exists.
240+
if (supplyUsageHistory.Id != default)
241+
{
242+
planRecordTemplate.Supplies.Add(new SupplyUsage { SupplyId = supplyUsageHistory.Id, Quantity = supplyUsageHistory.Quantity });
243+
}
244+
}
245+
}
246+
if (planRecordTemplate.Supplies.Any())
247+
{
248+
//check if all supplies are available
249+
var supplyAvailability = CheckSupplyRecordsAvailability(planRecordTemplate.Supplies);
250+
if (supplyAvailability.Any(x => x.Missing))
251+
{
252+
return Json(OperationResponse.Failed("Missing Supplies, Unable to Create Template."));
253+
}
254+
else if (supplyAvailability.Any(x => x.Insufficient))
255+
{
256+
return Json(OperationResponse.Failed("Insufficient Supplies"));
257+
}
258+
}
259+
var result = _planRecordTemplateDataAccess.SavePlanRecordTemplateToVehicle(planRecordTemplate);
260+
return Json(OperationResponse.Conditional(result, "Plan Record Template Created", StaticHelper.GenericErrorMessage));
261+
}
181262
[HttpGet]
182263
public IActionResult GetAddPlanRecordPartialView()
183264
{

Controllers/Vehicle/ReminderController.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,18 @@ public IActionResult SaveReminderRecordToVehicleId(ReminderRecordInput reminderR
125125
return Json(OperationResponse.Conditional(result, string.Empty, StaticHelper.GenericErrorMessage));
126126
}
127127
[HttpPost]
128-
public IActionResult GetAddReminderRecordPartialView(ReminderRecordInput? reminderModel)
128+
public IActionResult GetAddReminderRecordPartialView(ReminderRecordInputViewModel? reminderModel)
129129
{
130-
if (reminderModel is not null)
130+
if (reminderModel is null)
131131
{
132-
return PartialView("Reminder/_ReminderRecordModal", reminderModel);
132+
reminderModel = new ReminderRecordInputViewModel();
133133
}
134-
else
134+
if (reminderModel.VehicleId != default)
135135
{
136-
return PartialView("Reminder/_ReminderRecordModal", new ReminderRecordInput());
136+
var vehicleData = _dataAccess.GetVehicleById(reminderModel.VehicleId);
137+
reminderModel.UseHours = vehicleData.UseHours;
137138
}
139+
return PartialView("Reminder/_ReminderRecordModal", reminderModel);
138140
}
139141
[HttpGet]
140142
public IActionResult GetReminderRecordForEditById(int reminderRecordId)
@@ -145,8 +147,10 @@ public IActionResult GetReminderRecordForEditById(int reminderRecordId)
145147
{
146148
return Redirect("/Error/Unauthorized");
147149
}
150+
var vehicleData = _dataAccess.GetVehicleById(result.VehicleId);
151+
var vehicleUseHours = vehicleData.UseHours;
148152
//convert to Input object.
149-
var convertedResult = new ReminderRecordInput
153+
var convertedResult = new ReminderRecordInputViewModel
150154
{
151155
Id = result.Id,
152156
Date = result.Date.ToShortDateString(),
@@ -164,7 +168,8 @@ public IActionResult GetReminderRecordForEditById(int reminderRecordId)
164168
CustomMileageInterval = result.CustomMileageInterval,
165169
CustomMonthInterval = result.CustomMonthInterval,
166170
CustomMonthIntervalUnit = result.CustomMonthIntervalUnit,
167-
Tags = result.Tags
171+
Tags = result.Tags,
172+
UseHours = vehicleUseHours
168173
};
169174
return PartialView("Reminder/_ReminderRecordModal", convertedResult);
170175
}

Helper/ConfigHelper.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public interface IConfigHelper
3838
bool DeleteUserConfig(int userId);
3939
bool GetInvariantApi();
4040
bool GetWebSocketEnabled();
41+
bool GetResizeThumbnailEnabled();
4142
bool GetServerOpenRegistration();
4243
string GetDefaultReminderEmail();
4344
int GetAuthCookieLifeSpan();
@@ -81,6 +82,10 @@ public bool GetWebSocketEnabled()
8182
{
8283
return CheckBool(CheckString("LUBELOGGER_WEB_SOCKET"));
8384
}
85+
public bool GetResizeThumbnailEnabled()
86+
{
87+
return CheckBool(CheckString("LUBELOGGER_RESIZE_THUMBNAIL"));
88+
}
8489
public string GetMOTD()
8590
{
8691
var motd = CheckString("LUBELOGGER_MOTD");
@@ -274,6 +279,10 @@ public bool SaveServerConfig(ServerConfig serverConfig)
274279
{
275280
serverConfig.WebSocketEnabled = null;
276281
}
282+
if (serverConfig.ResizeThumbnail.HasValue && !serverConfig.ResizeThumbnail.Value)
283+
{
284+
serverConfig.ResizeThumbnail = null;
285+
}
277286
if (string.IsNullOrWhiteSpace(serverConfig.SMTPConfig?.EmailServer ?? string.Empty))
278287
{
279288
serverConfig.SMTPConfig = null;

0 commit comments

Comments
 (0)