Refactor project structure and remove deprecated features
- Updated README.md to include "Project Structure" section. - Removed WeatherForecastController.cs and WeatherForecast.cs. - Simplified Surge365.MassEmailReact.Server.csproj. - Updated solution file to reflect new project references. - Refactored jquery.ss.dbmanager-1.0.js and jquery.usahaulers.global.js. - Modified logging functionalities in jquery.usahaulers.logging-1.0.js. - Set up constants from environment variables in constants.js and constants.ts. - Introduced new classes in Surge365.MassEmailReact.Application, Domain, and Infrastructure. - Added UnitTest1.cs for basic unit testing structure. - Enhanced Surge365.MassEmailReact.Web.esproj with new configurations. - Expanded utility functions in ytb-massemail-.global.ts and ytb-massemail-utilities-1.0.ts.
This commit is contained in:
parent
2fa7b500b9
commit
f8df86f1b4
23
README.md
23
README.md
@ -4,27 +4,30 @@ Mass Email React Website
|
||||
|
||||
to clone: in command prompt, go to the directory you want to clone the project to, then type:
|
||||
|
||||
```
|
||||
git clone --branch main https://<your_username_here>@git.surge365.com/Surge365/MassEmailReact.git
|
||||
```
|
||||
|
||||
## TO DO IF YOU WANT TO BUILD THIS PROJECT
|
||||
|
||||
1. Install node.js v22.13.1
|
||||
2. Recommended to install nvm for Windows, then in command prompt, type:
|
||||
```
|
||||
nvm install 22.13.1
|
||||
```
|
||||
3. Then type:
|
||||
```
|
||||
nvm use 22.13.1
|
||||
```
|
||||
4. Then to verify, type:
|
||||
```
|
||||
node -v # Should return v22.13.1
|
||||
```
|
||||
5. Then to verify npm, type:
|
||||
```
|
||||
npm -v # Should return a version
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
This project consists of multiple layers to ensure separation of concerns and maintainability.
|
||||
|
||||
### Project Descriptions and Dependency Order
|
||||
|
||||
1. **Surge365.MassEmailReact.Domain** - Contains core business logic and domain entities.
|
||||
2. **Surge365.MassEmailReact.Application** - Handles application logic and use cases. Depends on `Domain`.
|
||||
3. **Surge365.MassEmailReact.Infrastructure** - Provides data access, external integrations, and persistence. Depends on `Application` and `Domain`.
|
||||
4. **Surge365.MassEmailReact.API** - The API layer that serves endpoints. Depends on `Application`.
|
||||
5. **Surge365.MassEmailReact.Web** - The front-end application. Communicates with `API`.
|
||||
6. **Surge365.MassEmailReact.UnitTests** - Contains unit tests for various layers of the application.
|
||||
|
||||
|
||||
7
Surge365.MassEmailReact.Application/Class1.cs
Normal file
7
Surge365.MassEmailReact.Application/Class1.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Surge365.MassEmailReact.Application
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Domain\Surge365.MassEmailReact.Domain.csproj" />
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Infrastructure\Surge365.MassEmailReact.Infrastructure.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
7
Surge365.MassEmailReact.Domain/Class1.cs
Normal file
7
Surge365.MassEmailReact.Domain/Class1.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Surge365.MassEmailReact.Domain
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
7
Surge365.MassEmailReact.Infrastructure/Class1.cs
Normal file
7
Surge365.MassEmailReact.Infrastructure/Class1.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace Surge365.MassEmailReact.Infrastructure
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,32 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Surge365.MassEmailReact.Server.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetWeatherForecast")]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
@ -17,9 +17,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\surge365.massemailreact.client\surge365.massemailreact.client.esproj">
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Application\Surge365.MassEmailReact.Application.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -1,13 +0,0 @@
|
||||
namespace Surge365.MassEmailReact.Server
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.2" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Application\Surge365.MassEmailReact.Application.csproj" />
|
||||
<ProjectReference Include="..\surge365.massemailreact.client\Surge365.MassEmailReact.Web.esproj" />
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Domain\Surge365.MassEmailReact.Domain.csproj" />
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Infrastructure\Surge365.MassEmailReact.Infrastructure.csproj" />
|
||||
<ProjectReference Include="..\Surge365.MassEmailReact.Server\Surge365.MassEmailReact.API.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
11
Surge365.MassEmailReact.UnitTests/UnitTest1.cs
Normal file
11
Surge365.MassEmailReact.UnitTests/UnitTest1.cs
Normal file
@ -0,0 +1,11 @@
|
||||
namespace Surge365.MassEmailReact.UnitTests
|
||||
{
|
||||
public class UnitTest1
|
||||
{
|
||||
[Fact]
|
||||
public void Test1()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,11 +1,24 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35806.99 d17.13
|
||||
VisualStudioVersion = 17.13.35806.99
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "surge365.massemailreact.client", "surge365.massemailreact.client\surge365.massemailreact.client.esproj", "{E719388D-D7C7-6E5A-3D56-06DBCCECFF8F}"
|
||||
Project("{54A90642-561A-4BB1-A94E-469ADEE60C69}") = "Surge365.MassEmailReact.Web", "surge365.massemailreact.client\Surge365.MassEmailReact.Web.esproj", "{E719388D-D7C7-6E5A-3D56-06DBCCECFF8F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Surge365.MassEmailReact.Server", "Surge365.MassEmailReact.Server\Surge365.MassEmailReact.Server.csproj", "{585F39DB-9461-48EB-9A0A-294478A9F052}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Surge365.MassEmailReact.API", "Surge365.MassEmailReact.Server\Surge365.MassEmailReact.API.csproj", "{585F39DB-9461-48EB-9A0A-294478A9F052}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Surge365.MassEmailReact.Domain", "Surge365.MassEmailReact.Domain\Surge365.MassEmailReact.Domain.csproj", "{6032050E-5666-4246-BA3E-4FABCD813724}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Surge365.MassEmailReact.Infrastructure", "Surge365.MassEmailReact.Infrastructure\Surge365.MassEmailReact.Infrastructure.csproj", "{F32A115E-06A6-4428-81CE-47C5943BC97D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Surge365.MassEmailReact.Application", "Surge365.MassEmailReact.Application\Surge365.MassEmailReact.Application.csproj", "{F60998C4-3301-414E-B2FE-5E08B2F4BC9D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Surge365.MassEmailReact.UnitTests", "Surge365.MassEmailReact.UnitTests\Surge365.MassEmailReact.UnitTests.csproj", "{A90972B7-7D32-4C1A-AB68-1043819F2A56}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
README.md = README.md
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
@ -23,6 +36,22 @@ Global
|
||||
{585F39DB-9461-48EB-9A0A-294478A9F052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{585F39DB-9461-48EB-9A0A-294478A9F052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{585F39DB-9461-48EB-9A0A-294478A9F052}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6032050E-5666-4246-BA3E-4FABCD813724}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6032050E-5666-4246-BA3E-4FABCD813724}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6032050E-5666-4246-BA3E-4FABCD813724}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6032050E-5666-4246-BA3E-4FABCD813724}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F32A115E-06A6-4428-81CE-47C5943BC97D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F32A115E-06A6-4428-81CE-47C5943BC97D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F32A115E-06A6-4428-81CE-47C5943BC97D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F32A115E-06A6-4428-81CE-47C5943BC97D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{F60998C4-3301-414E-B2FE-5E08B2F4BC9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{F60998C4-3301-414E-B2FE-5E08B2F4BC9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{F60998C4-3301-414E-B2FE-5E08B2F4BC9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{F60998C4-3301-414E-B2FE-5E08B2F4BC9D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A90972B7-7D32-4C1A-AB68-1043819F2A56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A90972B7-7D32-4C1A-AB68-1043819F2A56}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A90972B7-7D32-4C1A-AB68-1043819F2A56}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A90972B7-7D32-4C1A-AB68-1043819F2A56}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@ -8,11 +8,12 @@
|
||||
<!-- Folder where production build objects will be placed -->
|
||||
<BuildOutputFolder>$(MSBuildProjectDirectory)\dist</BuildOutputFolder>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="public\content\lib\**" />
|
||||
<TypeScriptConfiguration Remove="public\content\lib\**" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="src\components\layouts\LayoutLogin_Backup.tsx" />
|
||||
<None Remove="src\components\layouts\Layout_backup.tsx" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="public\content\lib\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@ -1,108 +0,0 @@
|
||||
const INTERNAL_SECOND_MS = 60 * 1000;
|
||||
const INTERNAL_MINUTE_MS = 60 * INTERNAL_SECOND_MS;
|
||||
const INTERNAL_HOUR_MS = 60 * INTERNAL_MINUTE_MS;
|
||||
|
||||
var isIndexedDBSupported = 'indexedDB' in window;
|
||||
|
||||
|
||||
$.dbManager = {
|
||||
openDatabases: {}
|
||||
}
|
||||
|
||||
$.dbManager.alert = function (msg) {
|
||||
alert(msg);
|
||||
}
|
||||
|
||||
$.dbManager.openDatabase = function (name, version, onUpgradeNeeded) {
|
||||
let dbManager = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
let db = dbManager.openDatabases[name];
|
||||
if (db !== undefined && db !== null) {
|
||||
resolve(db);
|
||||
return;
|
||||
}
|
||||
let request = indexedDB.open(name, version);
|
||||
request.onupgradeneeded = function (event) {
|
||||
//Upgrade DB? Drop DB and reload? For now, drop db
|
||||
console.log("onupgradeneeded");
|
||||
|
||||
if (onUpgradeNeeded != null) {
|
||||
onUpgradeNeeded(event);
|
||||
}
|
||||
else {
|
||||
dbManager.deleteDatabase(name).then(
|
||||
function onSuccess(db) {
|
||||
resolve(db);
|
||||
},
|
||||
function onError(error) {
|
||||
reject(error);
|
||||
});
|
||||
}
|
||||
//reject("Upgrade Needed");
|
||||
};
|
||||
|
||||
request.onerror = function () {
|
||||
console.error("Error: ", request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
|
||||
request.onblocked = function () {
|
||||
console.error();
|
||||
reject("Database blocked");
|
||||
};
|
||||
|
||||
request.onsuccess = function () {
|
||||
let db = request.result;
|
||||
|
||||
db.onversionchange = function (event) {
|
||||
let isDeleted = event.newVersion === null;
|
||||
db.close();
|
||||
if(!isDeleted)
|
||||
alert("Database is outdated, please reload the page: ", event.currentTarget.name)
|
||||
};
|
||||
|
||||
console.log("Database opened: ", name);
|
||||
if (dbManager.openDatabases == null)
|
||||
dbManager.openDatabases = {};
|
||||
|
||||
dbManager.openDatabases[name] = db;
|
||||
db.onclose = function () { //TODO: DOesn't appear to be called currently
|
||||
console.log('Database connection closed: ', name);
|
||||
dbManager.openDatabases[name] = null;
|
||||
}
|
||||
resolve(db);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
$.dbManager.closeDatabase = function (name) {
|
||||
let currentDB = this;
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
let db = currentDB.openDatabases[name];
|
||||
if (db != null) {
|
||||
db.close();
|
||||
}
|
||||
currentDB.openDatabases[name] == null;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
$.dbManager.deleteDatabase = function (name) {
|
||||
let currentDB = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
let request = indexedDB.deleteDatabase(name);
|
||||
|
||||
request.onerror = function () {
|
||||
console.error("Error", request.error);
|
||||
reject(request.error);
|
||||
};
|
||||
|
||||
request.onsuccess = function () {
|
||||
console.log("database deleted: ", name);
|
||||
currentDB.openDatabases[name] = null;
|
||||
resolve();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@ -1,931 +0,0 @@
|
||||
const DEFAULT_LOG_LEVELS_TO_LOG = ["debug","warn","info","error"];
|
||||
const DEFAULT_LOG_AJAX_REQUESTS = true;
|
||||
|
||||
const DEFAULT_LOG_AJAX_REQUESTS_TO_CONSOLE = true;
|
||||
const DEFAULT_LOG_AJAX_REQUESTS_TO_CONSOLE_ERROR_ONLY = true;
|
||||
const DEFAULT_LOG_AJAX_REQUESTS_TO_CONSOLE_MAX_RESPONSE_CHARS = 200
|
||||
|
||||
///CURRENTLY THESE INDEXEDDB CONSTS ARE NOT USED, LEAVING HERE IN CASE I FIGURE OUT HOW TO WIRE THEM UP.
|
||||
const DEFAULT_LOG_AJAX_REQUESTS_TO_INDEXEDDB = true;
|
||||
const DEFAULT_LOG_AJAX_REQUESTS_TO_INDEXEDDB_ERROR_ONLY = true;
|
||||
const DEFAULT_LOG_AJAX_REQUESTS_TO_INDEXEDDB_MAX_RESPONSE_CHARS = -1 //< 0 = log all, 0 = log none, > 0 log that # of chars
|
||||
const DEFAULT_LOG_URL = 'https://usahaulerslog.solutionsmith.net/WebServices/LoggingMethods.aspx/SaveLogs';
|
||||
|
||||
const INTERNAL_LOG_URLS = {
|
||||
DEFAULT: "https://usahaulerslogdev.solutionsmith.net/WebServices/LoggingMethods.aspx/SaveLogs",
|
||||
DEV: "https://usahaulerslogdev.solutionsmith.net/WebServices/LoggingMethods.aspx/SaveLogs",
|
||||
PROD: "https://usahaulerslog.solutionsmith.net/WebServices/LoggingMethods.aspx/SaveLogs"
|
||||
}
|
||||
const DEFAULT_LOG_CONFIG_OBJECT = {
|
||||
id: 0,
|
||||
defaultLogLevelsToLog: DEFAULT_LOG_LEVELS_TO_LOG,
|
||||
logAjaxRequests: DEFAULT_LOG_AJAX_REQUESTS,
|
||||
logAjaxRequestsToConsole: DEFAULT_LOG_AJAX_REQUESTS_TO_CONSOLE,
|
||||
logAjaxRequestsToConsoleErrorOnly: DEFAULT_LOG_AJAX_REQUESTS_TO_CONSOLE_ERROR_ONLY,
|
||||
logAjaxRequestsToConsoleMaxResponseChars: DEFAULT_LOG_AJAX_REQUESTS_TO_CONSOLE_MAX_RESPONSE_CHARS,
|
||||
logAjaxRequestsToIndexedDB: DEFAULT_LOG_AJAX_REQUESTS_TO_INDEXEDDB,
|
||||
logAjaxRequestsToIndexedDBErrorOnly: DEFAULT_LOG_AJAX_REQUESTS_TO_INDEXEDDB_ERROR_ONLY,
|
||||
logAjaxRequestsToIndexedDBMaxResponseChars: DEFAULT_LOG_AJAX_REQUESTS_TO_INDEXEDDB_MAX_RESPONSE_CHARS
|
||||
}
|
||||
|
||||
const OLD_CONSOLE_LOG = console.log;
|
||||
const OLD_CONSOLE_DEBUG = console.debug;
|
||||
const OLD_CONSOLE_WARN = console.warn;
|
||||
const OLD_CONSOLE_INFO = console.info;
|
||||
const OLD_CONSOLE_ERROR = console.error;
|
||||
|
||||
const USAHAULERSLOGGING_DATABASE_NAME = "usahaulerslogging";
|
||||
const USAHAULERSLOGGING_DATABASE_VERSION = 1;
|
||||
|
||||
const INTERNAL_USAHAULERSLOGGING_USEHAULERSLOGGINGDBCONFIG_OBJECT_STORE = "usahaulersloggingdb.config";
|
||||
const INTERNAL_USAHAULERSLOGGING_LOG_REFRESH_PERIOD = INTERNAL_MINUTE_MS * 5;
|
||||
|
||||
const INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE = "logs";
|
||||
const INTERNAL_USAHAULERSLOGGING_LOG_INDEX_DATE = "date";
|
||||
const INTERNAL_USAHAULERSLOGGING_LOG_INDEX_LEVEL = "level";
|
||||
const INTERNAL_USAHAULERSLOGGING_LOG_INDEX_UPLOADED = "uploaded";
|
||||
const INTERNAL_USAHAULERSLOGGING_MAXUPLOADQTY = 100
|
||||
|
||||
$.usaHaulersLoggingDB = {
|
||||
config: DEFAULT_LOG_CONFIG_OBJECT,
|
||||
shouldLogLevel: (level) => {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return config.defaultLogLevelsToLog.includes(level.trim().toLowerCase());
|
||||
},
|
||||
shouldLogAjaxRequests: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return config.logAjaxRequests && (config.logAjaxRequestsToConsole || config.logAjaxRequestsToIndexedDB);
|
||||
},
|
||||
shouldLogAjaxRequestsToConsole: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return config.logAjaxRequests && config.logAjaxRequestsToConsole;
|
||||
},
|
||||
shouldLogAjaxRequestsToConsoleErrorOnly: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return config.logAjaxRequests && config.logAjaxRequestsToConsole && config.logAjaxRequestsToConsoleErrorOnly;
|
||||
},
|
||||
logAjaxRequestsToConsoleMaxResponseChars: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return (config.logAjaxRequests && config.logAjaxRequestsToConsole ? config.logAjaxRequestsToConsoleMaxResponseChars : 0);
|
||||
},
|
||||
shouldLogAjaxRequestsToIndexedDB: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return config.logAjaxRequests && config.logAjaxRequestsToIndexedDB && $.usaHaulersLoggingDB.dbInitialized;
|
||||
},
|
||||
shouldLogAjaxRequestsToIndexedDBErrorOnly: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return config.logAjaxRequests && config.logAjaxRequestsToIndexedDB && config.logAjaxRequestsToIndexedDBErrorOnly;
|
||||
},
|
||||
logAjaxRequestsToIndexedDBMaxResponseChars: function () {
|
||||
var config = $.usaHaulersLoggingDB.config;
|
||||
if (config == null)
|
||||
config = DEFAULT_LOG_CONFIG_OBJECT;
|
||||
return (config.logAjaxRequests && config.logAjaxRequestsToIndexedDB ? config.logAjaxRequestsToIndexedDBMaxResponseChars : 0);
|
||||
},
|
||||
prepareLog: function (argumentArray) {
|
||||
var LOG_PREFIX = new Date().toISOString();
|
||||
var args = Array.from(argumentArray);
|
||||
args.unshift(LOG_PREFIX + ": ");
|
||||
return args;
|
||||
},
|
||||
getLogMsgFromArguments: function (argumentArray) {
|
||||
if (argumentArray === undefined || argumentArray === null)
|
||||
return "Unknown log request: null/undefined passed to getLogMsgFromArguments";
|
||||
|
||||
var args = Array.from(argumentArray);
|
||||
|
||||
var msg = "";
|
||||
|
||||
args.forEach((arg) => {
|
||||
var msg1 = "";
|
||||
if (arg !== undefined && arg !== null) {
|
||||
if (typeof arg === 'object')
|
||||
msg1 = JSON.stringify(arg);
|
||||
else
|
||||
msg1 = arg.toString();
|
||||
|
||||
if (msg.length > 0)
|
||||
msg += ", ";
|
||||
|
||||
msg += msg1;
|
||||
}
|
||||
});
|
||||
return msg;
|
||||
},
|
||||
getBoolean: function (variable) {
|
||||
if ($.getBoolean)
|
||||
return $.getBoolean(variable);
|
||||
|
||||
var vtype;
|
||||
var toReturn;
|
||||
|
||||
if (variable != null) {
|
||||
switch (typeof (variable)) {
|
||||
case 'boolean':
|
||||
vtype = "boolean";
|
||||
return variable;
|
||||
break;
|
||||
|
||||
case 'number':
|
||||
vtype = "number";
|
||||
if (variable == 0)
|
||||
toReturn = false;
|
||||
else toReturn = true;
|
||||
break;
|
||||
|
||||
case 'string':
|
||||
vtype = "string";
|
||||
if (variable.toLowerCase() == "true" || variable.toLowerCase() == "yes")
|
||||
toReturn = true;
|
||||
else if (variable.toLowerCase() == "false" || variable.toLowerCase() == "no")
|
||||
toReturn = false;
|
||||
else if (variable.length > 0)
|
||||
toReturn = true;
|
||||
else if (variable.length == 0)
|
||||
toReturn = false;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
},
|
||||
removeObjectMethodsForSerialization: function (obj) {
|
||||
try {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
catch (error) {
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log = console.debug = function () {
|
||||
var args = $.usaHaulersLoggingDB.prepareLog(arguments);
|
||||
OLD_CONSOLE_DEBUG.apply(console, args);
|
||||
if ($.usaHaulersLoggingDB && $.usaHaulersLoggingDB.addLog && $.usaHaulersLoggingDB.dbInitialized && $.usaHaulersLoggingDB.shouldLogLevel("debug")) {
|
||||
var msg = $.usaHaulersLoggingDB.getLogMsgFromArguments(arguments);
|
||||
var dbArgs = Array.from(arguments);
|
||||
$.usaHaulersLoggingDB.addLog("DEBUG", msg, dbArgs);
|
||||
}
|
||||
}
|
||||
console.warn = function () {
|
||||
var args = $.usaHaulersLoggingDB.prepareLog(arguments);
|
||||
OLD_CONSOLE_WARN.apply(console, args);
|
||||
if ($.usaHaulersLoggingDB && $.usaHaulersLoggingDB.addLog && $.usaHaulersLoggingDB.dbInitialized && $.usaHaulersLoggingDB.shouldLogLevel("warn")) {
|
||||
var msg = $.usaHaulersLoggingDB.getLogMsgFromArguments(arguments);
|
||||
var dbArgs = Array.from(arguments);
|
||||
$.usaHaulersLoggingDB.addLog("WARN", msg, dbArgs);
|
||||
}
|
||||
}
|
||||
console.info = function () {
|
||||
var args = $.usaHaulersLoggingDB.prepareLog(arguments);
|
||||
OLD_CONSOLE_INFO.apply(console, args);
|
||||
if ($.usaHaulersLoggingDB && $.usaHaulersLoggingDB.addLog && $.usaHaulersLoggingDB.dbInitialized && $.usaHaulersLoggingDB.shouldLogLevel("info")) {
|
||||
var msg = $.usaHaulersLoggingDB.getLogMsgFromArguments(arguments);
|
||||
var dbArgs = Array.from(arguments);
|
||||
$.usaHaulersLoggingDB.addLog("INFO", msg, dbArgs);
|
||||
}
|
||||
}
|
||||
console.error = function () {
|
||||
var args = $.usaHaulersLoggingDB.prepareLog(arguments);
|
||||
OLD_CONSOLE_ERROR.apply(console, args);
|
||||
if ($.usaHaulersLoggingDB && $.usaHaulersLoggingDB.addLog && $.usaHaulersLoggingDB.dbInitialized && $.usaHaulersLoggingDB.shouldLogLevel("error")) {
|
||||
var msg = $.usaHaulersLoggingDB.getLogMsgFromArguments(arguments);
|
||||
var dbArgs = Array.from(arguments);
|
||||
$.usaHaulersLoggingDB.addLog("ERROR", msg, dbArgs);
|
||||
}
|
||||
}
|
||||
|
||||
if ($ && $.ajaxSetup) {
|
||||
$(document).ready(function () {
|
||||
$(document).ajaxSuccess(function (event, xhr, settings) {
|
||||
if ($.usaHaulersLoggingDB.shouldLogAjaxRequests()) {
|
||||
var responseText = "";
|
||||
var isSuccess = true;
|
||||
if (xhr.responseJson != null && xhr.responseJson.d != null && xhr.responseJson.d.success != null && !xhr.responseJson.d.success)
|
||||
isSuccess = false;
|
||||
|
||||
if (!$.usaHaulersLoggingDB.shouldLogAjaxRequestsToConsoleErrorOnly() || !isSuccess) {
|
||||
if (xhr.responseText && xhr.responseText != null) {
|
||||
if ($.usaHaulersLoggingDB.logAjaxRequestsToConsoleMaxResponseChars() <= 0 || xhr.responseText.length <= $.usaHaulersLoggingDB.logAjaxRequestsToConsoleMaxResponseChars())
|
||||
responseText = "response = '" + xhr.responseText + "';";
|
||||
else
|
||||
responseText = "responseSnippet='" + xhr.responseText.substring(0, $.usaHaulersLoggingDB.logAjaxRequestsToConsoleMaxResponseChars()) + "';";
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($.usaHaulersLoggingDB.shouldLogAjaxRequestsToConsole()) {
|
||||
if (!isSuccess)
|
||||
console.debug("Ajax Success, returned success:false", {
|
||||
url: settings.url,
|
||||
httpMethod: settings.type,
|
||||
responseText: responseText
|
||||
});
|
||||
else {
|
||||
console.debug("Ajax Success", {
|
||||
url: settings.url,
|
||||
httpMethod: settings.type,
|
||||
responseText: responseText
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (xhr.responseJson != null && xhr.responseJson.d != null && xhr.responseJson.d.success != null && xhr.responseJson.d.success) {
|
||||
var lg_session_guid = request.getResponseHeader('lg_session_guid');
|
||||
var lg_access_token = $.getBoolean(request.getResponseHeader('lg_access_token'));
|
||||
var lg_application_code = $.getBoolean(request.getResponseHeader('lg_application_code'));
|
||||
var lg_application_user_id = $.getBoolean(request.getResponseHeader('lg_application_user_id'));
|
||||
if ($.cookie) {
|
||||
$.cookie.raw = true;
|
||||
$.cookie('lg_session_guid', lg_session_guid, { path: '/' });
|
||||
$.cookie('lg_access_token', lg_access_token, { path: '/' });
|
||||
$.cookie('lg_application_code', lg_application_code, { path: '/' });
|
||||
$.cookie('lg_application_user_id', lg_application_user_id, { path: '/' });
|
||||
}
|
||||
}
|
||||
});
|
||||
$(document).ajaxError(function (event, xhr, settings) {
|
||||
if ($.usaHaulersLoggingDB.shouldLogAjaxRequests()) {
|
||||
var responseText = "";
|
||||
|
||||
if (xhr.responseText && xhr.responseText != null) {
|
||||
if ($.usaHaulersLoggingDB.logAjaxRequestsToConsoleMaxResponseChars() <= 0 || xhr.responseText.length <= $.usaHaulersLoggingDB.logAjaxRequestsToConsoleMaxResponseChars())
|
||||
responseText = "response = '" + xhr.responseText + "';";
|
||||
else
|
||||
responseText = "responseSnippet='" + xhr.responseText.substring(0, $.usaHaulersLoggingDB.logAjaxRequestsToConsoleMaxResponseChars()) + "';";
|
||||
}
|
||||
|
||||
if ($.usaHaulersLoggingDB.shouldLogAjaxRequestsToConsole()) {
|
||||
console.error("Ajax Error", {
|
||||
url: settings.url,
|
||||
httpMethod: settings.type,
|
||||
responseText: responseText,
|
||||
xhr: $.usaHaulersLoggingDB.removeObjectMethodsForSerialization(xhr),
|
||||
settings: $.usaHaulersLoggingDB.removeObjectMethodsForSerialization(settings)
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const INTERNAL_USAHAULERSLOGGING_ONUPGRADEDNEEDED = function (event) {
|
||||
const db = event.target.result;
|
||||
const transaction = event.currentTarget.transaction;
|
||||
let oldVersion = event.oldVersion;
|
||||
let newVersion = event.newVersion;
|
||||
|
||||
if (oldVersion < 1 && newVersion >= 1) {
|
||||
|
||||
//setup object stores
|
||||
db.createObjectStore(INTERNAL_USAHAULERSLOGGING_USEHAULERSLOGGINGDBCONFIG_OBJECT_STORE, { keyPath: 'id' });
|
||||
|
||||
if (db.objectStoreNames.contains(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE)) {
|
||||
db.deleteObjectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE);
|
||||
}
|
||||
db.createObjectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, { keyPath: 'id' });
|
||||
|
||||
|
||||
//setup indexes
|
||||
let store = transaction.objectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE);
|
||||
|
||||
if (store.indexNames.contains(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_DATE)) {
|
||||
store.deleteIndex(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_DATE);
|
||||
}
|
||||
store.createIndex(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_DATE, "date", { unique: false });
|
||||
|
||||
if (store.indexNames.contains(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_LEVEL)) {
|
||||
store.deleteIndex(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_LEVEL);
|
||||
}
|
||||
store.createIndex(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_LEVEL, "level", { unique: false });
|
||||
|
||||
if (store.indexNames.contains(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_UPLOADED)) {
|
||||
store.deleteIndex(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_UPLOADED);
|
||||
}
|
||||
store.createIndex(INTERNAL_USAHAULERSLOGGING_LOG_INDEX_UPLOADED, "upload_status", { unique: false });
|
||||
|
||||
}
|
||||
|
||||
if (oldVersion < 2 && newVersion >= 2) {
|
||||
//
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$.extend($.usaHaulersLoggingDB, {
|
||||
dbInitialized: false,
|
||||
database: null,
|
||||
initializeDB: function () {
|
||||
let currentDB = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (currentDB.dbInitialized) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
currentDB.refreshConfigObject().then(function () {
|
||||
currentDB.dbInitialized = true;
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
createConfigObject: function () {
|
||||
let currentDB = this;
|
||||
var config = (!currentDB.config || currentDB.config == null ? DEFAULT_LOG_CONFIG_OBJECT : currentDB.config);
|
||||
return config;
|
||||
},
|
||||
refreshConfigObject: function () {
|
||||
let currentDB = this;
|
||||
return new Promise(async function (resolve, reject) {
|
||||
try {
|
||||
let config = await currentDB.getObjects(INTERNAL_USAHAULERSLOGGING_USEHAULERSLOGGINGDBCONFIG_OBJECT_STORE);
|
||||
let configDefault = currentDB.createConfigObject();
|
||||
|
||||
if (!config || config.length == 0) {
|
||||
currentDB.config = configDefault;
|
||||
await currentDB.persistConfigObject();
|
||||
}
|
||||
else {
|
||||
currentDB.config = config[0];
|
||||
let updatedConfig = false;
|
||||
for (const prop in configDefault) {
|
||||
if (prop !== "id" || currentDB.config[prop] === undefined) {
|
||||
updatedConfig = true;
|
||||
currentDB.config[prop] = configDefault[prop];
|
||||
}
|
||||
}
|
||||
if (updatedConfig)
|
||||
await currentDB.persistConfigObject();
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
persistConfigObject: function () {
|
||||
let currentDB = this;
|
||||
return currentDB.runTransactionReadWrite(INTERNAL_USAHAULERSLOGGING_USEHAULERSLOGGINGDBCONFIG_OBJECT_STORE, async function (transaction) {
|
||||
const configStore = transaction.objectStore(INTERNAL_USAHAULERSLOGGING_USEHAULERSLOGGINGDBCONFIG_OBJECT_STORE);
|
||||
|
||||
configStore.put(currentDB.config);
|
||||
|
||||
return transaction.complete;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
//#region basic indexeddb methods
|
||||
$.extend($.usaHaulersLoggingDB, {
|
||||
create: function (deleteIfExists = true) {
|
||||
return new Promise(async function (resolve, reject) {
|
||||
if (deleteIfExists === true) {
|
||||
try {
|
||||
await $.dbManager.deleteDatabase(USAHAULERSLOGGING_DATABASE_NAME);
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
try {
|
||||
await $.dbManager.openDatabase(USAHAULERSLOGGING_DATABASE_NAME, USAHAULERSLOGGING_DATABASE_VERSION, INTERNAL_USAHAULERSLOGGING_ONUPGRADEDNEEDED);
|
||||
}
|
||||
catch (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
},
|
||||
delete: function () {
|
||||
let currentDB = this;
|
||||
return $.dbManager.deleteDatabase(USAHAULERSLOGGING_DATABASE_NAME);
|
||||
},
|
||||
open: function () {
|
||||
let currentDB = this;
|
||||
return $.dbManager.openDatabase(USAHAULERSLOGGING_DATABASE_NAME, USAHAULERSLOGGING_DATABASE_VERSION, INTERNAL_USAHAULERSLOGGING_ONUPGRADEDNEEDED).then(
|
||||
function onSuccessInternal(db) {
|
||||
currentDB.database = db;
|
||||
if (!currentDB.dbInitialized)
|
||||
return currentDB.initializeDB();
|
||||
else
|
||||
return currentDB.refreshConfigObject();
|
||||
},
|
||||
function onErrorInternal(error) {
|
||||
}
|
||||
);
|
||||
},
|
||||
close: function () {
|
||||
let currentDB = this;
|
||||
|
||||
return $.dbManager.closeDatabase(USAHAULERSLOGGING_DATABASE_NAME).then(
|
||||
function onSuccessInternal(db) {
|
||||
currentDB.database = null;
|
||||
},
|
||||
function onErrorInternal(error) {
|
||||
}
|
||||
);
|
||||
},
|
||||
runTransactionReadOnly: function (objectNames, transactionCode) {
|
||||
let currentDB = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (transactionCode != null) {
|
||||
let didOpenDB = false;
|
||||
var onSuccessInternal = function () {
|
||||
let transaction = currentDB.database.transaction(objectNames, "readonly");
|
||||
|
||||
transactionCode(transaction);
|
||||
|
||||
//if (didOpenDB)
|
||||
// currentDB.close();
|
||||
|
||||
transaction.oncomplete = function (event) {
|
||||
resolve();
|
||||
};
|
||||
|
||||
transaction.onerror = function (event) {
|
||||
reject(error.error);
|
||||
};
|
||||
//Transactions auto-commit after scope ends, cannot manually commit
|
||||
};
|
||||
if ($.usaHaulersLoggingDB.database == null) {
|
||||
didOpenDB = true;
|
||||
currentDB.open().then(
|
||||
onSuccessInternal,
|
||||
function onErrorInternal(error) {
|
||||
reject(error);
|
||||
});
|
||||
}
|
||||
else {
|
||||
onSuccessInternal();
|
||||
}
|
||||
}
|
||||
else {
|
||||
reject("No transactionCode passed");
|
||||
}
|
||||
});
|
||||
},
|
||||
runTransactionReadWrite: function (objectNames, transactionCode) {
|
||||
let currentDB = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
if (transactionCode != null) {
|
||||
let didOpenDB = false;
|
||||
var onSuccessInternal = function () {
|
||||
let transaction = currentDB.database.transaction(objectNames, "readwrite");
|
||||
|
||||
transactionCode(transaction);
|
||||
|
||||
//if (didOpenDB)
|
||||
// currentDB.close();
|
||||
|
||||
transaction.oncomplete = function (event) {
|
||||
resolve();
|
||||
};
|
||||
|
||||
transaction.onerror = function (event) {
|
||||
reject(error.error);
|
||||
};
|
||||
//Transactions auto-commit after scope ends, cannot manually commit
|
||||
};
|
||||
if ($.usaHaulersLoggingDB.database == null) {
|
||||
didOpenDB = true;
|
||||
currentDB.open().then(
|
||||
onSuccessInternal,
|
||||
function onErrorInternal(error) {
|
||||
reject(error);
|
||||
});
|
||||
}
|
||||
else {
|
||||
onSuccessInternal();
|
||||
}
|
||||
}
|
||||
else {
|
||||
reject("No transactionCode passed");
|
||||
}
|
||||
});
|
||||
},
|
||||
getObjects: function (objectName, query, indexes) {
|
||||
let currentDB = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
currentDB.runTransactionReadOnly(objectName, function (transaction) {
|
||||
const objectStore = transaction.objectStore(objectName);
|
||||
let request = {};
|
||||
if (indexes && ((typeof indexes === "string" || indexes instanceof String) == false || indexes.length > 0))
|
||||
if (query
|
||||
&& (typeof query === "IDBKeyRange" || query instanceof IDBKeyRange || typeof query === "string" || query instanceof String))
|
||||
request = objectStore.index(indexes).getAll(query);
|
||||
else
|
||||
request = objectStore.index(indexes).getAll();
|
||||
else
|
||||
if (query
|
||||
&& (typeof query === "IDBKeyRange" || query instanceof IDBKeyRange || typeof query === "string" || query instanceof String))
|
||||
request = objectStore.getAll(query);
|
||||
else
|
||||
request = objectStore.getAll()
|
||||
request.onsuccess = function () {
|
||||
if (request.result !== undefined) {
|
||||
objects = request.result;
|
||||
resolve(objects);
|
||||
}
|
||||
else {
|
||||
console.log("no objects found: ", objectName);
|
||||
reject("no objects found: ", objectName);
|
||||
}
|
||||
};
|
||||
request.onerror = function (error) {
|
||||
console.log("Error getting objects(", objectName, ") from db: ", error);
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
});
|
||||
},
|
||||
getObjectsCustom: function (objectName, query, indexes, predicateBlock) {
|
||||
let currentDB = this;
|
||||
return new Promise(function (resolve, reject) {
|
||||
currentDB.runTransactionReadOnly(objectName, function (transaction) {
|
||||
const objectStore = transaction.objectStore(objectName);
|
||||
let request = {};
|
||||
if (indexes && ((typeof indexes === "string" || indexes instanceof String) == false || indexes.length > 0))
|
||||
request = (query && ((typeof query === "string" || query instanceof String) == false || query.length > 0) ? objectStore.index(indexes).getAll(query) : objectStore.index(indexes).getAll());
|
||||
else
|
||||
request = (query && ((typeof query === "string" || query instanceof String) == false || query.length > 0) ? objectStore.getAll(query) : objectStore.getAll());
|
||||
|
||||
request.onsuccess = function () {
|
||||
if (request.result !== undefined) {
|
||||
let objectsUnfiltered = request.result;
|
||||
let objects = [];
|
||||
for (ix in objectsUnfiltered) {
|
||||
if (!predicateBlock || predicateBlock(objectsUnfiltered[ix])) {
|
||||
objects.push(objectsUnfiltered[ix]);
|
||||
}
|
||||
}
|
||||
resolve(objects);
|
||||
}
|
||||
else {
|
||||
console.log("no objects found: ", objectName);
|
||||
reject("no objects found: ", objectName);
|
||||
}
|
||||
};
|
||||
request.onerror = function (error) {
|
||||
console.log("Error getting objects(", objectName, ") from db: ", error);
|
||||
reject(error);
|
||||
};
|
||||
});
|
||||
});
|
||||
},
|
||||
deleteAllObjects: function () {
|
||||
let currentDB = this;
|
||||
var error = null;
|
||||
var objectNames = INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE;
|
||||
return this.runTransactionReadWrite(objectNames, async function (transaction) {
|
||||
const logStore = transaction.objectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE);
|
||||
try {
|
||||
await logStore.clear();
|
||||
}
|
||||
catch (error2) {
|
||||
error = error2;
|
||||
}
|
||||
return transaction.complete;
|
||||
});
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
});
|
||||
//#endregion
|
||||
|
||||
//ADD NON-GENERIC METHODS
|
||||
$.extend($.usaHaulersLoggingDB, {
|
||||
newGuid: function () {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
const r = Math.random() * 16 | 0,
|
||||
v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
},
|
||||
createLogObjectInternal: function (id, level, msg, args, date) {
|
||||
return {
|
||||
id: (id == null ? this.newGuid() : id),
|
||||
version: '1.0',
|
||||
url: window.location.href,
|
||||
application_code: $.cookie('lg_application_code'),
|
||||
application_user_id: $.cookie('lg_application_user_id'),
|
||||
environment_code: $.cookie('lg_environment_code'),
|
||||
level: level,
|
||||
msg: msg,
|
||||
arguments: args,
|
||||
date: (date == null ? new Date() : date),
|
||||
time: (date == null ? new Date() : date).toISOString(),
|
||||
uploaded: false,
|
||||
upload_status: 'Not Uploaded',
|
||||
upload_date: null
|
||||
}
|
||||
},
|
||||
createLogObject: function (level, msg, args) {
|
||||
return this.createLogObjectInternal(null, level, msg, args, null);
|
||||
},
|
||||
addLog: async function (level, msg, args) {
|
||||
let currentDB = this;
|
||||
|
||||
args = currentDB.removeObjectMethodsForSerialization(args);
|
||||
try {
|
||||
await currentDB.refreshConfigObject();
|
||||
var error = null;
|
||||
var log = currentDB.createLogObject(level, msg, args);
|
||||
return this.runTransactionReadWrite(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, async function (transaction) {
|
||||
const logStore = transaction.objectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE);
|
||||
logStore.put(log);
|
||||
return transaction.complete;
|
||||
}).then(
|
||||
function () {
|
||||
},
|
||||
function (errorInternal) {
|
||||
error = errorInternal;
|
||||
}
|
||||
);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
deleteLogs: async function (logs) {
|
||||
let currentDB = this;
|
||||
|
||||
try {
|
||||
await currentDB.refreshConfigObject();
|
||||
var error = null;
|
||||
return this.runTransactionReadWrite(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, async function (transaction) {
|
||||
const logStore = transaction.objectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE);
|
||||
|
||||
logs.forEach((log) => {
|
||||
logStore.delete(log.id);
|
||||
});
|
||||
return transaction.complete;
|
||||
}).then(
|
||||
function () {
|
||||
},
|
||||
function (errorInternal) {
|
||||
error = errorInternal;
|
||||
}
|
||||
);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.log(error);
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
getLogsByLevel: async function (level, startDate, endDate) {
|
||||
let currentDB = this;
|
||||
let levelText = "";
|
||||
if (level != undefined && level != null)
|
||||
levelText = level.toUpperCase();
|
||||
|
||||
let query = levelText;
|
||||
|
||||
let indexes = INTERNAL_USAHAULERSLOGGING_LOG_INDEX_LEVEL;
|
||||
let logs = await currentDB.getObjects(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, query, indexes);
|
||||
let logs2 = [];
|
||||
logs.forEach((log) => {
|
||||
if ((startDate == null || log.date >= startDate) && (endDate == null || log.date <= endDate))
|
||||
logs2.push(log);
|
||||
});
|
||||
|
||||
logs2.sort(function (l1, l2) {
|
||||
return l1.date - l2.date;
|
||||
});
|
||||
|
||||
return logs2;
|
||||
},
|
||||
getLogsAll: async function (startDate, endDate) {
|
||||
let currentDB = this;
|
||||
let query = "";
|
||||
let logs = await currentDB.getObjects(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, query);
|
||||
let logs2 = [];
|
||||
logs.forEach((log) => {
|
||||
if ((startDate == null || log.date >= startDate) && (endDate == null || log.date <= endDate))
|
||||
logs2.push(log);
|
||||
});
|
||||
|
||||
logs2.sort(function (l1, l2) {
|
||||
return l1.date - l2.date;
|
||||
});
|
||||
|
||||
return logs2;
|
||||
},
|
||||
getLogsByUploaded: async function (uploaded, startDate, endDate) {
|
||||
let currentDB = this;
|
||||
let query = uploaded ? "Uploaded" : "Not Uploaded";
|
||||
|
||||
let indexes = INTERNAL_USAHAULERSLOGGING_LOG_INDEX_UPLOADED;
|
||||
let logs = await currentDB.getObjects(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, query, indexes);
|
||||
let logs2 = [];
|
||||
logs.forEach((log) => {
|
||||
if ((startDate == null || log.date >= startDate) && (endDate == null || log.date <= endDate))
|
||||
logs2.push(log);
|
||||
});
|
||||
|
||||
logs2.sort(function (l1, l2) {
|
||||
return l1.date - l2.date;
|
||||
});
|
||||
|
||||
return logs2;
|
||||
},
|
||||
getLogsByUploadStatus: async function (uploadStatus, startDate, endDate) {
|
||||
let currentDB = this;
|
||||
let query = uploadStatus
|
||||
|
||||
let indexes = INTERNAL_USAHAULERSLOGGING_LOG_INDEX_UPLOADED;
|
||||
let logs = await currentDB.getObjects(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, query, indexes);
|
||||
let logs2 = [];
|
||||
logs.forEach((log) => {
|
||||
if ((startDate == null || log.date >= startDate) && (endDate == null || log.date <= endDate))
|
||||
logs2.push(log);
|
||||
});
|
||||
|
||||
logs2.sort(function (l1, l2) {
|
||||
return l1.date - l2.date;
|
||||
});
|
||||
|
||||
return logs2;
|
||||
},
|
||||
markLogsUploaded: async function (logs) {
|
||||
let currentDB = this;
|
||||
|
||||
try {
|
||||
await currentDB.refreshConfigObject();
|
||||
var error = null;
|
||||
|
||||
logs.forEach((log) => {
|
||||
log.uploaded = true;
|
||||
log.upload_status = "Uploaded";
|
||||
log.upload_date = new Date();
|
||||
});
|
||||
return this.runTransactionReadWrite(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE, async function (transaction) {
|
||||
const logStore = transaction.objectStore(INTERNAL_USAHAULERSLOGGING_LOG_OBJECT_STORE);
|
||||
logs.forEach((log) => {
|
||||
logStore.put(log);
|
||||
});
|
||||
return transaction.complete;
|
||||
}).then(
|
||||
function () {
|
||||
},
|
||||
function (errorInternal) {
|
||||
error = errorInternal;
|
||||
}
|
||||
);
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
//throw error;
|
||||
}
|
||||
|
||||
},
|
||||
uploadLogs: async function () {
|
||||
var currentDB = this;
|
||||
try {
|
||||
await currentDB.refreshConfigObject();
|
||||
var logs = null;
|
||||
var maxUploadQty = INTERNAL_USAHAULERSLOGGING_MAXUPLOADQTY;
|
||||
if (maxUploadQty <= 0)
|
||||
maxUploadQty = 999999;
|
||||
|
||||
do {
|
||||
logs = await currentDB.getLogsByUploaded(false, maxUploadQty);
|
||||
if (logs != null && logs.length > 0) {
|
||||
var success = false;
|
||||
|
||||
//try {
|
||||
success = await currentDB.uploadLogChunk(logs);
|
||||
//}
|
||||
//catch {
|
||||
// throw;
|
||||
//}
|
||||
if (!success) {
|
||||
console.debug("currentDB.uploadLogChunk returned false");
|
||||
return false;
|
||||
}
|
||||
//await currentDB.markLogsUploaded(logs);
|
||||
await currentDB.deleteLogs(logs);
|
||||
if (logs.length < maxUploadQty)
|
||||
break;
|
||||
}
|
||||
} while (logs != null && logs.length > 0);
|
||||
return true;
|
||||
}
|
||||
catch (error) {
|
||||
if (!(error instanceof Error))
|
||||
console.error(JSON.stringify(error));
|
||||
else
|
||||
console.error(error);
|
||||
return false;
|
||||
//throw error;
|
||||
}
|
||||
},
|
||||
getLogURL: function () {
|
||||
var environmentCode = $.cookie('lg_environment_code');
|
||||
if (environmentCode === null || environmentCode.trim().length == 0)
|
||||
environmentCode = "DEFAULT";
|
||||
|
||||
environmentCode = environmentCode.toUpperCase();
|
||||
var logUrl = INTERNAL_LOG_URLS[environmentCode];
|
||||
if (logUrl === null || logUrl.trim().length == 0)
|
||||
logUrl = INTERNAL_LOG_URLS['DEFAULT'];
|
||||
return logUrl;
|
||||
},
|
||||
uploadLogChunk: async function (logs) {
|
||||
var currentDB = this;
|
||||
|
||||
var success = false;
|
||||
await $.ajax({
|
||||
type: "POST",
|
||||
url: currentDB.getLogURL(),
|
||||
data: JSON.stringify({ "jsonData": JSON.stringify(logs) }),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json',
|
||||
async: true,
|
||||
cache: false,
|
||||
timeout: 30000,
|
||||
disable_auth_token:true,
|
||||
headers: {
|
||||
lg_session_id: $.cookie('lg_session_guid'),
|
||||
lg_access_token: $.cookie('lg_access_token')
|
||||
},
|
||||
success: function (value, textStatus, request) {
|
||||
var json = value.hasOwnProperty("d") ? $.parseJSON(value.d) : $.parseJSON(value);
|
||||
if (currentDB.getBoolean(json.success)) {
|
||||
success = true;
|
||||
return true;
|
||||
}
|
||||
success = false;
|
||||
return false;
|
||||
},
|
||||
error: function (xhr, error, errorThrown) {
|
||||
//if ((error instanceof jqXHR)
|
||||
// console.error(JSON.stringify(error));
|
||||
//else if (!(error instanceof Error))
|
||||
// console.error(JSON.stringify(error));
|
||||
//else
|
||||
// console.error(error);
|
||||
success = false;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return success;
|
||||
}
|
||||
});
|
||||
|
||||
//TODO: Decide what to do here. This PROBABLY should be a method call that the UI calls on page load, otherwise some calls could happen before this is done/ready. Can't put await on this method, jquery .ready queue will not wait correctly.
|
||||
$(document).ready(function () {
|
||||
$.usaHaulersLoggingDB.open().then(() => {
|
||||
console.log("$.usaHaulersLoggingDB.open() success");
|
||||
return $.usaHaulersLoggingDB.initializeDB();
|
||||
})
|
||||
.then(() => {
|
||||
console.log("$.usaHaulersLoggingDB.initializeDB() success");
|
||||
return $.usaHaulersLoggingDB.uploadLogs();
|
||||
},
|
||||
(error) => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
|
||||
$(document).ajaxSend(function (event, xhr, settings) {
|
||||
if (settings.disable_auth_token) {
|
||||
xhr.setRequestHeader('Auth-Token', null);
|
||||
xhr.setRequestHeader('Auth-Impersonate-Guid', null);
|
||||
xhr.setRequestHeader('Auth-Current-Franchise', null);
|
||||
}
|
||||
});
|
||||
@ -1,404 +0,0 @@
|
||||
|
||||
$.webauthn = {
|
||||
methodCodeRegister: "Register",
|
||||
methodCodeLogin: "Login",
|
||||
isSupported: function () {// Availability of `window.PublicKeyCredential` means webauthn is usable.
|
||||
if (window.PublicKeyCredential && PublicKeyCredential.isConditionalMediationAvailable) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
abortController: new AbortController(),
|
||||
getPublicKey: async function (method, type, username) {
|
||||
let jsonData = {};
|
||||
let error = null;
|
||||
await $.webMethodAsync({
|
||||
'methodPage': 'Webauthn/GetPublicKey',
|
||||
'parameters': { "method": method, "type": type, "username": username },
|
||||
success: function (json) {
|
||||
if (json.success === true || json.success === "true") {
|
||||
jsonData = json.data;
|
||||
}
|
||||
else {
|
||||
error = "success=false";
|
||||
}
|
||||
},
|
||||
error: function (errorInternal) {
|
||||
error = errorInternal;
|
||||
}
|
||||
});
|
||||
|
||||
if (error)
|
||||
throw error;////
|
||||
|
||||
return jsonData;
|
||||
},
|
||||
getPublicKeyForLogin: async function (username) {
|
||||
return $.webauthn.getPublicKey($.webauthn.methodCodeLogin, "Any", username);
|
||||
},
|
||||
authenticate: async function (publicKey) {
|
||||
if (!this.isSupported())
|
||||
throw new Error("webauthn is not supported");
|
||||
|
||||
var publicKeyMain = JSON.parse(JSON.stringify(publicKey));
|
||||
|
||||
if (publicKey.publicKey !== undefined) {
|
||||
publicKey = publicKey.publicKey;
|
||||
}
|
||||
var manager = this;
|
||||
|
||||
if (publicKey.challenge !== undefined)
|
||||
publicKey.challenge = $.webauthn.coerceToArrayBuffer(publicKey.challenge);
|
||||
|
||||
if (publicKey.user !== undefined && publicKey.user.id !== undefined)
|
||||
publicKey.user.id = $.webauthn.coerceToArrayBuffer(publicKey.user.id);
|
||||
|
||||
if (publicKey.excludeCredentials !== undefined && publicKey.excludeCredentials !== null) {
|
||||
for (var exKey of publicKey.excludeCredentials) {
|
||||
if (exKey.id !== undefined && exKey.id !== null)
|
||||
exKey.id = $.webauthn.coerceToArrayBuffer(exKey.id);
|
||||
}
|
||||
}
|
||||
if (publicKey.allowCredentials !== undefined && publicKey.allowCredentials !== null) {
|
||||
for (var allowCred of publicKey.allowCredentials) {
|
||||
if (allowCred.id !== undefined && allowCred.id !== null)
|
||||
allowCred.id = $.webauthn.coerceToArrayBuffer(allowCred.id);
|
||||
}
|
||||
}
|
||||
|
||||
var clientResponse;
|
||||
try {
|
||||
assertedCredential = await navigator.credentials.get({
|
||||
publicKey: publicKey,
|
||||
signal: $.webauthn.abortController.signal
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
showAlert("error", error);
|
||||
return null;
|
||||
}
|
||||
|
||||
let authData = new Uint8Array(assertedCredential.response.authenticatorData);
|
||||
let clientDataJSON = new Uint8Array(assertedCredential.response.clientDataJSON);
|
||||
let rawId = new Uint8Array(assertedCredential.rawId);
|
||||
let sig = new Uint8Array(assertedCredential.response.signature);
|
||||
const data = {
|
||||
id: assertedCredential.id,
|
||||
rawId: $.webauthn.coerceToBase64Url(rawId),
|
||||
type: assertedCredential.type,
|
||||
extensions: assertedCredential.getClientExtensionResults(),
|
||||
response: {
|
||||
authenticatorData: $.webauthn.coerceToBase64Url(authData),
|
||||
clientDataJSON: $.webauthn.coerceToBase64Url(clientDataJSON),
|
||||
signature: $.webauthn.coerceToBase64Url(sig)
|
||||
}
|
||||
};
|
||||
|
||||
return await $.webauthn.verifyKey(data);
|
||||
},
|
||||
saveKey: async function (type, publicKey, newKey) {
|
||||
let error = null;
|
||||
var outputJson = null;
|
||||
await $.webMethodAsync({
|
||||
'methodPage': 'Webauthn/SaveKey',
|
||||
'parameters': { "type": type, "publicKey": publicKey, "newKey": newKey },
|
||||
success: function (json) {
|
||||
if (json.success === true || json.success === "true") {
|
||||
outputJson = json;
|
||||
}
|
||||
else {
|
||||
error = "success=false";
|
||||
}
|
||||
},
|
||||
error: function (errorInternal) {
|
||||
error = errorInternal;
|
||||
}
|
||||
});
|
||||
|
||||
if (error)
|
||||
throw error;
|
||||
|
||||
return outputJson;
|
||||
},
|
||||
verifyKey: async function (clientResponse) {
|
||||
let error = null;
|
||||
var outputJson = null;
|
||||
await $.webMethodAsync({
|
||||
'methodPage': 'Webauthn/VerifyKey',
|
||||
'parameters': { "clientResponse": clientResponse },
|
||||
success: function (json) {
|
||||
if (json.success === true || json.success === "true") {
|
||||
outputJson = json;
|
||||
}
|
||||
else {
|
||||
error = "success=false";
|
||||
}
|
||||
},
|
||||
error: function (errorInternal) {
|
||||
error = errorInternal;
|
||||
}
|
||||
});
|
||||
|
||||
if (error)
|
||||
throw error;
|
||||
|
||||
return outputJson;
|
||||
},
|
||||
passkeys: {
|
||||
typeCode: "passkey",
|
||||
abortController: new AbortController(),
|
||||
isSupported: function () {
|
||||
if ($.webauthn.isSupported()) {
|
||||
return true;
|
||||
//// Check if conditional mediation is available.
|
||||
//const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
|
||||
//if (isCMA) {
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getPublicKeyForRegister: async function (username) {
|
||||
return $.webauthn.getPublicKey($.webauthn.methodCodeRegister, this.typeCode, username);
|
||||
},
|
||||
getPublicKeyForLogin: async function (username) {
|
||||
return $.webauthn.getPublicKey($.webauthn.methodCodeLogin, this.typeCode, username);
|
||||
},
|
||||
authenticate: async function (publicKey) {
|
||||
if (!this.isSupported())
|
||||
throw new Error("webauthn/passkeys is not supported");
|
||||
|
||||
return $.webauthn.authenticate(publicKey);
|
||||
},
|
||||
create: async function (publicKey) {
|
||||
if (!this.isSupported())
|
||||
throw new Error("webauthn/passkeys is not supported");
|
||||
|
||||
var publicKeyMain = JSON.parse(JSON.stringify(publicKey));
|
||||
|
||||
if (publicKey.publicKey !== undefined) {
|
||||
publicKey = publicKey.publicKey;
|
||||
}
|
||||
var manager = this;
|
||||
|
||||
if (publicKey.challenge !== undefined)
|
||||
publicKey.challenge = $.webauthn.coerceToArrayBuffer(publicKey.challenge);
|
||||
|
||||
if (publicKey.user !== undefined && publicKey.user.id !== undefined)
|
||||
publicKey.user.id = $.webauthn.coerceToArrayBuffer(publicKey.user.id);
|
||||
|
||||
if (publicKey.excludeCredentials !== undefined && publicKey.excludeCredentials !== null) {
|
||||
for (var exKey of publicKey.excludeCredentials) {
|
||||
if (exKey.id !== undefined && exKey.id !== null)
|
||||
exKey.id = $.webauthn.coerceToArrayBuffer(exKey.id);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var credential = await navigator.credentials.create({
|
||||
publicKey: publicKey,
|
||||
signal: $.webauthn.abortController.signal
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
showAlert("error", error);
|
||||
return null;
|
||||
}
|
||||
|
||||
var credential2 = {
|
||||
authenticatorAttachment: credential.authenticatorAttachment,
|
||||
id: credential.id,
|
||||
rawId: $.webauthn.coerceToBase64Url(credential.rawId),
|
||||
type: credential.type,
|
||||
extensions: credential.getClientExtensionResults(),
|
||||
response: {
|
||||
attestationObject: $.webauthn.coerceToBase64Url(credential.response.attestationObject),
|
||||
clientDataJSON: $.webauthn.coerceToBase64Url(credential.response.clientDataJSON),
|
||||
transports: credential.response.getTransports()
|
||||
},
|
||||
type: credential.type
|
||||
}
|
||||
|
||||
var publicKey2 = JSON.parse(JSON.stringify(publicKey));
|
||||
publicKey2.user.id = publicKeyMain.publicKey.user.id;
|
||||
publicKey2.challenge = publicKeyMain.publicKey.challenge;
|
||||
var keySaved = await $.webauthn.saveKey(this.typeCode, publicKey2, credential2);
|
||||
|
||||
if ($.getBoolean(keySaved.success))
|
||||
showAlert("success", "Key created");
|
||||
else
|
||||
showAlert("error", "Key creation failed");
|
||||
}
|
||||
},
|
||||
securityKeys: {
|
||||
typeCode: "securitykey",
|
||||
abortController: new AbortController(),
|
||||
isSupported: function () {
|
||||
if ($.webauthn.isSupported()) {
|
||||
return true;
|
||||
//// Check if conditional mediation is available.
|
||||
//const isCMA = await PublicKeyCredential.isConditionalMediationAvailable();
|
||||
//if (isCMA) {
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
getPublicKeyForRegister: async function (username) {
|
||||
return $.webauthn.getPublicKey($.webauthn.methodCodeRegister, this.typeCode, username);
|
||||
},
|
||||
getPublicKeyForLogin: async function (username) {
|
||||
return $.webauthn.getPublicKey($.webauthn.methodCodeLogin, this.typeCode, username);
|
||||
},
|
||||
saveKey: async function (publicKey, newKey) {
|
||||
return $.webauthn.saveKey(this.typeCode, publicKey, newKey);
|
||||
},
|
||||
authenticate: async function (publicKey) {
|
||||
if (!this.isSupported())
|
||||
throw new Error("webauthn/securityKeys is not supported");
|
||||
|
||||
return $.webauthn.authenticate(publicKey);
|
||||
},
|
||||
create: async function (publicKey) {
|
||||
if (!this.isSupported())
|
||||
throw new Error("webauthn/securityKeys is not supported");
|
||||
|
||||
var publicKeyMain = JSON.parse(JSON.stringify(publicKey));
|
||||
|
||||
if (publicKey.publicKey !== undefined) {
|
||||
publicKey = publicKey.publicKey;
|
||||
}
|
||||
var manager = this;
|
||||
|
||||
if (publicKey.challenge !== undefined)
|
||||
publicKey.challenge = $.webauthn.coerceToArrayBuffer(publicKey.challenge);
|
||||
|
||||
if (publicKey.user !== undefined && publicKey.user.id !== undefined)
|
||||
publicKey.user.id = $.webauthn.coerceToArrayBuffer(publicKey.user.id);
|
||||
|
||||
if (publicKey.excludeCredentials !== undefined && publicKey.excludeCredentials !== null) {
|
||||
for (var exKey of publicKey.excludeCredentials) {
|
||||
if (exKey.id !== undefined && exKey.id !== null)
|
||||
exKey.id = $.webauthn.coerceToArrayBuffer(exKey.id);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var credential = await navigator.credentials.create({
|
||||
publicKey: publicKey,
|
||||
signal: $.webauthn.abortController.signal
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
console.error(error);
|
||||
showAlert("error", error);
|
||||
return null;
|
||||
}
|
||||
|
||||
var credential2 = {
|
||||
authenticatorAttachment: credential.authenticatorAttachment,
|
||||
id: credential.id,
|
||||
rawId: $.webauthn.coerceToBase64Url(credential.rawId),
|
||||
type: credential.type,
|
||||
extensions: credential.getClientExtensionResults(),
|
||||
response: {
|
||||
attestationObject: $.webauthn.coerceToBase64Url(credential.response.attestationObject),
|
||||
clientDataJSON: $.webauthn.coerceToBase64Url(credential.response.clientDataJSON),
|
||||
transports: credential.response.getTransports()
|
||||
},
|
||||
type: credential.type
|
||||
}
|
||||
|
||||
var publicKey2 = JSON.parse(JSON.stringify(publicKey));
|
||||
publicKey2.user.id = publicKeyMain.publicKey.user.id;
|
||||
publicKey2.challenge = publicKeyMain.publicKey.challenge;
|
||||
var keySaved = await $.webauthn.saveKey(this.typeCode, publicKey2, credential2);
|
||||
|
||||
if ($.getBoolean(keySaved.success))
|
||||
showAlert("success", "Key created");
|
||||
else
|
||||
showAlert("error", "Key creation failed");
|
||||
}
|
||||
},
|
||||
stringToArrayBuffer: function (string) {
|
||||
var string2 = (typeof string !== "string" ? string.toString() : string);
|
||||
return Uint8Array.from(string2, c => c.charCodeAt(0));
|
||||
},
|
||||
arrayBufferToString: function (buffer) {
|
||||
return String.fromCharCode.apply(null, new Uint8Array(buffer));
|
||||
},
|
||||
arrayBufferToBase64String: function (buffer) {
|
||||
return window.btoa(String.fromCharCode.apply(null, new Uint8Array(buffer)));
|
||||
},
|
||||
coerceToArrayBuffer: function (thing, name) {
|
||||
if (thing === undefined || thing === null)
|
||||
return null;
|
||||
|
||||
if (typeof thing === "string") {
|
||||
// base64url to base64
|
||||
thing = thing.replace(/-/g, "+").replace(/_/g, "/");
|
||||
|
||||
// base64 to Uint8Array
|
||||
var str = window.atob(thing);
|
||||
var bytes = new Uint8Array(str.length);
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
bytes[i] = str.charCodeAt(i);
|
||||
}
|
||||
thing = bytes;
|
||||
}
|
||||
|
||||
// Array to Uint8Array
|
||||
if (Array.isArray(thing)) {
|
||||
thing = new Uint8Array(thing);
|
||||
}
|
||||
|
||||
// Uint8Array to ArrayBuffer
|
||||
if (thing instanceof Uint8Array) {
|
||||
thing = thing.buffer;
|
||||
}
|
||||
|
||||
// error if none of the above worked
|
||||
if (!(thing instanceof ArrayBuffer)) {
|
||||
throw new TypeError("could not coerce '" + name + "' to ArrayBuffer");
|
||||
}
|
||||
|
||||
return thing;
|
||||
},
|
||||
|
||||
coerceToBase64Url: function (thing) {
|
||||
if (thing === undefined || thing === null)
|
||||
return null;
|
||||
|
||||
// Array or ArrayBuffer to Uint8Array
|
||||
if (Array.isArray(thing)) {
|
||||
thing = Uint8Array.from(thing);
|
||||
}
|
||||
|
||||
if (thing instanceof ArrayBuffer) {
|
||||
thing = new Uint8Array(thing);
|
||||
}
|
||||
|
||||
// Uint8Array to base64
|
||||
if (thing instanceof Uint8Array) {
|
||||
var str = "";
|
||||
var len = thing.byteLength;
|
||||
|
||||
for (var i = 0; i < len; i++) {
|
||||
str += String.fromCharCode(thing[i]);
|
||||
}
|
||||
thing = window.btoa(str);
|
||||
}
|
||||
|
||||
if (typeof thing !== "string") {
|
||||
throw new Error("could not coerce to string");
|
||||
}
|
||||
|
||||
// base64 to base64url
|
||||
// NOTE: "=" at the end of challenge is optional, strip it off here
|
||||
//thing = thing.replace(/\+/g, "-").replace(/\//g, "_").replace(/=*$/g, "");
|
||||
|
||||
return thing;
|
||||
}
|
||||
}
|
||||
@ -1,149 +0,0 @@
|
||||
|
||||
|
||||
async function CheckAuthToken() {
|
||||
|
||||
var data = null;
|
||||
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
callMethod("CheckAuthToken", {}).then((data) => {
|
||||
//return the first element in the array for this call.
|
||||
resolve(data[0]);
|
||||
}).catch((data) => {
|
||||
reject(data);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function GetVehicles() {
|
||||
var data = null;
|
||||
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
callMethod("GetVehicles", {}).then((data) => {
|
||||
//return the first element in the array for this call.
|
||||
resolve(data);
|
||||
}).catch((data) => {
|
||||
reject(data);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function SaveVehicle(vehicleId, vehicleData)
|
||||
{
|
||||
var data = null;
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
callMethod("SaveVehicle", {"vehicleId":vehicleId, "jsonData": JSON.stringify(vehicle) }).then((data) => {
|
||||
//return the first element in the array for this call.
|
||||
resolve(data);
|
||||
}).catch((data) => {
|
||||
reject(data);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function GetVehicleImages(vehicleID) {
|
||||
var data = null;
|
||||
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
callMethod("GetVehicleImages", { "vehicleID": vehicleID }).then((data) => {
|
||||
//return the first element in the array for this call.
|
||||
resolve(data);
|
||||
}).catch((data) => {
|
||||
reject(data);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function SaveCurrentUser() {
|
||||
|
||||
user = currentUser;
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
callMethod("SaveUser", { "userJson": JSON.stringify(user) }).then((data) => {
|
||||
resolve(data);
|
||||
}).catch((data) => {
|
||||
reject(data);
|
||||
});
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function ServerHealthCheck() {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.webMethod({
|
||||
'methodPage': 'UserMethods/',
|
||||
'methodName': "ServerHealthCheck",
|
||||
'parameters': {},
|
||||
'timeout': 3000,
|
||||
success: function (json) {
|
||||
|
||||
if ($.getBoolean(json.success)) {
|
||||
|
||||
data = json;
|
||||
resolve(data);
|
||||
}
|
||||
else {
|
||||
data = json;
|
||||
reject(data);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
reject(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
async function callMethod(methodName, parameters) {
|
||||
return new Promise((resolve, reject) => {
|
||||
$.webMethod({
|
||||
'methodPage': 'UserMethods',
|
||||
'methodName': methodName,
|
||||
'parameters': parameters,
|
||||
'timeout': 60000,
|
||||
success: function (json) {
|
||||
|
||||
if (json.data != null) {
|
||||
data = json.data;
|
||||
}
|
||||
else {
|
||||
data = json;
|
||||
}
|
||||
|
||||
if ($.getBoolean(json.success)) {
|
||||
resolve(data);
|
||||
}
|
||||
else {
|
||||
reject(data);
|
||||
}
|
||||
},
|
||||
error: function (data) {
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -7,6 +7,12 @@ export const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
|
||||
|
||||
|
||||
// Add global values to window object for use in static JS
|
||||
declare global {
|
||||
interface Window {
|
||||
API_BASE_URL: object
|
||||
}
|
||||
}
|
||||
if (typeof window !== 'undefined') {
|
||||
|
||||
window.API_BASE_URL = API_BASE_URL;
|
||||
}
|
||||
@ -44,8 +44,8 @@ const utils = {
|
||||
baseMethodPath?: string;
|
||||
methodPage?: string;
|
||||
methodName?: string;
|
||||
parameters?: Record<string, any>;
|
||||
contentType?: string;
|
||||
parameters?: Record<string, any>;
|
||||
timeout?: number;
|
||||
success?: (data: any) => void;
|
||||
error?: (err: any) => void;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user