From 384a037b52163ae76209204273f6f94170c404ae Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 00:55:06 -0800 Subject: [PATCH 01/26] Update README.md Master build icon from appveyor to GH Actions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7376d6e..bdf56e9 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A useful class library for universal utilities like encryption, sending emails, | Master | Develop | NuGet | | ----- | ----- | ----- | -| [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/master?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/master) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [![NuGet Package](https://buildstats.info/nuget/Devlord.Utilities)](https://www.nuget.org/packages/Devlord.Utilities/) | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [![NuGet Package](https://buildstats.info/nuget/Devlord.Utilities)](https://www.nuget.org/packages/Devlord.Utilities/) | To install Devlord.Utilities, run the following command in the Package Manager Console: From 11cc6437c9cd81cb2e635f3d265c49d1ad7ab7d8 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 01:00:57 -0800 Subject: [PATCH 02/26] Update README.md package info icon deprecated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bdf56e9..ac41bab 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ A useful class library for universal utilities like encryption, sending emails, | Master | Develop | NuGet | | ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [![NuGet Package](https://buildstats.info/nuget/Devlord.Utilities)](https://www.nuget.org/packages/Devlord.Utilities/) | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | To install Devlord.Utilities, run the following command in the Package Manager Console: From 45a2f19ecece367e3b57a43fbad2ee5e933ee27e Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 01:06:57 -0800 Subject: [PATCH 03/26] Prep packing for v7 --- .github/workflows/package.yml | 30 +++++++++++++++++++ Devlord.Utilities.sln.DotSettings | 7 +++-- .../Devlord.Utilities.csproj | 10 +++++-- src/Encryptamajig/Encryptamajig.csproj | 2 +- 4 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 .github/workflows/package.yml diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 0000000..a7e9494 --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,30 @@ +name: Publish NuGet package + +on: + release: + types: [ created ] + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v5 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: 10.0.x + + - name: Build release + run: dotnet build --configuration Release + - name: Pack prerelease with build number + if: "github.event.release.prerelease" + run: | + dotnet pack --configuration Release --output ./nupkg \ + -p:VersionSuffix="preview.${{ github.run_number }}" + - name: Pack release + if: "!github.event.release.prerelease" + run: dotnet pack --configuration Release --output ./nupkg + - name: Publish the package to NuGet + run: dotnet nuget push "./nupkg/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json \ No newline at end of file diff --git a/Devlord.Utilities.sln.DotSettings b/Devlord.Utilities.sln.DotSettings index e64a9f3..e6ce0c5 100644 --- a/Devlord.Utilities.sln.DotSettings +++ b/Devlord.Utilities.sln.DotSettings @@ -1,19 +1,20 @@  -------------------------------------------------------------------------------------------------------------------- -<copyright file="$FILENAME$" company="Lord Design"> - © $CURRENT_YEAR$ Lord Design +<copyright file="${File.FileName}" company="Lord Design"> + © ${CurrentDate.Year} Lord Design </copyright> <license type="GPL-3.0"> You may use freely and commercially without modification; if you make changes, please share back to the community. </license> -<author>$USER_NAME$</author> +<author>${User.Name}</author> -------------------------------------------------------------------------------------------------------------------- DR True True True + True <data><IncludeFilters /><ExcludeFilters><Filter ModuleMask="Devlord.Utilities" ModuleVersionMask="*" ClassMask="Devlord.Utilities.Properties.*" FunctionMask="*" IsEnabled="True" /><Filter ModuleMask="Devlord.Utilities" ModuleVersionMask="*" ClassMask="Devlord.Utilities.Resources.*" FunctionMask="*" IsEnabled="True" /></ExcludeFilters></data> True True diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 7a060bc..6af4d97 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -1,15 +1,15 @@ - netstandard2.1;net6.0 + netstandard2.1;net8.0 false false false false - 6.0.0 + 7.0.0 Devlords Cooperative devlord https://github.com/lorddev/utilities - Copyright © 2022 Aaron Lord + Copyright © 2026 Aaron Lord https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png https://github.com/lorddev/utilities @@ -21,6 +21,7 @@ true Devlord.Utilities.nuspec 22b9d517-6954-4beb-b7be-ba24eb9ac441 + README.md @@ -44,6 +45,9 @@ ExceptionText.resx + + + ResXFileCodeGenerator diff --git a/src/Encryptamajig/Encryptamajig.csproj b/src/Encryptamajig/Encryptamajig.csproj index 54a3401..71405af 100644 --- a/src/Encryptamajig/Encryptamajig.csproj +++ b/src/Encryptamajig/Encryptamajig.csproj @@ -1,7 +1,7 @@  - netstandard2.1;net6.0 + netstandard2.1;net8.0 false false false From d69f67eed3be068ea2420d88779fe0f468c0fcb4 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 01:16:34 -0800 Subject: [PATCH 04/26] Only pack the main project --- .github/workflows/package.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index a7e9494..b8dc167 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -17,14 +17,14 @@ jobs: dotnet-version: 10.0.x - name: Build release - run: dotnet build --configuration Release + run: dotnet build src/Devlord.Utilities/Devlord.Utilities.csproj --configuration Release - name: Pack prerelease with build number if: "github.event.release.prerelease" run: | - dotnet pack --configuration Release --output ./nupkg \ + dotnet pack src/Devlord.Utilities/Devlord.Utilities.csproj --configuration Release --output ./nupkg \ -p:VersionSuffix="preview.${{ github.run_number }}" - name: Pack release if: "!github.event.release.prerelease" - run: dotnet pack --configuration Release --output ./nupkg + run: dotnet pack src/Devlord.Utilities/Devlord.Utilities.csproj --configuration Release --output ./nupkg - name: Publish the package to NuGet run: dotnet nuget push "./nupkg/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json \ No newline at end of file From f2f939b9ebe62732ccce98a290f3a35d227813e3 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 01:30:30 -0800 Subject: [PATCH 05/26] Fix broken build --- .../Devlord.Utilities.csproj | 2 +- src/Devlord.Utilities/package-lock.json | 984 ++++++++++++++++++ src/Encryptamajig/Encryptamajig.csproj | 8 +- 3 files changed, 986 insertions(+), 8 deletions(-) create mode 100644 src/Devlord.Utilities/package-lock.json diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 6af4d97..9187a0a 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -1,6 +1,6 @@ - netstandard2.1;net8.0 + net8.0 false false false diff --git a/src/Devlord.Utilities/package-lock.json b/src/Devlord.Utilities/package-lock.json new file mode 100644 index 0000000..efd9be1 --- /dev/null +++ b/src/Devlord.Utilities/package-lock.json @@ -0,0 +1,984 @@ +{ + "name": "asp.net", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "asp.net", + "version": "1.0.0", + "devDependencies": { + "gulp-bump": "0.1.9" + } + }, + "node_modules/ansi-regex": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "integrity": "sha512-sGwIGMjhYdW26/IhwK2gkWWI8DRCVO6uj3hYgHT+zD+QL1pa37tM3ujhyfcJIYSbsxp7Gxhy7zrRW/1AHm4BmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", + "integrity": "sha512-f2PKUkN5QngiSemowa6Mrk9MPCdtFiOSmibjZ+j1qhLGHHYsqZwmBMRF3IRMVXo8sybDqx2fJl2d/8OphBoWkA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chalk": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "integrity": "sha512-bIKA54hP8iZhyDT81TOsJiQvR1gW+ZYSXFaZUAvoD4wCHdbHY2actmpTE4x344ZlFqHbvoxKOaESULTZN2gstg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^1.1.0", + "escape-string-regexp": "^1.0.0", + "has-ansi": "^0.1.0", + "strip-ansi": "^0.3.0", + "supports-color": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dateformat": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", + "integrity": "sha512-5sFRfAAmbHdIts+eKjR9kYJoF0ViCMVX9yqLu5A7S/v+nd077KgCITOMiirmyCBiZpKLDXbBOkYm6tu7rX/TKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-stdin": "^4.0.1", + "meow": "^3.3.0" + }, + "bin": { + "dateformat": "bin/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/duplexer2": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "integrity": "sha512-+AWBwjGadtksxjOQSFDhPNQbed7icNXApT4+2BNpsXzcCBiInq2H9XW0O8sfHFaPmnQRs7cg/P0fAr2IWQSW0g==", + "dev": true, + "license": "BSD", + "dependencies": { + "readable-stream": "~1.1.9" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/gulp-bump": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/gulp-bump/-/gulp-bump-0.1.9.tgz", + "integrity": "sha512-p+SP6YF62hHSwwqXaR64Z991OhGlF4OQ1B9T7R6ryo4FdIgo3tf/XInOapT5++KkMVTV215gKgocKXMEF+1DLQ==", + "dev": true, + "dependencies": { + "gulp-util": "^2.2.14", + "semver": "^2.2.1", + "through2": "^0.5.1" + }, + "engines": { + "node": ">= 0.9.0" + } + }, + "node_modules/gulp-util": { + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-2.2.20.tgz", + "integrity": "sha512-9rtv4sj9EtCWYGD15HQQvWtRBtU9g1t0+w29tphetHxjxEAuBKQJkhGqvlLkHEtUjEgoqIpsVwPKU1yMZAa+wA==", + "deprecated": "gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5", + "dev": true, + "dependencies": { + "chalk": "^0.5.0", + "dateformat": "^1.0.7-1.2.3", + "lodash._reinterpolate": "^2.4.1", + "lodash.template": "^2.4.1", + "minimist": "^0.2.0", + "multipipe": "^0.1.0", + "through2": "^0.5.0", + "vinyl": "^0.2.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/has-ansi": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", + "integrity": "sha512-1YsTg1fk2/6JToQhtZkArMkurq8UoWU1Qe0aR3VUHjgij4nOylSWLWAtBXoZ4/dXOmugfLGm1c+QhuD0JyedFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^0.2.0" + }, + "bin": { + "has-ansi": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==", + "dev": true, + "license": "MIT", + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lodash._escapehtmlchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz", + "integrity": "sha512-eHm2t2Lg476lq5v4FVmm3B5mCaRlDyTE8fnMfPCEq2o46G4au0qNXIKh7YWhjprm1zgSMLcMSs1XHMgkw02PbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._htmlescapes": "~2.4.1" + } + }, + "node_modules/lodash._escapestringchar": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz", + "integrity": "sha512-iZ6Os4iipaE43pr9SBks+UpZgAjJgRC+lGf7onEoByMr1+Nagr1fmR7zCM6Q4RGMB/V3a57raEN0XZl7Uub3/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._htmlescapes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz", + "integrity": "sha512-g79hNmMOBVyV+4oKIHM7MWy9Awtk3yqf0Twlawr6f+CmG44nTwBh9I5XiLUnk39KTfYoDBpS66glQGgQCnFIuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._isnative": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz", + "integrity": "sha512-BOlKGKNHhCHswGOWtmVb5zBygyxN7EmTuzVOSQI6QSoGhG+kvv71gICFS1TBpnqvT1n53txK8CDK3u5D2/GZxQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._objecttypes": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz", + "integrity": "sha512-XpqGh1e7hhkOzftBfWE7zt+Yn9mVHFkDhicVttvKLsoCMLVVL+xTQjfjB4X4vtznauxv0QZ5ZAeqjvat0dh62Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._reinterpolate": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz", + "integrity": "sha512-QGEOOjJi7W9LIgDAMVgtGBb8Qgo8ieDlSOCoZjtG45ZNRvDJZjwVMTYlfTIWdNRUiR1I9BjIqQ3Zaf1+DYM94g==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash._reunescapedhtml": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz", + "integrity": "sha512-CfmZRU1Mk4E/5jh+Wu8lc7tuc3VkuwWZYVIgdPDH9NRSHgiL4Or3AA4JCIpgrkVzHOM+jKu2OMkAVquruhRHDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._htmlescapes": "~2.4.1", + "lodash.keys": "~2.4.1" + } + }, + "node_modules/lodash._shimkeys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz", + "integrity": "sha512-lBrglYxLD/6KAJ8IEa5Lg+YHgNAL7FyKqXg4XOUI+Du/vtniLs1ZqS+yHNKPkK54waAgkdUnDOYaWf+rv4B+AA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._objecttypes": "~2.4.1" + } + }, + "node_modules/lodash.defaults": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz", + "integrity": "sha512-5wTIPWwGGr07JFysAZB8+7JB2NjJKXDIwogSaRX5zED85zyUAQwtOqUk8AsJkkigUcL3akbHYXd5+BPtTGQPZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._objecttypes": "~2.4.1", + "lodash.keys": "~2.4.1" + } + }, + "node_modules/lodash.escape": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz", + "integrity": "sha512-PiEStyvZ8gz37qBE+HqME1Yc/ewb/59AMOu8pG7Ztani86foPTxgzckQvMdphmXPY6V5f20Ex/CaNBqHG4/ycQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._escapehtmlchar": "~2.4.1", + "lodash._reunescapedhtml": "~2.4.1", + "lodash.keys": "~2.4.1" + } + }, + "node_modules/lodash.isobject": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz", + "integrity": "sha512-sTebg2a1PoicYEZXD5PBdQcTlIJ6hUslrlWr7iV0O7n+i4596s2NQ9I5CaZ5FbXSfya/9WQsrYLANUJv9paYVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._objecttypes": "~2.4.1" + } + }, + "node_modules/lodash.keys": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz", + "integrity": "sha512-ZpJhwvUXHSNL5wYd1RM6CUa2ZuqorG9ngoJ9Ix5Cce+uX7I5O/E06FCJdhSZ33b5dVyeQDnIlWH7B2s5uByZ7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._isnative": "~2.4.1", + "lodash._shimkeys": "~2.4.1", + "lodash.isobject": "~2.4.1" + } + }, + "node_modules/lodash.template": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz", + "integrity": "sha512-5yLOQwlS69xbaez3g9dA1i0GMAj8pLDHp8lhA4V7M1vRam1lqD76f0jg5EV+65frbqrXo1WH9ZfKalfYBzJ5yQ==", + "deprecated": "This package is deprecated. Use https://socket.dev/npm/package/eta instead.", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._escapestringchar": "~2.4.1", + "lodash._reinterpolate": "~2.4.1", + "lodash.defaults": "~2.4.1", + "lodash.escape": "~2.4.1", + "lodash.keys": "~2.4.1", + "lodash.templatesettings": "~2.4.1", + "lodash.values": "~2.4.1" + } + }, + "node_modules/lodash.templatesettings": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz", + "integrity": "sha512-vY3QQ7GxbeLe8XfTvoYDbaMHO5iyTDJS1KIZrxp00PRMmyBKr8yEcObHSl2ppYTwd8MgqPXAarTvLA14hx8ffw==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash._reinterpolate": "~2.4.1", + "lodash.escape": "~2.4.1" + } + }, + "node_modules/lodash.values": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", + "integrity": "sha512-fQwubKvj2Nox2gy6YnjFm8C1I6MIlzKUtBB+Pj7JGtloGqDDL5CPRr4DUUFWPwXWwAl2k3f4C3Aw8H1qAPB9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash.keys": "~2.4.1" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minimist": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.4.tgz", + "integrity": "sha512-Pkrrm8NjyQ8yVt8Am9M+yUt74zE3iokhzbG1bFVNjLB92vwM71hf40RkEsryg98BujhVOncKm/C1xROxZ030LQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/multipipe": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "integrity": "sha512-7ZxrUybYv9NonoXgwoOqtStIu18D1c3eFZj27hqgf5kBrBF8Q+tE8V0MW8dKM5QLkQPh1JhhbKgHLY9kifov4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer2": "0.0.2" + } + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pinkie": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-2.3.2.tgz", + "integrity": "sha512-abLdIKCosKfpnmhS52NCTjO4RiLspDfsn37prjzGrp9im5DPJOgh82Os92vtwGh6XdQryKI/7SREZnV+aqiXrA==", + "dev": true, + "license": "BSD", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/strip-ansi": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "integrity": "sha512-DerhZL7j6i6/nEnVG0qViKXI0OKouvvpsAiaj7c+LfqZZZxdwZtv8+UiA/w4VUJpT8UzX0pR1dcHOii1GbmruQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^0.2.1" + }, + "bin": { + "strip-ansi": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", + "integrity": "sha512-tdCZ28MnM7k7cJDJc7Eq80A9CsRFAAOZUy41npOZCs++qSjfIy7o5Rh46CBk+Dk5FbKJ33X3Tqg4YrV07N5RaA==", + "dev": true, + "license": "MIT", + "bin": { + "supports-color": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/through2": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.5.1.tgz", + "integrity": "sha512-zexCrAOTbjkBCXGyozn7hhS3aEaqdrc59mAD2E3dKYzV1vFuEGQ1hEDJN2oQMQFwy4he2zyLqPZV+AlfS8ZWJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~1.0.17", + "xtend": "~3.0.0" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha512-ok1qVCJuRkNmvebYikljxJA/UEsKwLl2nI1OmaqAu4/UE+h0wKCHok4XkL/gvi39OacXvw59RJUOFUkDib2rHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/vinyl": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.2.3.tgz", + "integrity": "sha512-4gFk9xrecazOTuFKcUYrE1TjHSYL63dio72D+q0d1mHF51FEcxTT2RHFpHbN5TNJgmPYHuVsBdhvXEOCDcytSA==", + "dev": true, + "dependencies": { + "clone-stats": "~0.0.1" + }, + "engines": { + "node": ">= 0.9" + } + }, + "node_modules/xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha512-sp/sT9OALMjRW1fKDlPeuSZlDQpkqReA0pyJukniWbTGoEKefHxhGJynE3PNhUMlcM8qWIjPwecwCw4LArS5Eg==", + "dev": true, + "engines": { + "node": ">=0.4" + } + } + } +} diff --git a/src/Encryptamajig/Encryptamajig.csproj b/src/Encryptamajig/Encryptamajig.csproj index 71405af..76ecafb 100644 --- a/src/Encryptamajig/Encryptamajig.csproj +++ b/src/Encryptamajig/Encryptamajig.csproj @@ -18,13 +18,7 @@ Git Encryption - - - - - - 1.0.0 - + From 03c497f2703b484be8a73d0933d319ce64152457 Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 01:35:33 -0800 Subject: [PATCH 06/26] Reconfigure without nuspec --- .../Devlord.Utilities.csproj | 1 - .../Devlord.Utilities.nuspec | 99 ------------------- .../Devlord.Utilities.nuspec2 | 33 ------- 3 files changed, 133 deletions(-) delete mode 100644 src/Devlord.Utilities/Devlord.Utilities.nuspec delete mode 100644 src/Devlord.Utilities/Devlord.Utilities.nuspec2 diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 9187a0a..41776bc 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -19,7 +19,6 @@ ... true - Devlord.Utilities.nuspec 22b9d517-6954-4beb-b7be-ba24eb9ac441 README.md diff --git a/src/Devlord.Utilities/Devlord.Utilities.nuspec b/src/Devlord.Utilities/Devlord.Utilities.nuspec deleted file mode 100644 index 30c605a..0000000 --- a/src/Devlord.Utilities/Devlord.Utilities.nuspec +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - Devlord.Utilities - - - 6.0.0 - Devlord.Utilities - - - Aaron Lord - - - devlord - - - https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE - https://github.com/lorddev/utilities - - - https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png - - - false - Utilities class library so you don't have to rewrite your utilities on every project. - - - * Upgraded .NET targets to netstandard2.1 and net6.0 - * Refactored configuration for MailbotFactory and Throttles (see README) - * Fixed bugs in API querystrings - - - Multipurpose universal utilities library so you don't have to write your own utils for every project. Includes extensions, encapsulation of logging and encryption, basic datareader-to-POCO mapping, a mailer throttle, and strongly-typed API callers. - - - Copyright © 2022 Aaron Lord - - - utils utilities email distance-matrix micro-orm logging encryption - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Devlord.Utilities/Devlord.Utilities.nuspec2 b/src/Devlord.Utilities/Devlord.Utilities.nuspec2 deleted file mode 100644 index 501b9ad..0000000 --- a/src/Devlord.Utilities/Devlord.Utilities.nuspec2 +++ /dev/null @@ -1,33 +0,0 @@ - - - - - Devlord.Utilities - 5.0.0 - Devlord.Utilities - lorddev/authors> - Devlords Cooperative - https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE - https://github.com/lorddev/utilities - https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png - false - Multipurpose universal utilities library so you don't have to write your own utils for every project. Includes extensions, encapsulation of logging and encryption, DataReader-to-POCO mapping, a mailer throttle, and strongly-typed API callers. Also includes a .NET Core-compatible build of Encryptamajig. - New IDataReader mapper for dynamic ORM. - Copyright © 2017 Aaron Lord - utils utilities email distance-matrix micro-orm logging encryption - - - - - - - - - \ No newline at end of file From 720080804651721645e8b2898c77217694a6211c Mon Sep 17 00:00:00 2001 From: Aaron Date: Tue, 17 Feb 2026 01:46:56 -0800 Subject: [PATCH 07/26] Configuration --- .github/workflows/package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index b8dc167..8741179 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -14,8 +14,8 @@ jobs: - uses: actions/checkout@v5 - uses: actions/setup-dotnet@v4 with: - dotnet-version: 10.0.x - + dotnet-version: 8.0.x + - name: Build release run: dotnet build src/Devlord.Utilities/Devlord.Utilities.csproj --configuration Release - name: Pack prerelease with build number From 71bebe532c126d1cf673bb162e8e7f13ae25be1f Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 21 Feb 2026 11:08:44 -0800 Subject: [PATCH 08/26] Remove Encryptamajig entirely The cryptography used in Encryptamajig is outdated. It was using Rfc2898DeriveBytes of which there are no remaining non-obsolete constructors in the .NET library. --- Devlord.Utilities.sln | 14 -- README.md | 6 - src/Devlord.Utilities/App_Readme/Elmah.txt | 15 -- src/Devlord.Utilities/Cryptography/Crypt.cs | 79 ---------- .../Devlord.Utilities.csproj | 23 +-- src/Devlord.Utilities/Logger.Core.cs | 4 +- src/Devlord.Utilities/Mailbot.cs | 25 +-- src/Devlord.Utilities/MailbotFactory.cs | 2 +- .../Services/ContinuousLoop.cs | 7 +- src/Encryptamajig/AesEncryptamajig.cs | 142 ------------------ src/Encryptamajig/AesManaged.cs | 105 ------------- src/Encryptamajig/DeriveResult.cs | 14 -- src/Encryptamajig/Encryptamajig.csproj | 29 ---- src/Encryptamajig/LICENSE | 21 --- src/Encryptamajig/Properties/AssemblyInfo.cs | 36 ----- src/Encryptamajig/README.md | 54 ------- test/Devlord.Utilities.Tests/CryptKeyTests.cs | 85 ----------- .../Devlord.Utilities.Tests.csproj | 22 ++- test/Devlord.Utilities.Tests/MailTests.cs | 28 +--- .../Services/ContinuousLoopTests.cs | 2 +- test/Devlord.Utilities.Tests/TestLogger.cs | 52 ------- .../Encryptamajig.Tests.csproj | 32 ---- .../Encryptamajig.Tests/EncryptamajigTests.cs | 113 -------------- .../Properties/AssemblyInfo.cs | 36 ----- .../corefx/AesManagedTests.cs | 127 ---------------- .../Encryptamajig.Tests/corefx/CryptoUtils.cs | 55 ------- test/Encryptamajig.Tests/packages.config | 4 - 27 files changed, 33 insertions(+), 1099 deletions(-) delete mode 100644 src/Devlord.Utilities/App_Readme/Elmah.txt delete mode 100644 src/Devlord.Utilities/Cryptography/Crypt.cs delete mode 100644 src/Encryptamajig/AesEncryptamajig.cs delete mode 100644 src/Encryptamajig/AesManaged.cs delete mode 100644 src/Encryptamajig/DeriveResult.cs delete mode 100644 src/Encryptamajig/Encryptamajig.csproj delete mode 100644 src/Encryptamajig/LICENSE delete mode 100644 src/Encryptamajig/Properties/AssemblyInfo.cs delete mode 100644 src/Encryptamajig/README.md delete mode 100644 test/Devlord.Utilities.Tests/CryptKeyTests.cs delete mode 100644 test/Devlord.Utilities.Tests/TestLogger.cs delete mode 100644 test/Encryptamajig.Tests/Encryptamajig.Tests.csproj delete mode 100644 test/Encryptamajig.Tests/EncryptamajigTests.cs delete mode 100644 test/Encryptamajig.Tests/Properties/AssemblyInfo.cs delete mode 100644 test/Encryptamajig.Tests/corefx/AesManagedTests.cs delete mode 100644 test/Encryptamajig.Tests/corefx/CryptoUtils.cs delete mode 100644 test/Encryptamajig.Tests/packages.config diff --git a/Devlord.Utilities.sln b/Devlord.Utilities.sln index 553d0b6..fc7860e 100644 --- a/Devlord.Utilities.sln +++ b/Devlord.Utilities.sln @@ -18,10 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D98FBDA4-114 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F789018F-60C1-4E97-8E2F-5FFD41A008D1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Encryptamajig", "src\Encryptamajig\Encryptamajig.csproj", "{E5BACB77-AE20-4834-9AAA-DED949436118}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Encryptamajig.Tests", "test\Encryptamajig.Tests\Encryptamajig.Tests.csproj", "{239FCC70-2688-4EAF-8C19-85A348840E34}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -36,14 +32,6 @@ Global {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998}.Debug|Any CPU.Build.0 = Debug|Any CPU {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998}.Release|Any CPU.ActiveCfg = Release|Any CPU {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998}.Release|Any CPU.Build.0 = Release|Any CPU - {E5BACB77-AE20-4834-9AAA-DED949436118}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E5BACB77-AE20-4834-9AAA-DED949436118}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E5BACB77-AE20-4834-9AAA-DED949436118}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E5BACB77-AE20-4834-9AAA-DED949436118}.Release|Any CPU.Build.0 = Release|Any CPU - {239FCC70-2688-4EAF-8C19-85A348840E34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {239FCC70-2688-4EAF-8C19-85A348840E34}.Debug|Any CPU.Build.0 = Debug|Any CPU - {239FCC70-2688-4EAF-8C19-85A348840E34}.Release|Any CPU.ActiveCfg = Release|Any CPU - {239FCC70-2688-4EAF-8C19-85A348840E34}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -51,8 +39,6 @@ Global GlobalSection(NestedProjects) = preSolution {BDA4FCBB-3582-42E0-B383-1BAB2BC69547} = {D98FBDA4-114C-469D-A722-A8DB70F42BFE} {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998} = {F789018F-60C1-4E97-8E2F-5FFD41A008D1} - {E5BACB77-AE20-4834-9AAA-DED949436118} = {D98FBDA4-114C-469D-A722-A8DB70F42BFE} - {239FCC70-2688-4EAF-8C19-85A348840E34} = {F789018F-60C1-4E97-8E2F-5FFD41A008D1} EndGlobalSection GlobalSection(CodealikeProperties) = postSolution SolutionGuid = 786e0001-a81c-40a8-96b1-bd100ef383c7 diff --git a/README.md b/README.md index a9ad9ef..e2e7787 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,6 @@ Or from the command-line: * System.Threading.Timers service clocks * Email throttling to help you avoid being suspended by your ISP * Generic HTTP API wrappers -* Two-way AES encryption * "Micro-ORM" DataReader mapper for when using a full-featured ORM would be overkill More details below, but for even _more_ details, see the [project wiki](https://github.com/lorddev/utilities/wiki). @@ -89,11 +88,6 @@ A multithreaded SMTP queued mail sender, has a configurable throttle for mail fr } ``` -### Crypt - -Bidirectional encryption methods useful for storing credit cards or encrypting passwords or API keys to save in a project's -configuration files. (Not recommend for use with user's site credentials as those should use one-way encryption.) - ### DRMapper Allows mapping of an `IDataReader` to POCO classes using reflection. It's faster than you might expect. diff --git a/src/Devlord.Utilities/App_Readme/Elmah.txt b/src/Devlord.Utilities/App_Readme/Elmah.txt deleted file mode 100644 index 784b309..0000000 --- a/src/Devlord.Utilities/App_Readme/Elmah.txt +++ /dev/null @@ -1,15 +0,0 @@ -A new HTTP handler has been configured in your application for consulting the -error log and its feeds. It is reachable at elmah.axd under your application -root. If, for example, your application is deployed at http://www.example.com, -the URL for ELMAH would be http://www.example.com/elmah.axd. You can, of -course, change this path in your application's configuration file. - -ELMAH is also set up to be secure such that it can only be accessed locally. -You can enable remote access but then it is paramount that you secure access -to authorized users or/and roles only. This can be done using standard -authorization rules and configuration already built into ASP.NET. For more -information, see http://code.google.com/p/elmah/wiki/SecuringErrorLogPages on -the project site. - -Please review the commented out authorization section under - and make the appropriate changes. diff --git a/src/Devlord.Utilities/Cryptography/Crypt.cs b/src/Devlord.Utilities/Cryptography/Crypt.cs deleted file mode 100644 index a278054..0000000 --- a/src/Devlord.Utilities/Cryptography/Crypt.cs +++ /dev/null @@ -1,79 +0,0 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// © 2017 Lord Design -// -// -// You may use freely and commercially without modification; if you make changes, please share back to the -// community. -// -// Aaron Lord -// -------------------------------------------------------------------------------------------------------------------- - -using System; -using System.Security.Cryptography; -using System.Text; -using Encryptamajig; -using BC = BCrypt.Net.BCrypt; - -namespace Devlord.Utilities.Cryptography -{ - /// - /// A basic wrapper for crucial encryption algorithms. - /// - public class Crypt - { - #region Fields - - public byte[] Key { get; set; } - - public static UTF8Encoding SafeUtf8 = new UTF8Encoding(false, true); - - #endregion - - #region Public Methods and Operators - - /// - /// Run this method in a Test project to quickly get a new key of strong random bytes. Iterate through the byte - /// with a StringBuilder to construct your private field instantiator. - /// - /// - /// The . - /// - public static byte[] MakeKey() - { - var random = new byte[100]; - var rng = RandomNumberGenerator.Create(); - rng.GetBytes(random); - return random; - } - - public string HideSecretPassword(string secret) - { - return AesEncryptamajig.Encrypt(secret, Convert.ToBase64String(Key)); - } - - public string DecryptSecret(string cipher) - { - return AesEncryptamajig.Decrypt(cipher, Convert.ToBase64String(Key)); - } - - public string OneWay(string cleartext) - { - var bcrypt = BC.HashPassword(cleartext); - return bcrypt; - } - - /// - /// Todo: BCrypt expects string for cleartext, but that's not secure due to GC issues with strings in memory. - /// Need to "override" BCrypt's behavior here, or somehow access their private static method. - /// - /// - /// - /// - public bool Verify(byte[] input, string storedCipherText) - { - return BC.Verify(SafeUtf8.GetString(input), storedCipherText); - } - #endregion - } -} \ No newline at end of file diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 41776bc..be67642 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -5,7 +5,7 @@ false false false - 7.0.0 + 7.0.0 Devlords Cooperative devlord https://github.com/lorddev/utilities @@ -16,26 +16,19 @@ Git utils utilities email distance-matrix micro-orm logging encryption Utilities class library so you don't have to rewrite your utilities on every project. - ... true 22b9d517-6954-4beb-b7be-ba24eb9ac441 README.md - - - - - - - - - - - - - + + + + + + + diff --git a/src/Devlord.Utilities/Logger.Core.cs b/src/Devlord.Utilities/Logger.Core.cs index d674ca0..142d7af 100644 --- a/src/Devlord.Utilities/Logger.Core.cs +++ b/src/Devlord.Utilities/Logger.Core.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // © Lord Design // @@ -11,8 +11,6 @@ // Aaron Lord // -------------------------------------------------------------------------------------------------------------------- -using Elmah.Io; - #if !NET451 using System.Diagnostics; diff --git a/src/Devlord.Utilities/Mailbot.cs b/src/Devlord.Utilities/Mailbot.cs index 04bcd64..a4c8bec 100644 --- a/src/Devlord.Utilities/Mailbot.cs +++ b/src/Devlord.Utilities/Mailbot.cs @@ -1,4 +1,4 @@ -// -------------------------------------------------------------------------------------------------------------------- +// -------------------------------------------------------------------------------------------------------------------- // // © Lord Design. Modified GPL: You may use freely and commercially without modification; you can modify if result // is also free. @@ -11,7 +11,6 @@ // -------------------------------------------------------------------------------------------------------------------- using System.Threading.Tasks; -using Devlord.Utilities.Cryptography; using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; @@ -26,8 +25,6 @@ public class Mailbot { #region Fields - private readonly Crypt _crypt = new Crypt(); - /// /// The throttles. /// @@ -42,15 +39,6 @@ public class Mailbot /// internal Mailbot() { - _crypt.Key = new byte[] - { - 80, 20, 245, 0, 124, 61, 192, 137, 232, 79, 249, 228, 1, 246, 187, 3, 228, 215, 250, 11, - 131, 33, 180, 143, 41, 217, 4, 16, 219, 34, 50, 115, 96, 140, 146, 24, 5, 69, 58, 183, 66, 88, 58, 44, - 213, 81, 26, 187, 247, 101, 163, 248, 103, 3, 179, 60, 14, 152, 90, 230, 92, 69, 100, 246, 32, 27, 201, - 123, 99, 229, 66, 118, 185, 241, 136, 38, 174, 104, 203, 207, 4, 175, 223, 104, 140, 234, 20, 228, 209, - 175, 94, 212, 105, 165, 47, 61, 100, 219, 18, - 224 - }; } #endregion @@ -64,7 +52,7 @@ internal Mailbot() public int SmtpPort { get; internal set; } public string SmtpLogin { get; internal set; } - public string EncryptedPassword { get; internal set; } + public string SmtpPassword { get; internal set; } #endregion @@ -83,19 +71,18 @@ private async Task SendMail(Botmail botmail) Throttles.Wait(); var mm = new MimeMessage(); - mm.From.Add(new MailboxAddress(botmail.Addresser)); + mm.From.Add(MailboxAddress.Parse(botmail.Addresser)); mm.Subject = botmail.Subject; mm.Body = new TextPart(botmail.Format.ToString().ToLower()) { Text = botmail.Body }; - botmail.Addressees.ForEach(a => mm.To.Add(new MailboxAddress(a))); + botmail.Addressees.ForEach(a => mm.To.Add(MailboxAddress.Parse(a))); using (var client = new SmtpClient()) { - client.Connect(SmtpServer, SmtpPort, SecureSocketOptions.SslOnConnect); - await client.AuthenticateAsync(SmtpLogin, - _crypt.DecryptSecret(EncryptedPassword)); + await client.ConnectAsync(SmtpServer, SmtpPort, SecureSocketOptions.SslOnConnect); + await client.AuthenticateAsync(SmtpLogin, SmtpPassword); await client.SendAsync(mm); Throttles.Increment(); client.Disconnect(true); diff --git a/src/Devlord.Utilities/MailbotFactory.cs b/src/Devlord.Utilities/MailbotFactory.cs index f38a9bd..28356e1 100644 --- a/src/Devlord.Utilities/MailbotFactory.cs +++ b/src/Devlord.Utilities/MailbotFactory.cs @@ -56,7 +56,7 @@ public Mailbot GetMailbot(string name) SmtpServer = thisOptions.SmtpServer, SmtpPort = thisOptions.SmtpPort, SmtpLogin = thisOptions.SmtpLogin, - EncryptedPassword = thisOptions.SmtpPassword, + SmtpPassword = thisOptions.SmtpPassword, Throttles = new Throttles(thisOptions.MaxPerMinute, thisOptions.MaxPerHour, thisOptions.MaxPerDay) }; diff --git a/src/Devlord.Utilities/Services/ContinuousLoop.cs b/src/Devlord.Utilities/Services/ContinuousLoop.cs index 1e3f0c1..3c211be 100644 --- a/src/Devlord.Utilities/Services/ContinuousLoop.cs +++ b/src/Devlord.Utilities/Services/ContinuousLoop.cs @@ -28,16 +28,17 @@ public class ContinuousLoop : ServiceTimer /// /// Adding multiple events to the timer will allow the events to run consecutively, though in no particular order. /// - /// + /// /// - public override ServiceTimer AddEvent(ServiceTimerEventHandler @event) + + public override ServiceTimer AddEvent(ServiceTimerEventHandler elapsedHandler) { _queuedTimers++; Events += (s, e) => { try { - @event.Invoke(this, e); + elapsedHandler.Invoke(this, e); } catch (Exception error) { diff --git a/src/Encryptamajig/AesEncryptamajig.cs b/src/Encryptamajig/AesEncryptamajig.cs deleted file mode 100644 index a2d806b..0000000 --- a/src/Encryptamajig/AesEncryptamajig.cs +++ /dev/null @@ -1,142 +0,0 @@ -namespace Encryptamajig -{ - using System; - using System.IO; - using System.Linq; - using System.Security.Cryptography; - - /// - /// A simple wrapper to the AesManaged class and the AES algorithm. - /// Requires a securely stored key which should be a random string of characters that an attacker could never guess. - /// Make sure to save the Key if you want to decrypt your data later! - /// If you're using this with a Web app, put the key in the web.config and encrypt the web.config. - /// - public static class AesEncryptamajig - { - private const int SaltSize = 32; - - /// - /// Encrypts the plainText input using the given Key. - /// A 256-bit random salt will be generated and prepended to the cipherText before it is base64 encoded. - /// - /// The plain text to encrypt. - /// The plain text encryption key. - /// The salt and the cipherText, Base64 encoded for convenience. - public static string Encrypt(string plainText, string key) - { - CheckInput(plainText, "plainText"); - CheckInput(key, "key"); - - // Derive a new Salt and IV from the Key - var bytes = DeriveBytes(key); - - // Return the encrypted keys from the memory stream, in Base64 form so we can send it right to a database (if we want). - var cipherTextBytes = EncryptStream(plainText, bytes); - var buffer = bytes.Salt; - Array.Resize(ref buffer, buffer.Length + cipherTextBytes.Length); - Array.Copy(cipherTextBytes, 0, buffer, SaltSize, cipherTextBytes.Length); - - return Convert.ToBase64String(buffer); - } - - /// - /// Decrypts the cipherText using the Key. - /// - /// The cipherText to decrypt. - /// The plain text encryption key. - /// The decrypted text. - public static string Decrypt(string cipherText, string key) - { - CheckInput(cipherText, "cipherText"); - CheckInput(key, "key"); - - // Extract the salt from our cipherText - var allTheBytes = Convert.FromBase64String(cipherText); - var saltBytes = allTheBytes.Take(SaltSize).ToArray(); - var ciphertextBytes = allTheBytes.Skip(SaltSize).Take(allTheBytes.Length - SaltSize).ToArray(); - - var bytes = DeriveBytes(key, saltBytes); - return DecryptStream(ciphertextBytes, bytes); - } - - private static bool CheckInput(string field, string fieldName) - { - if (string.IsNullOrEmpty(field)) - { - throw new ArgumentNullException(fieldName); - } - - return field.Trim().Length > 0; - } - - // Supress warnings due to .NET 3.5 compatibility - // ReSharper disable SuspiciousTypeConversion.Global - #pragma warning disable S1944 // Inappropriate casts should not be made - private static DeriveResult DeriveBytes(string key) - { - var deriver = new Rfc2898DeriveBytes(key, SaltSize); - var result = new DeriveResult - { - Salt = deriver.Salt, - Key = deriver.GetBytes(32), - InitializationVector = deriver.GetBytes(16) - }; - ((IDisposable)deriver).Dispose(); - return result; - } - - private static DeriveResult DeriveBytes(string key, byte[] saltBytes) - { - var deriver = new Rfc2898DeriveBytes(key, saltBytes); - - // Derive the previous IV from the Key and Salt - var result = new DeriveResult - { - Key = deriver.GetBytes(32), - InitializationVector = deriver.GetBytes(16) - }; - - ((IDisposable)deriver).Dispose(); - return result; - } - - private static byte[] EncryptStream(string clearText, DeriveResult bytes) - { - // Create an encryptor to perform the stream transform. - // Create the streams used for encryption. - using (var aesManaged = new AesManaged()) - using (var encryptor = aesManaged.CreateEncryptor(bytes.Key, bytes.InitializationVector)) - using (var memoryStream = new MemoryStream()) - { - using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) - using (var streamWriter = new StreamWriter(cryptoStream)) - { - // Send the data through the StreamWriter, through the CryptoStream, to the underlying MemoryStream - streamWriter.Write(clearText); - - // vv Have to dispose of the SW here in order to maintain the integrity of the memoryStream. - } - - // Return the encrypted keys from the memory stream, in Base64 form so we can send it right to a database (if we want). - var cipherTextBytes = memoryStream.ToArray(); - return cipherTextBytes; - } - } - - private static string DecryptStream(byte[] cipher, DeriveResult keys) - { - // Create a decrytor to perform the stream transform. - // Create the streams used for decryption. - // The default Cipher Mode is CBC and the Padding is PKCS7 which are both good - using (var aesManaged = new AesManaged()) - using (var decryptor = aesManaged.CreateDecryptor(keys.Key, keys.InitializationVector)) - using (var memoryStream = new MemoryStream(cipher)) - using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) - using (var streamReader = new StreamReader(cryptoStream)) - { - // Return the decrypted keys from the decrypting stream. - return streamReader.ReadToEnd(); - } - } - } -} diff --git a/src/Encryptamajig/AesManaged.cs b/src/Encryptamajig/AesManaged.cs deleted file mode 100644 index 9dfc24a..0000000 --- a/src/Encryptamajig/AesManaged.cs +++ /dev/null @@ -1,105 +0,0 @@ -// Source: https://github.com/dotnet/corefx/commit/6d523750c4356af1d5c9e001c362baa833059833#diff-4d021d7c9e9a9ef5fdf2d896a928c0b6 - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.ComponentModel; -using System.Security.Cryptography; - -#if NETSTANDARD1_5 || NETSTANDARD1_3 -namespace Encryptamajig -{ - [EditorBrowsable(EditorBrowsableState.Never)] - public sealed class AesManaged : Aes - { - private readonly Aes _impl; - - public AesManaged() - { - // This class wraps Aes - _impl = Create(); - } - - public override int BlockSize - { - get => _impl.BlockSize; - set => _impl.BlockSize = value; - } - - public override byte[] IV - { - get => _impl.IV; - set => _impl.IV = value; - } - - public override byte[] Key - { - get => _impl.Key; - set => _impl.Key = value; - } - - public override int KeySize - { - get => _impl.KeySize; - set => _impl.KeySize = value; - } - - public override CipherMode Mode - { - get => _impl.Mode; - set => _impl.Mode = value; - } - - public override PaddingMode Padding - { - get => _impl.Padding; - set => _impl.Padding = value; - } - - public override KeySizes[] LegalBlockSizes => _impl.LegalBlockSizes; - public override KeySizes[] LegalKeySizes => _impl.LegalKeySizes; - - public override ICryptoTransform CreateEncryptor() - { - return _impl.CreateEncryptor(); - } - - public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV) - { - return _impl.CreateEncryptor(rgbKey, rgbIV); - } - - public override ICryptoTransform CreateDecryptor() - { - return _impl.CreateDecryptor(); - } - - public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV) - { - return _impl.CreateDecryptor(rgbKey, rgbIV); - } - - public override void GenerateIV() - { - _impl.GenerateIV(); - } - - public override void GenerateKey() - { - _impl.GenerateKey(); - } - - protected override void Dispose(bool disposing) - { - if (disposing) - { - _impl.Dispose(); - } - - base.Dispose(disposing); - } - } -} - -#endif \ No newline at end of file diff --git a/src/Encryptamajig/DeriveResult.cs b/src/Encryptamajig/DeriveResult.cs deleted file mode 100644 index 973c24f..0000000 --- a/src/Encryptamajig/DeriveResult.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Encryptamajig -{ - /// - /// Holds the result of derivation functions, including salt and key/iv pair. - /// - internal struct DeriveResult - { - public byte[] Salt { get; set; } - - public byte[] Key { get; set; } - - public byte[] InitializationVector { get; set; } - } -} diff --git a/src/Encryptamajig/Encryptamajig.csproj b/src/Encryptamajig/Encryptamajig.csproj deleted file mode 100644 index 76ecafb..0000000 --- a/src/Encryptamajig/Encryptamajig.csproj +++ /dev/null @@ -1,29 +0,0 @@ - - - - netstandard2.1;net8.0 - false - false - false - false - false - false - false - LICENSE - 2.0 - Supports .NET Core netstandard 1.3 - https://github.com/jbubriski/Encryptamajig - John Bubriski - https://github.com/jbubriski/Encryptamajig - Git - Encryption - - - - - - - - - - diff --git a/src/Encryptamajig/LICENSE b/src/Encryptamajig/LICENSE deleted file mode 100644 index ad64f7d..0000000 --- a/src/Encryptamajig/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 John Bubriski - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/src/Encryptamajig/Properties/AssemblyInfo.cs b/src/Encryptamajig/Properties/AssemblyInfo.cs deleted file mode 100644 index 64a3da8..0000000 --- a/src/Encryptamajig/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Encryptamajig")] -[assembly: AssemblyDescription("A simple wrapper to the .NET AES encryption algorithm functionality.")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("John Bubriski")] -[assembly: AssemblyProduct("Encryptamajig")] -[assembly: AssemblyCopyright("Copyright © John Bubriski 2013")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("ad445e2e-0998-4131-9941-556d7a6fcca1")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/Encryptamajig/README.md b/src/Encryptamajig/README.md deleted file mode 100644 index 42fd262..0000000 --- a/src/Encryptamajig/README.md +++ /dev/null @@ -1,54 +0,0 @@ -This software is derived from https://github.com/jbubriski/Encryptamajig. See the included LICENSE file for its own license, which is different from the license for Devlord.Utilities. - -The text below is jbubriski's. - ---------------- - -# Encryptamajig - -A simple wrapper to the .NET AES encryption algorithm functionality. - -**(Note: this is not a new encryption alogorithm, it's simply a wrapper that forces you to use AES as correctly.)** - -## But Why? - -> **"But John, there are so many encryption examples on the 'Net, why do we need another? Can't I just roll my own?"** - -When you look at encryption examples online many are verbose, misleading, outdated, or **flat out insecure**. By creating this project I hope to provide a single resource that myself and others can use to incoporate encryption into their .NET projects. - -My goal is to make sure this project uses an up-to-date encryption algorithm and forces appropriate usage of that algorithm. - -## Who Should Use This - -Anyone needing to encrypt data using a good algorithm that doesn't want to screw it up. - -## Issues We Avoid - - - Use of the ECB cipher mode. Simply put, ECB is unsecure. If you don't believe me, look at the images in this [Wikipedia article on the various cipher modes](http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation). - - Use of older or less secure algorithms. (Right now this is more of an assumption, I will try and cite specific algorithms to avoid and update this readme) - - Incorrect usage of encryption algorithms and block cipher modes. - - Guess work. Which algorithm do I use, how do I use it, what size should my key be, what size should my IV be, do I need a salt, etc. - - Use of the Rijndael algorithm. While Rijndael is a good algorithm, it's the **predecessor** to AES. So why not use AES? Read these articles if you more reasons or if you don't believe me: [The Differences Between Rijndael and AES](http://blogs.msdn.com/b/shawnfa/archive/2006/10/09/the-differences-between-rijndael-and-aes.aspx) and [the MSDN documentation for Rijndael](http://msdn.microsoft.com/en-us/library/system.security.cryptography.rijndael(v=vs.90).aspx). - - Ugly code. This code is tight. - -## Usage - -The AesEncryptamajig class provides 2 methods: 1 for encrypting and 1 for decrypting. You call both methods with your plain text key, and the data that you want to encrypt/decrypt. After encrypting data for the first time using this library, the salt will be prepended to the ciphertext. When you decrypt the data using this library, the salt is extracted, and the IV (Initialization Vector) is recreated. This way, you don't have to worry about storing the Salt/IV separately. - -Make sure you are storing your key someplace safe. If you're writing a web appication, you can store the Key in the Web.Config, **but make sure you encrypt the Web.Config**. - -## Encryption Resources - -Do you want to know more? (All links via Wikipedia) - -- [Encryption](http://en.wikipedia.org/wiki/Encryption) -- [Keys](http://en.wikipedia.org/wiki/Key_\(cryptography\)) -- [Initialization Vectors](http://en.wikipedia.org/wiki/Initialization_vector) -- [Block Cipher Modes](http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation) -- [AES](http://en.wikipedia.org/wiki/Advanced_Encryption_Standard) - -## Disclaimer - -I am not a security expert but I think I got the big things right. **If you are an expert** and you see that I'm doing something wrong, [please tell me](https://github.com/jbubriski)! I will take the time to look at your pull requests if you send one! - -"You don't know what you don't know", or more like "I don't know what I don't know". diff --git a/test/Devlord.Utilities.Tests/CryptKeyTests.cs b/test/Devlord.Utilities.Tests/CryptKeyTests.cs deleted file mode 100644 index 705628b..0000000 --- a/test/Devlord.Utilities.Tests/CryptKeyTests.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Text; -using Devlord.Utilities.Cryptography; -using Xunit; -using Xunit.Abstractions; - -namespace Devlord.Utilities.Tests -{ - public class CryptKeyTests - { - public CryptKeyTests(ITestOutputHelper output) - { - _output = output; - } - - private readonly ITestOutputHelper _output; - - [Fact(Skip = "This is meant for outputting arrays that we can copy to code. Run it manually.")] - public void MakeNewKeyAsString() - { - var key = Crypt.MakeKey(); - var builder = new StringBuilder("var newKey = new byte[]"); - builder.AppendLine("{"); - - var lastIndex = key.Length - 1; - - for (var i = 0; i < key.Length; i++) - { - builder.Append(" " + key[i]); - if (i != lastIndex) - { - builder.Append(','); - } - - builder.AppendLine(); - } - - builder.AppendLine("};"); - - _output.WriteLine(builder.ToString()); - } - - [Fact] - public void VerifyBCryptSimple() - { - // Arrange - const string clearText = "P@s5W1rdBruh"; - var encryptor = new Crypt(); - var ciphered = encryptor.OneWay(clearText); - - // first: "$2a$10$3btSI0hlWbdg5.xdb/x0suZGjxwiFsw7omOFvlLnoduPH3BB5Af6W" - - // Act - var result = encryptor.Verify(Crypt.SafeUtf8.GetBytes(clearText), - "$2a$10$3btSI0hlWbdg5.xdb/x0suZGjxwiFsw7omOFvlLnoduPH3BB5Af6W"); - - // Assert - Assert.True(result); - - result = encryptor.Verify(new byte[] - { - 80, - 64, - 115, - 53, - 87, - 49, - 114, - 100, - 66, - 114, - 117, - 104 - }, "$2a$10$L048plNTmEuy4znjJe5K8uS0y9EPWp0vNvicaLYcqlmaT/bJawGJy" - - ); - - result.ShouldBeTrue(); - - result = encryptor.Verify(Crypt.SafeUtf8.GetBytes("fakePass"), - "$2a$10$/.Ca2J2etjIfXPUCWAKB5.ldzqDw00A7MYuggwFCwzkX3GPZ5Ptfu"); - - Assert.False(result); - } - } -} \ No newline at end of file diff --git a/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj b/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj index 84b371b..2e715c7 100644 --- a/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj +++ b/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj @@ -1,6 +1,6 @@ - + - netstandard2.1;net6.0 + net8.0;net10.0 10 false false @@ -16,25 +16,23 @@ 22b9d517-6954-4beb-b7be-ba24eb9ac441 - - - - - + + + + + - - + + - - + all runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/test/Devlord.Utilities.Tests/MailTests.cs b/test/Devlord.Utilities.Tests/MailTests.cs index db9bb88..ff63bc2 100644 --- a/test/Devlord.Utilities.Tests/MailTests.cs +++ b/test/Devlord.Utilities.Tests/MailTests.cs @@ -1,10 +1,7 @@ using System; -using System.Diagnostics; using System.Linq; using System.Threading.Tasks; -using Devlord.Utilities.Cryptography; using Devlord.Utilities.Exceptions; -using Microsoft.Extensions.Options; using Xunit; namespace Devlord.Utilities.Tests @@ -17,28 +14,7 @@ public MailTests(DevlordTestConfiguration fixture) { _fixture = fixture; } - - [Fact] - public void EncryptPassword() - { - Debug.WriteLine("asdf"); - - var crypt = new Crypt - { - Key = - new byte[] - { - 80, 20, 245, 0, 124, 61, 192, 137, 232, 79, 249, 228, 1, 246, 187, 3, 228, - 215, 250, 11, 131, 33, 180, 143, 41, 217, 4, 16, 219, 34, 50, 115, 96, 140, - 146, 24, 5, 69, 58, 183, 66, 88, 58, 44, 213, 81, 26, 187, 247, 101, 163, - 248, 103, 3, 179, 60, 14, 152, 90, 230, 92, 69, 100, 246, 32, 27, 201, 123, - 99, 229, 66, 118, 185, 241, 136, 38, 174, 104, 203, 207, 4, 175, 223, 104, - 140, 234, 20, 228, 209, 175, 94, 212, 105, 165, 47, 61, 100, 219, 18, 224 - } - }; - Debug.WriteLine(crypt.HideSecretPassword("AuOsVkTXzzrcq58RZ+AsOBzL5KwkztAyXB5ZQOIfOY7E")); - } - + [Fact(Skip = "Dude, don't be sending emails from unit tests!")] public async Task TestMailbot() { @@ -68,7 +44,7 @@ public async Task TestMailbot() SmtpPort = thisOptions.SmtpPort, SmtpLogin = thisOptions.SmtpLogin, SmtpServer = thisOptions.SmtpServer, - EncryptedPassword = thisOptions.SmtpPassword + SmtpPassword = thisOptions.SmtpPassword }.QueueMail(botMail); } catch (Exception e) diff --git a/test/Devlord.Utilities.Tests/Services/ContinuousLoopTests.cs b/test/Devlord.Utilities.Tests/Services/ContinuousLoopTests.cs index 873c7ad..42c7c2c 100644 --- a/test/Devlord.Utilities.Tests/Services/ContinuousLoopTests.cs +++ b/test/Devlord.Utilities.Tests/Services/ContinuousLoopTests.cs @@ -32,7 +32,7 @@ public ContinuousLoopTests(ITestOutputHelper output) [Fact] public void TestContinuousLoop() { - Console.WriteLine(@"Test app start logging."); + _output.WriteLine("Test app start logging."); var success = false; ServiceTimer timedMultiple = new ContinuousLoop(); timedMultiple.AddEvent(LoopedElapsed) diff --git a/test/Devlord.Utilities.Tests/TestLogger.cs b/test/Devlord.Utilities.Tests/TestLogger.cs deleted file mode 100644 index 5200000..0000000 --- a/test/Devlord.Utilities.Tests/TestLogger.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.Logging; -using Xunit; -#if NETCOREAPP1_1 -using LogType = Microsoft.Extensions.Logging.LogLevel; - -#elif NET462 -using LogType = System.Diagnostics.EventLogEntryType; -#endif - -namespace Devlord.Utilities.Tests -{ - public class TestLogger : IDevLogger - { - public void Log(Exception exception) - { - Console.WriteLine(exception); - Errors.Add(exception); - throw new Exception("Logged exception found in tested code. Rethrowing...", exception); - } - - public void WriteEntry(string message, LogLevel error, LogCode errorCode = LogCode.None) - { - throw new NotImplementedException(); - } - - private static readonly List Errors = new List(); - - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, - Func formatter) - { - throw new NotImplementedException(); - } - - public bool IsEnabled(LogLevel logLevel) - { - throw new NotImplementedException(); - } - - public IDisposable BeginScope(TState state) - { - throw new NotImplementedException(); - } - - [Fact] - public void VerifyNoErrors() - { - Assert.Empty(Errors); - } - } -} \ No newline at end of file diff --git a/test/Encryptamajig.Tests/Encryptamajig.Tests.csproj b/test/Encryptamajig.Tests/Encryptamajig.Tests.csproj deleted file mode 100644 index 7fe74b8..0000000 --- a/test/Encryptamajig.Tests/Encryptamajig.Tests.csproj +++ /dev/null @@ -1,32 +0,0 @@ - - - - netstandard2.1;net6.0 - false - false - false - false - false - false - false - - - - - - - - - - - - - - - - - - - - - diff --git a/test/Encryptamajig.Tests/EncryptamajigTests.cs b/test/Encryptamajig.Tests/EncryptamajigTests.cs deleted file mode 100644 index 2d4b490..0000000 --- a/test/Encryptamajig.Tests/EncryptamajigTests.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System; -using System.Diagnostics; -using System.Security.Cryptography; -using Xunit; - -namespace Encryptamajig.Tests -{ - public class EncryptamajigTests - { - // A test credit card number - private static readonly string _plainText = "4111111111111111"; - - // The key should be a random string of characters that an attacker could never guess - private static readonly string _key = "Something you can't guess"; - - [Fact] - public void AesManaged_EncryptionRoundtripWithCustomInputs_ReturnsOriginalText() - { - // Arrange - // Act - var encrypted = AesEncryptamajig.Encrypt(_plainText, _key); - var roundtrip = AesEncryptamajig.Decrypt(encrypted, _key); - - Debug.WriteLine(_plainText); - Debug.WriteLine(encrypted); - Debug.WriteLine(roundtrip); - - // Assert - Assert.NotEqual(_plainText, encrypted); - Assert.Equal(_plainText, roundtrip); - } - - [Fact] - public void AesManaged_EncryptionRoundtripWithRandomKey_ReturnsOriginalText() - { - // Arrange - var aesManaged = new AesManaged(); - - var key = Convert.ToBase64String(aesManaged.Key); - - // Act - var encrypted = AesEncryptamajig.Encrypt(_plainText, key); - var roundtrip = AesEncryptamajig.Decrypt(encrypted, key); - - Debug.WriteLine(_plainText); - Debug.WriteLine(encrypted); - Debug.WriteLine(roundtrip); - - // Assert - Assert.NotEqual(_plainText, encrypted); - Assert.Equal(_plainText, roundtrip); - } - - [Fact] - public void AesManaged_ReencryptionWithSameKey_ReturnsSameText() - { - // Arrange - var aesManaged = new AesManaged(); - - var key = Convert.ToBase64String(aesManaged.Key); - - // Act - var encrypted1 = AesEncryptamajig.Encrypt(_plainText, key); - var roundtrip1 = AesEncryptamajig.Decrypt(encrypted1, key); - - Debug.WriteLine("Plain Text: " + _plainText); - Debug.WriteLine("Encrypted: " + encrypted1); - Debug.WriteLine("Roundtrip: " + roundtrip1); - - // Act 2 (encrypt the same data again) - var encrypted2 = AesEncryptamajig.Encrypt(_plainText, key); - var roundtrip2 = AesEncryptamajig.Decrypt(encrypted2, key); - - - Debug.WriteLine("Encrypted again: " + encrypted2); - Debug.WriteLine("Roundtrip again: " + roundtrip2); - - // Assert - Assert.NotEqual(_plainText, encrypted1); - Assert.NotEqual(_plainText, encrypted2); - - Assert.Equal(_plainText, roundtrip1); - Assert.Equal(_plainText, roundtrip2); - - Assert.NotEqual(encrypted1, encrypted2); - } - - [Fact] - public void Decrypt_WithDifferentKey_ThrowsException() - { - // Arrange - var aesManaged = new AesManaged(); - - var originalKey = Convert.ToBase64String(aesManaged.Key); - - // This should generate a new key - aesManaged = new AesManaged(); - var newKey = Convert.ToBase64String(aesManaged.Key); - - // Act - var encrypted = AesEncryptamajig.Encrypt(_plainText, originalKey); - - Debug.WriteLine("Org Key = " + originalKey); - Debug.WriteLine("New Key = " + newKey); - - // Assert - Assert.Throws(() => - { - var roundtrip = AesEncryptamajig.Decrypt(encrypted, newKey); - }); - } - } -} \ No newline at end of file diff --git a/test/Encryptamajig.Tests/Properties/AssemblyInfo.cs b/test/Encryptamajig.Tests/Properties/AssemblyInfo.cs deleted file mode 100644 index 10c87c5..0000000 --- a/test/Encryptamajig.Tests/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Encryptamajig.Tests")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("Encryptamajig.Tests")] -[assembly: AssemblyCopyright("Copyright © 2012")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("186270a9-32ff-412b-b654-a9a599d81620")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/test/Encryptamajig.Tests/corefx/AesManagedTests.cs b/test/Encryptamajig.Tests/corefx/AesManagedTests.cs deleted file mode 100644 index ccd0cc3..0000000 --- a/test/Encryptamajig.Tests/corefx/AesManagedTests.cs +++ /dev/null @@ -1,127 +0,0 @@ -// Source: https://github.com/dotnet/corefx/commit/6d523750c4356af1d5c9e001c362baa833059833#diff-4d021d7c9e9a9ef5fdf2d896a928c0b6 - -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Diagnostics; -using System.Text; -using Test.Cryptography; -using Xunit; -using System.Security.Cryptography; - -namespace Encryptamajig.Tests -{ - /// - /// Since AesManaged wraps Aes, we only test minimally here. - /// - public class AesManagedTests - { - [Fact] - public static void VerifyDefaults() - { - using (var alg = new AesManaged()) - { - Assert.Equal(128, alg.BlockSize); - Assert.Equal(256, alg.KeySize); - Assert.Equal(CipherMode.CBC, alg.Mode); - Assert.Equal(PaddingMode.PKCS7, alg.Padding); - } - } - - [Fact] - public static void EncryptDecryptKnownECB192() - { - byte[] plainTextBytes = - new ASCIIEncoding().GetBytes("This is a sentence that is longer than a block, it ensures that multi-block functions work."); - - byte[] encryptedBytesExpected = new byte[] - { - 0xC9, 0x7F, 0xA5, 0x5B, 0xC3, 0x92, 0xDC, 0xA6, - 0xE4, 0x9F, 0x2D, 0x1A, 0xEF, 0x7A, 0x27, 0x03, - 0x04, 0x9C, 0xFB, 0x56, 0x63, 0x38, 0xAE, 0x4F, - 0xDC, 0xF6, 0x36, 0x98, 0x28, 0x05, 0x32, 0xE9, - 0xF2, 0x6E, 0xEC, 0x0C, 0x04, 0x9D, 0x12, 0x17, - 0x18, 0x35, 0xD4, 0x29, 0xFC, 0x01, 0xB1, 0x20, - 0xFA, 0x30, 0xAE, 0x00, 0x53, 0xD4, 0x26, 0x25, - 0xA4, 0xFD, 0xD5, 0xE6, 0xED, 0x79, 0x35, 0x2A, - 0xE2, 0xBB, 0x95, 0x0D, 0xEF, 0x09, 0xBB, 0x6D, - 0xC5, 0xC4, 0xDB, 0x28, 0xC6, 0xF4, 0x31, 0x33, - 0x9A, 0x90, 0x12, 0x36, 0x50, 0xA0, 0xB7, 0xD1, - 0x35, 0xC4, 0xCE, 0x81, 0xE5, 0x2B, 0x85, 0x6B, - }; - - byte[] aes192Key = new byte[] - { - 0xA6, 0x1E, 0xC7, 0x54, 0x37, 0x4D, 0x8C, 0xA5, - 0xA4, 0xBB, 0x99, 0x50, 0x35, 0x4B, 0x30, 0x4D, - 0x6C, 0xFE, 0x3B, 0x59, 0x65, 0xCB, 0x93, 0xE3, - }; - - using (var alg = new AesManaged()) - { - // The CipherMode and KeySize are different than the default values; this ensures the type - // forwards the state properly to Aes. - alg.Mode = CipherMode.ECB; - alg.Key = aes192Key; - - byte[] encryptedBytes = alg.Encrypt(plainTextBytes); - Assert.Equal(encryptedBytesExpected, encryptedBytes); - - byte[] decryptedBytes = alg.Decrypt(encryptedBytes); - Assert.Equal(plainTextBytes, decryptedBytes); - } - } - - [Fact] - public static void TestShims() - { - using (var alg = new AesManaged()) - { - alg.BlockSize = 128; - Assert.Equal(128, alg.BlockSize); - - var emptyIV = new byte[alg.BlockSize / 8]; - alg.IV = emptyIV; - Assert.Equal(emptyIV, alg.IV); - alg.GenerateIV(); - Assert.NotEqual(emptyIV, alg.IV); - - var emptyKey = new byte[alg.KeySize / 8]; - alg.Key = emptyKey; - Assert.Equal(emptyKey, alg.Key); - alg.GenerateKey(); - Assert.NotEqual(emptyKey, alg.Key); - - alg.KeySize = 128; - Assert.Equal(128, alg.KeySize); - - alg.Mode = CipherMode.ECB; - Assert.Equal(CipherMode.ECB, alg.Mode); - - alg.Padding = PaddingMode.PKCS7; - Assert.Equal(PaddingMode.PKCS7, alg.Padding); - } - } - - [Fact] - public void AesManaged_NewInstances_ReturnsNewKeyAndIv() - { - // Arrange - // Act - var aesManaged = new AesManaged(); - var aesManaged2 = new AesManaged(); - - Debug.WriteLine(Convert.ToBase64String(aesManaged.Key)); - Debug.WriteLine(Convert.ToBase64String(aesManaged2.Key)); - - Debug.WriteLine(Convert.ToBase64String(aesManaged.IV)); - Debug.WriteLine(Convert.ToBase64String(aesManaged2.IV)); - - // Assert - Assert.NotEqual(aesManaged.Key, aesManaged2.Key); - Assert.NotEqual(aesManaged.IV, aesManaged2.IV); - } - } -} diff --git a/test/Encryptamajig.Tests/corefx/CryptoUtils.cs b/test/Encryptamajig.Tests/corefx/CryptoUtils.cs deleted file mode 100644 index 8cb7e38..0000000 --- a/test/Encryptamajig.Tests/corefx/CryptoUtils.cs +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Security.Cryptography; -// ReSharper disable CheckNamespace - -namespace Test.Cryptography -{ - internal static class CryptoUtils - { - internal static byte[] Encrypt(this SymmetricAlgorithm alg, byte[] plainText, int blockSizeMultipler = 1) - { - using (ICryptoTransform encryptor = alg.CreateEncryptor()) - { - return encryptor.Transform(plainText, blockSizeMultipler); - } - } - - internal static byte[] Decrypt(this SymmetricAlgorithm alg, byte[] cipher, int blockSizeMultipler = 1) - { - using (ICryptoTransform decryptor = alg.CreateDecryptor()) - { - return decryptor.Transform(cipher, blockSizeMultipler); - } - } - - internal static byte[] Transform(this ICryptoTransform transform, byte[] input, int blockSizeMultipler = 1) - { - List output = new List(input.Length); - int blockSize = transform.InputBlockSize * blockSizeMultipler; - for (int i = 0; i <= input.Length; i += blockSize) - { - int count = Math.Min(blockSize, input.Length - i); - if (count >= blockSize) - { - byte[] buffer = new byte[blockSize]; - int numBytesWritten = transform.TransformBlock(input, i, count, buffer, 0); - Array.Resize(ref buffer, numBytesWritten); - output.AddRange(buffer); - } - else - { - byte[] finalBlock = transform.TransformFinalBlock(input, i, count); - output.AddRange(finalBlock); - break; - } - } - - return output.ToArray(); - } - } -} \ No newline at end of file diff --git a/test/Encryptamajig.Tests/packages.config b/test/Encryptamajig.Tests/packages.config deleted file mode 100644 index 0c82178..0000000 --- a/test/Encryptamajig.Tests/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file From 9a2969b77553152ca4e22be58dc4b6a700b31fe9 Mon Sep 17 00:00:00 2001 From: Aaron Date: Mon, 23 Feb 2026 13:15:15 -0800 Subject: [PATCH 09/26] Remove encryption tags from NuGet --- README.md | 2 +- src/Devlord.Utilities/Devlord.Utilities.csproj | 2 +- src/Devlord.Utilities/Properties/AssemblyInfo.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e2e7787..f1b856e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ devlord utilities ==================== -A useful class library for universal utilities like encryption, sending emails, and consuming RESTful APIs. +A useful class library for universal utilities like sending emails and consuming RESTful APIs. | Master | Develop | NuGet | | ----- | ----- | ----- | diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index be67642..02ebfa8 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -14,7 +14,7 @@ https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png https://github.com/lorddev/utilities Git - utils utilities email distance-matrix micro-orm logging encryption + utils utilities email distance-matrix micro-orm Utilities class library so you don't have to rewrite your utilities on every project. true diff --git a/src/Devlord.Utilities/Properties/AssemblyInfo.cs b/src/Devlord.Utilities/Properties/AssemblyInfo.cs index 2dd4ef1..190a5c9 100644 --- a/src/Devlord.Utilities/Properties/AssemblyInfo.cs +++ b/src/Devlord.Utilities/Properties/AssemblyInfo.cs @@ -8,7 +8,7 @@ [assembly: AssemblyTitle("Devlord.Utilities")] [assembly: AssemblyDescription( - "Multipurpose universal utilities library so you don't have to write your own utils for every project. Includes extensions, encapsulation of logging and encryption, DataReader-to-POCO mapping, a mailer throttle, and strongly-typed API callers. Also includes a .NET Core-compatible build of Encryptamajig.")] + "Multipurpose universal utilities library so you don't have to write your own utils for every project. Includes extensions, DataReader-to-POCO mapping, a mailer throttle, and strongly-typed API callers.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] From 7b369b2ba6a07778d3f9c591cb544b3d85786aea Mon Sep 17 00:00:00 2001 From: Aaron Lord Date: Sat, 28 Feb 2026 12:16:20 -0800 Subject: [PATCH 10/26] New PackageIcon --- Devlord.Utilities.sln | 1 + images/devlord-105.png | Bin 0 -> 12613 bytes src/Devlord.Utilities/Devlord.Utilities.csproj | 5 +++-- 3 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 images/devlord-105.png diff --git a/Devlord.Utilities.sln b/Devlord.Utilities.sln index fc7860e..5b50a4f 100644 --- a/Devlord.Utilities.sln +++ b/Devlord.Utilities.sln @@ -12,6 +12,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution appveyor.yml = appveyor.yml LICENSE = LICENSE README.md = README.md + images\devlord-105.png = images\devlord-105.png EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D98FBDA4-114C-469D-A722-A8DB70F42BFE}" diff --git a/images/devlord-105.png b/images/devlord-105.png new file mode 100644 index 0000000000000000000000000000000000000000..946133bb46689d26ca3fe155d70f45390b2156aa GIT binary patch literal 12613 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 literal 0 HcmV?d00001 diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 02ebfa8..1584f2c 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -11,7 +11,7 @@ https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE - https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png + devlord-105.png https://github.com/lorddev/utilities Git utils utilities email distance-matrix micro-orm @@ -38,7 +38,8 @@ - + + From 5ff0ce898fc79a38695f05c8d014b4d379928bb9 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 12:53:21 -0800 Subject: [PATCH 11/26] Separate Mail and MapsApi packages. Also removed Newtonsoft.Json --- Devlord.Utilities.sln | 14 +++++ README.md | 8 +++ .../Botmail.cs | 0 .../Devlord.Utilities.Mail.csproj | 27 ++++++++++ .../DevlordSettingsExtension.cs | 2 +- .../GmailThrottles.cs | 0 .../IMailbotFactory.cs | 0 .../MailFormat.cs | 0 .../MailThrottle.cs | 0 .../Mailbot.cs | 0 .../MailbotFactory.cs | 0 .../ThrottleInterval.cs | 0 .../Throttles.cs | 0 .../Devlord.Utilities.MapsApi.csproj | 26 +++++++++ .../DevlordSettingsExtension.cs | 27 ++++++++++ .../DistanceElement.cs | 0 .../DistanceResults.cs | 20 +++---- .../DistanceService.cs | 0 .../ElementRow.cs | 0 .../ValueText.cs | 2 +- src/Devlord.Utilities/ApiCall.cs | 17 +++--- .../Devlord.Utilities.csproj | 4 +- src/Devlord.Utilities/DevlordOptions.cs | 5 -- .../UnderscoreContractResolver.cs | 17 ------ src/Devlord.Utilities/packages.config | 3 +- .../Devlord.Utilities.Tests.csproj | 5 +- .../DevlordTestConfiguration.cs | 3 +- .../DistanceApiTests.cs | 18 +++++-- .../JsonDeserializerTests.cs | 54 +++++-------------- test/Devlord.Utilities.Tests/packages.config | 1 - 30 files changed, 154 insertions(+), 99 deletions(-) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/Botmail.cs (100%) create mode 100644 src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/DevlordSettingsExtension.cs (91%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/GmailThrottles.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/IMailbotFactory.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/MailFormat.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/MailThrottle.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/Mailbot.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/MailbotFactory.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/ThrottleInterval.cs (100%) rename src/{Devlord.Utilities => Devlord.Utilities.Mail}/Throttles.cs (100%) create mode 100644 src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj create mode 100644 src/Devlord.Utilities.MapsApi/DevlordSettingsExtension.cs rename src/{Devlord.Utilities/MapsApi => Devlord.Utilities.MapsApi}/DistanceElement.cs (100%) rename src/{Devlord.Utilities/MapsApi => Devlord.Utilities.MapsApi}/DistanceResults.cs (60%) rename src/{Devlord.Utilities/MapsApi => Devlord.Utilities.MapsApi}/DistanceService.cs (100%) rename src/{Devlord.Utilities/MapsApi => Devlord.Utilities.MapsApi}/ElementRow.cs (100%) rename src/{Devlord.Utilities/MapsApi => Devlord.Utilities.MapsApi}/ValueText.cs (74%) delete mode 100644 src/Devlord.Utilities/UnderscoreContractResolver.cs diff --git a/Devlord.Utilities.sln b/Devlord.Utilities.sln index fc7860e..a7324d0 100644 --- a/Devlord.Utilities.sln +++ b/Devlord.Utilities.sln @@ -18,6 +18,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D98FBDA4-114 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{F789018F-60C1-4E97-8E2F-5FFD41A008D1}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Devlord.Utilities.Mail", "src\Devlord.Utilities.Mail\Devlord.Utilities.Mail.csproj", "{5336A7B7-3BA1-4025-B39D-B831DEA65668}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Devlord.Utilities.MapsApi", "src\Devlord.Utilities.MapsApi\Devlord.Utilities.MapsApi.csproj", "{C6AEABA2-94DD-4642-8DD8-8795DAAE797C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -32,6 +36,14 @@ Global {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998}.Debug|Any CPU.Build.0 = Debug|Any CPU {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998}.Release|Any CPU.ActiveCfg = Release|Any CPU {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998}.Release|Any CPU.Build.0 = Release|Any CPU + {5336A7B7-3BA1-4025-B39D-B831DEA65668}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5336A7B7-3BA1-4025-B39D-B831DEA65668}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5336A7B7-3BA1-4025-B39D-B831DEA65668}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5336A7B7-3BA1-4025-B39D-B831DEA65668}.Release|Any CPU.Build.0 = Release|Any CPU + {C6AEABA2-94DD-4642-8DD8-8795DAAE797C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C6AEABA2-94DD-4642-8DD8-8795DAAE797C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C6AEABA2-94DD-4642-8DD8-8795DAAE797C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C6AEABA2-94DD-4642-8DD8-8795DAAE797C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -39,6 +51,8 @@ Global GlobalSection(NestedProjects) = preSolution {BDA4FCBB-3582-42E0-B383-1BAB2BC69547} = {D98FBDA4-114C-469D-A722-A8DB70F42BFE} {F41E3A90-DCB2-4E86-B9A1-DC45B0DFB998} = {F789018F-60C1-4E97-8E2F-5FFD41A008D1} + {5336A7B7-3BA1-4025-B39D-B831DEA65668} = {D98FBDA4-114C-469D-A722-A8DB70F42BFE} + {C6AEABA2-94DD-4642-8DD8-8795DAAE797C} = {D98FBDA4-114C-469D-A722-A8DB70F42BFE} EndGlobalSection GlobalSection(CodealikeProperties) = postSolution SolutionGuid = 786e0001-a81c-40a8-96b1-bd100ef383c7 diff --git a/README.md b/README.md index f1b856e..50bd10c 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,14 @@ Or from the command-line: dotnet add package Devlord.Utilities +### Breaking Changes + +* Mail utilities have been moved to the Devlord.Utilities.Mail package. +* Maps API utilities have been moved to the Devlord.Utilities.MapsApi package. +* Encryption has been deprecated because the protocols are no longer recommended. +* UnderscoreContractResolver has been removed in favor of System.Text.Json snake case handling. +* ValueText.Value has been changed from string to decimal. + ### Feature Summary * .NET Core compatibility diff --git a/src/Devlord.Utilities/Botmail.cs b/src/Devlord.Utilities.Mail/Botmail.cs similarity index 100% rename from src/Devlord.Utilities/Botmail.cs rename to src/Devlord.Utilities.Mail/Botmail.cs diff --git a/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj b/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj new file mode 100644 index 0000000..d1cbc21 --- /dev/null +++ b/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj @@ -0,0 +1,27 @@ + + + + net10.0 + enable + enable + 7.0.1 + Devlords Cooperative + devlord + https://github.com/lorddev/utilities + Copyright © 2026 Aaron Lord + https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE + https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png + https://github.com/lorddev/utilities + Git + utils utilities email gmail mailbot + Utilities class library so you don't have to rewrite your utilities on every project. + README.md + + + + + + + + + diff --git a/src/Devlord.Utilities/DevlordSettingsExtension.cs b/src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs similarity index 91% rename from src/Devlord.Utilities/DevlordSettingsExtension.cs rename to src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs index 6e11bfb..bb6f911 100644 --- a/src/Devlord.Utilities/DevlordSettingsExtension.cs +++ b/src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs @@ -16,7 +16,7 @@ namespace Devlord.Utilities { public static class DevlordSettingsExtension { - public static IServiceCollection AddDevlordUtilities(this IServiceCollection services, + public static IServiceCollection AddDevlordMail(this IServiceCollection services, IConfiguration namedConfigurationSection) { services.Configure(namedConfigurationSection); diff --git a/src/Devlord.Utilities/GmailThrottles.cs b/src/Devlord.Utilities.Mail/GmailThrottles.cs similarity index 100% rename from src/Devlord.Utilities/GmailThrottles.cs rename to src/Devlord.Utilities.Mail/GmailThrottles.cs diff --git a/src/Devlord.Utilities/IMailbotFactory.cs b/src/Devlord.Utilities.Mail/IMailbotFactory.cs similarity index 100% rename from src/Devlord.Utilities/IMailbotFactory.cs rename to src/Devlord.Utilities.Mail/IMailbotFactory.cs diff --git a/src/Devlord.Utilities/MailFormat.cs b/src/Devlord.Utilities.Mail/MailFormat.cs similarity index 100% rename from src/Devlord.Utilities/MailFormat.cs rename to src/Devlord.Utilities.Mail/MailFormat.cs diff --git a/src/Devlord.Utilities/MailThrottle.cs b/src/Devlord.Utilities.Mail/MailThrottle.cs similarity index 100% rename from src/Devlord.Utilities/MailThrottle.cs rename to src/Devlord.Utilities.Mail/MailThrottle.cs diff --git a/src/Devlord.Utilities/Mailbot.cs b/src/Devlord.Utilities.Mail/Mailbot.cs similarity index 100% rename from src/Devlord.Utilities/Mailbot.cs rename to src/Devlord.Utilities.Mail/Mailbot.cs diff --git a/src/Devlord.Utilities/MailbotFactory.cs b/src/Devlord.Utilities.Mail/MailbotFactory.cs similarity index 100% rename from src/Devlord.Utilities/MailbotFactory.cs rename to src/Devlord.Utilities.Mail/MailbotFactory.cs diff --git a/src/Devlord.Utilities/ThrottleInterval.cs b/src/Devlord.Utilities.Mail/ThrottleInterval.cs similarity index 100% rename from src/Devlord.Utilities/ThrottleInterval.cs rename to src/Devlord.Utilities.Mail/ThrottleInterval.cs diff --git a/src/Devlord.Utilities/Throttles.cs b/src/Devlord.Utilities.Mail/Throttles.cs similarity index 100% rename from src/Devlord.Utilities/Throttles.cs rename to src/Devlord.Utilities.Mail/Throttles.cs diff --git a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj new file mode 100644 index 0000000..c9cca44 --- /dev/null +++ b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj @@ -0,0 +1,26 @@ + + + + net10.0 + enable + enable + 7.0.1 + Devlords Cooperative + devlord + https://github.com/lorddev/utilities + Copyright © 2026 Aaron Lord + https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE + https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png + https://github.com/lorddev/utilities + Git + utils utilities distance-matrix + Utilities class library so you don't have to rewrite your utilities on every project. + README.md + + + + + + + + diff --git a/src/Devlord.Utilities.MapsApi/DevlordSettingsExtension.cs b/src/Devlord.Utilities.MapsApi/DevlordSettingsExtension.cs new file mode 100644 index 0000000..21225ca --- /dev/null +++ b/src/Devlord.Utilities.MapsApi/DevlordSettingsExtension.cs @@ -0,0 +1,27 @@ +// -------------------------------------------------------------------------------------------------------------------- +// +// © 2022 Lord Design +// +// +// You may use freely and commercially without modification; if you make changes, please share back to the +// community. +// +// Aaron Lord +// -------------------------------------------------------------------------------------------------------------------- + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Devlord.Utilities +{ + public static class DevlordSettingsExtension + { + public static IServiceCollection AddDevlordMaps(this IServiceCollection services, + IConfiguration namedConfigurationSection) + { + services.Configure(namedConfigurationSection); + + return services; + } + } +} \ No newline at end of file diff --git a/src/Devlord.Utilities/MapsApi/DistanceElement.cs b/src/Devlord.Utilities.MapsApi/DistanceElement.cs similarity index 100% rename from src/Devlord.Utilities/MapsApi/DistanceElement.cs rename to src/Devlord.Utilities.MapsApi/DistanceElement.cs diff --git a/src/Devlord.Utilities/MapsApi/DistanceResults.cs b/src/Devlord.Utilities.MapsApi/DistanceResults.cs similarity index 60% rename from src/Devlord.Utilities/MapsApi/DistanceResults.cs rename to src/Devlord.Utilities.MapsApi/DistanceResults.cs index b8a277b..487f3c4 100644 --- a/src/Devlord.Utilities/MapsApi/DistanceResults.cs +++ b/src/Devlord.Utilities.MapsApi/DistanceResults.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; +using System.Text.Json; namespace Devlord.Utilities.MapsApi { @@ -28,22 +25,21 @@ public DistanceElement GetResult(int index) public string ToJson() { - string json = JsonConvert.SerializeObject( + string json = JsonSerializer.Serialize( this, - Formatting.Indented, Settings); return json; } - private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings - { - ContractResolver = - new UnderscoreContractResolver() + private static readonly JsonSerializerOptions Settings = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + WriteIndented = true, }; - public static DistanceResults FromJson(string json) + public static DistanceResults? FromJson(string json) { - return JsonConvert.DeserializeObject(json, Settings); + return JsonSerializer.Deserialize(json, Settings); } } } \ No newline at end of file diff --git a/src/Devlord.Utilities/MapsApi/DistanceService.cs b/src/Devlord.Utilities.MapsApi/DistanceService.cs similarity index 100% rename from src/Devlord.Utilities/MapsApi/DistanceService.cs rename to src/Devlord.Utilities.MapsApi/DistanceService.cs diff --git a/src/Devlord.Utilities/MapsApi/ElementRow.cs b/src/Devlord.Utilities.MapsApi/ElementRow.cs similarity index 100% rename from src/Devlord.Utilities/MapsApi/ElementRow.cs rename to src/Devlord.Utilities.MapsApi/ElementRow.cs diff --git a/src/Devlord.Utilities/MapsApi/ValueText.cs b/src/Devlord.Utilities.MapsApi/ValueText.cs similarity index 74% rename from src/Devlord.Utilities/MapsApi/ValueText.cs rename to src/Devlord.Utilities.MapsApi/ValueText.cs index 0fea529..f71bd5a 100644 --- a/src/Devlord.Utilities/MapsApi/ValueText.cs +++ b/src/Devlord.Utilities.MapsApi/ValueText.cs @@ -4,6 +4,6 @@ public struct ValueText { public string Text { get; set; } - public string Value { get; set; } + public decimal Value { get; set; } } } \ No newline at end of file diff --git a/src/Devlord.Utilities/ApiCall.cs b/src/Devlord.Utilities/ApiCall.cs index 6509398..5f44ba1 100644 --- a/src/Devlord.Utilities/ApiCall.cs +++ b/src/Devlord.Utilities/ApiCall.cs @@ -4,8 +4,7 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Text; -using Newtonsoft.Json; -using Newtonsoft.Json.Serialization; +using System.Text.Json; #pragma warning disable S1449 // Culture should be specified for "string" operations @@ -15,9 +14,9 @@ public class ApiCall : IApiCall { #region Fields - private readonly HttpClient _client = new HttpClient(); + private readonly HttpClient _client = new(); - private readonly JsonSerializerSettings _settings; + private readonly JsonSerializerOptions _settings; private bool _disposed; @@ -33,10 +32,10 @@ public ApiCall(string endpoint) QueryParams = new Dictionary(); Method = "GET"; _endPoint = endpoint; - _settings = new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }; + _settings = new JsonSerializerOptions(); } - public ApiCall(string endpoint, JsonSerializerSettings settings) + public ApiCall(string endpoint, JsonSerializerOptions settings) : this(endpoint) { _settings = settings; @@ -49,7 +48,7 @@ public ApiCall(Uri endpoint) protected ApiCall() { - _settings = new JsonSerializerSettings { ContractResolver = new DefaultContractResolver() }; + _settings = new JsonSerializerOptions(); } #endregion @@ -91,7 +90,7 @@ public virtual IApiResult Execute(Uri endPoint) where T : class } else { - serialize = JsonConvert.SerializeObject; + serialize = x => JsonSerializer.Serialize(x); format = "application/json"; } @@ -131,7 +130,7 @@ public virtual IApiResult Execute(Uri endPoint) where T : class // Assume we know how to deserialize the object. if (format.EndsWith("json")) { - var dataItem = JsonConvert.DeserializeObject(content, _settings); + var dataItem = JsonSerializer.Deserialize(content, _settings); return new ApiResult { StatusCode = response.StatusCode, DataItem = dataItem }; } diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 02ebfa8..33fb634 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -5,7 +5,7 @@ false false false - 7.0.0 + 7.0.1 Devlords Cooperative devlord https://github.com/lorddev/utilities @@ -23,11 +23,9 @@ - - diff --git a/src/Devlord.Utilities/DevlordOptions.cs b/src/Devlord.Utilities/DevlordOptions.cs index f5ff3d2..2c9d5ee 100644 --- a/src/Devlord.Utilities/DevlordOptions.cs +++ b/src/Devlord.Utilities/DevlordOptions.cs @@ -11,11 +11,6 @@ // Aaron Lord // -------------------------------------------------------------------------------------------------------------------- -using System; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; - namespace Devlord.Utilities { public class DevlordOptions diff --git a/src/Devlord.Utilities/UnderscoreContractResolver.cs b/src/Devlord.Utilities/UnderscoreContractResolver.cs deleted file mode 100644 index 40c98a8..0000000 --- a/src/Devlord.Utilities/UnderscoreContractResolver.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Text.RegularExpressions; -using Newtonsoft.Json.Serialization; - -namespace Devlord.Utilities -{ - public class UnderscoreContractResolver : DefaultContractResolver - { - #region Methods - - protected override string ResolvePropertyName(string propertyName) - { - return Regex.Replace(propertyName, "(?<=[a-z])[A-Z]", m => "_" + m).ToLower(); - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Devlord.Utilities/packages.config b/src/Devlord.Utilities/packages.config index 082ce43..bd4d7c8 100644 --- a/src/Devlord.Utilities/packages.config +++ b/src/Devlord.Utilities/packages.config @@ -3,6 +3,5 @@ - - + \ No newline at end of file diff --git a/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj b/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj index 2e715c7..7422ad5 100644 --- a/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj +++ b/test/Devlord.Utilities.Tests/Devlord.Utilities.Tests.csproj @@ -1,6 +1,6 @@ - net8.0;net10.0 + net10.0 10 false false @@ -27,7 +27,6 @@ - all @@ -41,6 +40,8 @@ + + diff --git a/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs b/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs index 5d36fe8..8b38b37 100644 --- a/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs +++ b/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs @@ -27,7 +27,8 @@ public DevlordTestConfiguration() .AddUserSecrets() .Build(); var services = new ServiceCollection().AddOptions(); - services.AddDevlordUtilities(config.GetSection("Devlord.Utilities")); + services.AddDevlordMail(config.GetSection("Devlord.Utilities")); + services.AddDevlordMaps(config.GetSection("Devlord.Utilities")); Options = services.BuildServiceProvider().GetService>().Value; //return config; } diff --git a/test/Devlord.Utilities.Tests/DistanceApiTests.cs b/test/Devlord.Utilities.Tests/DistanceApiTests.cs index 64a8040..27f6d0a 100644 --- a/test/Devlord.Utilities.Tests/DistanceApiTests.cs +++ b/test/Devlord.Utilities.Tests/DistanceApiTests.cs @@ -1,9 +1,9 @@ using System.Linq; using System.Net; using System.Net.Http; +using System.Text.Json; using System.Text.RegularExpressions; using Devlord.Utilities.MapsApi; -using Newtonsoft.Json; using Xunit; namespace Devlord.Utilities.Tests @@ -45,9 +45,9 @@ public void ReturnsDeserializedResults() var content = response.Content.ReadAsStringAsync().Result; - var settings = new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() }; + var settings = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower }; - var parsedObject = JsonConvert.DeserializeObject(content, settings); + var parsedObject = JsonSerializer.Deserialize(content, settings); Assert.Equal(typeof(DistanceElement), parsedObject.Rows.ElementAt(0).Elements.ElementAt(0).GetType()); @@ -65,7 +65,11 @@ public void ReturnsExpectedResultWithCustomApi() + _options.GoogleMapsApiKey; using (IApiCall client = new ApiCall(endPoint, - new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() })) + new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + WriteIndented = true, + })) { var result = client.Execute(); Assert.Equal(HttpStatusCode.OK, result.StatusCode); @@ -139,7 +143,11 @@ public void ReturnsResultWithCustomApiAndQueryParams() // sensor=false&origins=95969&destinations=95928 using (IApiCall client = new ApiCall(baseUri, - new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() })) + new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + WriteIndented = true, + })) { client.QueryParams.Add("sensor", "false"); client.QueryParams.Add("origins", "95969"); diff --git a/test/Devlord.Utilities.Tests/JsonDeserializerTests.cs b/test/Devlord.Utilities.Tests/JsonDeserializerTests.cs index 71e0ee0..aaf6074 100644 --- a/test/Devlord.Utilities.Tests/JsonDeserializerTests.cs +++ b/test/Devlord.Utilities.Tests/JsonDeserializerTests.cs @@ -1,8 +1,8 @@ using System.Linq; +using System.Text.Json; +using System.Text.Json.Nodes; using System.Text.RegularExpressions; using Devlord.Utilities.MapsApi; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; using Xunit; namespace Devlord.Utilities.Tests @@ -12,10 +12,14 @@ public class JsonDeserializerTests [Fact] public void TestCustomResolver() { - var settings = new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() }; + var settings = new JsonSerializerOptions + { + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + WriteIndented = true, + }; var bob = new { PropertyName = "asdf" }; - var json = JsonConvert.SerializeObject(bob, Formatting.Indented, settings); + var json = JsonSerializer.Serialize(bob, settings); // For macOS, Linux compatibility json = json.Replace("\r\n", "\n"); @@ -23,7 +27,7 @@ public void TestCustomResolver() } [Fact] - public void TestDeserializeDynamic() + public void TestDeserializeStronglyTyped() { var input = @"{ ""destination_addresses"" : [ ""Chico, CA 95928, USA"" ], @@ -49,43 +53,13 @@ public void TestDeserializeDynamic() } ".Replace("\r\n", "\n"); - var settings = new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() }; - - dynamic parsedObject = JsonConvert.DeserializeObject(input, settings); - - Assert.Equal(typeof(JObject), parsedObject.rows[0].elements[0].GetType()); - } - - [Fact] - public void TestDeserializeStrongTyped() - { - var input = @"{ - ""destination_addresses"" : [ ""Chico, CA 95928, USA"" ], - ""origin_addresses"" : [ ""Paradise, CA 95969, USA"" ], - ""rows"" : [ - { - ""elements"" : [ + var settings = new JsonSerializerOptions { - ""distance"" : { - ""text"" : ""27.7 km"", - ""value"" : 27722 - }, - ""duration"" : { - ""text"" : ""25 mins"", - ""value"" : 1518 - }, - ""status"" : ""OK"" - } - ] - } - ], - ""status"" : ""OK"" -} -".Replace("\r\n", "\n"); - - var settings = new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() }; + PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower, + WriteIndented = true, + }; - var parsedObject = JsonConvert.DeserializeObject(input, settings); + var parsedObject = JsonSerializer.Deserialize(input, settings); Assert.Equal(typeof(DistanceElement), parsedObject.Rows.ElementAt(0).Elements.ElementAt(0).GetType()); diff --git a/test/Devlord.Utilities.Tests/packages.config b/test/Devlord.Utilities.Tests/packages.config index 3358f43..3a0face 100644 --- a/test/Devlord.Utilities.Tests/packages.config +++ b/test/Devlord.Utilities.Tests/packages.config @@ -5,7 +5,6 @@ - \ No newline at end of file From 3e52103c6a1183d17a93c0113cd2653a6829dbd0 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 13:05:32 -0800 Subject: [PATCH 12/26] Fixed JSON serialization and updated READMEs --- README.md | 2 +- src/Devlord.Utilities.Mail/Botmail.cs | 4 +- .../Devlord.Utilities.Mail.csproj | 7 +- .../DevlordSettingsExtension.cs | 2 +- src/Devlord.Utilities.Mail/GmailThrottles.cs | 6 +- src/Devlord.Utilities.Mail/IMailbotFactory.cs | 2 +- src/Devlord.Utilities.Mail/MailFormat.cs | 2 +- src/Devlord.Utilities.Mail/MailThrottle.cs | 6 +- src/Devlord.Utilities.Mail/Mailbot.cs | 3 +- src/Devlord.Utilities.Mail/MailbotFactory.cs | 4 +- src/Devlord.Utilities.Mail/README.md | 69 +++++++++++++++++++ .../ThrottleInterval.cs | 2 +- src/Devlord.Utilities.Mail/Throttles.cs | 6 +- .../Devlord.Utilities.MapsApi.csproj | 7 +- src/Devlord.Utilities.MapsApi/README.md | 67 ++++++++++++++++++ .../DevlordTestConfiguration.cs | 1 + test/Devlord.Utilities.Tests/MailTests.cs | 1 + 17 files changed, 161 insertions(+), 30 deletions(-) create mode 100644 src/Devlord.Utilities.Mail/README.md create mode 100644 src/Devlord.Utilities.MapsApi/README.md diff --git a/README.md b/README.md index 50bd10c..69b95b2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -devlord utilities +Devlord.Utilities ==================== diff --git a/src/Devlord.Utilities.Mail/Botmail.cs b/src/Devlord.Utilities.Mail/Botmail.cs index 91d8c5c..dd7c1e5 100644 --- a/src/Devlord.Utilities.Mail/Botmail.cs +++ b/src/Devlord.Utilities.Mail/Botmail.cs @@ -6,9 +6,7 @@ // aaron@lorddesign.net // -------------------------------------------------------------------------------------------------------------------- -using System.Collections.Generic; - -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { /// /// The botmail. diff --git a/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj b/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj index d1cbc21..d7587c5 100644 --- a/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj +++ b/src/Devlord.Utilities.Mail/Devlord.Utilities.Mail.csproj @@ -10,7 +10,7 @@ https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE - https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png + devlord-105.png https://github.com/lorddev/utilities Git utils utilities email gmail mailbot @@ -19,6 +19,11 @@ + + + + + diff --git a/src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs b/src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs index bb6f911..c9459b8 100644 --- a/src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs +++ b/src/Devlord.Utilities.Mail/DevlordSettingsExtension.cs @@ -12,7 +12,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { public static class DevlordSettingsExtension { diff --git a/src/Devlord.Utilities.Mail/GmailThrottles.cs b/src/Devlord.Utilities.Mail/GmailThrottles.cs index 212eb08..d293ecb 100644 --- a/src/Devlord.Utilities.Mail/GmailThrottles.cs +++ b/src/Devlord.Utilities.Mail/GmailThrottles.cs @@ -1,8 +1,4 @@ -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { /// /// The throttles. diff --git a/src/Devlord.Utilities.Mail/IMailbotFactory.cs b/src/Devlord.Utilities.Mail/IMailbotFactory.cs index 06fee98..15dc414 100644 --- a/src/Devlord.Utilities.Mail/IMailbotFactory.cs +++ b/src/Devlord.Utilities.Mail/IMailbotFactory.cs @@ -9,7 +9,7 @@ // Aaron Lord // -------------------------------------------------------------------------------------------------------------------- -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { public interface IMailbotFactory { diff --git a/src/Devlord.Utilities.Mail/MailFormat.cs b/src/Devlord.Utilities.Mail/MailFormat.cs index 1e544fc..49d1e16 100644 --- a/src/Devlord.Utilities.Mail/MailFormat.cs +++ b/src/Devlord.Utilities.Mail/MailFormat.cs @@ -1,4 +1,4 @@ -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { public enum MailFormat { diff --git a/src/Devlord.Utilities.Mail/MailThrottle.cs b/src/Devlord.Utilities.Mail/MailThrottle.cs index 7957cec..4ee9950 100644 --- a/src/Devlord.Utilities.Mail/MailThrottle.cs +++ b/src/Devlord.Utilities.Mail/MailThrottle.cs @@ -10,11 +10,7 @@ // aaron@lorddesign.net // -------------------------------------------------------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Linq; - -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { /// /// The mail throttle. diff --git a/src/Devlord.Utilities.Mail/Mailbot.cs b/src/Devlord.Utilities.Mail/Mailbot.cs index a4c8bec..200a9d7 100644 --- a/src/Devlord.Utilities.Mail/Mailbot.cs +++ b/src/Devlord.Utilities.Mail/Mailbot.cs @@ -10,12 +10,11 @@ // aaron@lorddesign.net // -------------------------------------------------------------------------------------------------------------------- -using System.Threading.Tasks; using MailKit.Net.Smtp; using MailKit.Security; using MimeKit; -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { /// /// Multi-threaded mailer to keep your systems running by sending messages asynchronously. If you're using it in a diff --git a/src/Devlord.Utilities.Mail/MailbotFactory.cs b/src/Devlord.Utilities.Mail/MailbotFactory.cs index 28356e1..53da23c 100644 --- a/src/Devlord.Utilities.Mail/MailbotFactory.cs +++ b/src/Devlord.Utilities.Mail/MailbotFactory.cs @@ -9,14 +9,12 @@ // Aaron Lord // -------------------------------------------------------------------------------------------------------------------- -using System.Collections.Generic; -using System.Linq; using System.Runtime.CompilerServices; using Devlord.Utilities.Exceptions; using Microsoft.Extensions.Options; [assembly: InternalsVisibleTo("Devlord.Utilities.Tests")] -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { public class MailbotFactory : IMailbotFactory { diff --git a/src/Devlord.Utilities.Mail/README.md b/src/Devlord.Utilities.Mail/README.md new file mode 100644 index 0000000..5505f61 --- /dev/null +++ b/src/Devlord.Utilities.Mail/README.md @@ -0,0 +1,69 @@ +Devlord.Utilities.Mail +==================== + + +A useful class library for universal utilities like sending emails and consuming RESTful APIs. + +| Master | Develop | NuGet | +| ----- | ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | + +To install Devlord.Utilities.Mail, run the following command in the Package Manager Console: + + PM> Install-Package Devlord.Utilities.Mail + +Or from the command-line: + + dotnet add package Devlord.Utilities.Mail + +### Changes from Devlord.Utilities 6.0 + +* Mail utilities have been moved to the Devlord.Utilities.Mail package. +* `Devlord.Utilities.Mail` is the new namespace. + +### Feature Summary + +* .NET Core compatibility +* Email throttling to help you avoid being suspended by your ISP + +More details below, but for even _more_ details, see the [project wiki](https://github.com/lorddev/utilities/wiki). + +### Mailbot + +A multithreaded SMTP queued mail sender, has a configurable throttle for mail frequency sent by a single account. + +**Configuration** + +```json +{ + "Devlord.Utilities": { + "MailSettings": [ + { + "Name": "Gmail", + "SmtpServer": "mail.google.com", + "SmtpPort": 587, + "SmtpPassword": "", + "MaxPerMinute": 500, + "MaxPerHour": 500, + "MaxPerDay": 500 + } + ] + } +} +``` + +### Contributing + +Yes, please! + +### License + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published +by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see . + +Contact [lorddev](https://github.com/lorddev) on GitHub or [@devlord@hachyderm.io](https://hachyderm.io/@devlord) on Mastodon. diff --git a/src/Devlord.Utilities.Mail/ThrottleInterval.cs b/src/Devlord.Utilities.Mail/ThrottleInterval.cs index adc58d1..d016631 100644 --- a/src/Devlord.Utilities.Mail/ThrottleInterval.cs +++ b/src/Devlord.Utilities.Mail/ThrottleInterval.cs @@ -1,4 +1,4 @@ -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { /// /// The throttle interval. diff --git a/src/Devlord.Utilities.Mail/Throttles.cs b/src/Devlord.Utilities.Mail/Throttles.cs index 642abf3..b7388df 100644 --- a/src/Devlord.Utilities.Mail/Throttles.cs +++ b/src/Devlord.Utilities.Mail/Throttles.cs @@ -1,8 +1,4 @@ -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Devlord.Utilities +namespace Devlord.Utilities.Mail { /// /// The throttles. diff --git a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj index c9cca44..4617119 100644 --- a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj +++ b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj @@ -10,7 +10,7 @@ https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE - https://raw.githubusercontent.com/lorddev/devlords-org/develop/Image.png + devlord-105.png https://github.com/lorddev/utilities Git utils utilities distance-matrix @@ -18,6 +18,11 @@ README.md + + + + + diff --git a/src/Devlord.Utilities.MapsApi/README.md b/src/Devlord.Utilities.MapsApi/README.md new file mode 100644 index 0000000..7719326 --- /dev/null +++ b/src/Devlord.Utilities.MapsApi/README.md @@ -0,0 +1,67 @@ +Devlord.Utilities.MapsApi +==================== + + +A useful class library for universal utilities like sending emails and consuming RESTful APIs. + +| Master | Develop | NuGet | +| ----- | ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | + +To install Devlord.Utilities.MapsApi, run the following command in the Package Manager Console: + + PM> Install-Package Devlord.Utilities.MapsApi + +Or from the command-line: + + dotnet add package Devlord.Utilities.MapsApi + +### Changes from Devlord.Utilities 6.0 + +* UnderscoreContractResolver has been removed in favor of System.Text.Json snake case handling. +* ValueText.Value has been changed from string to decimal. + +### Distance API + +POCO classes for accessing the Google Maps distance API. + +Usage with a custom JSON contract resolver that converts the Google JSON property names to POCO object properties. + +```csharp + const string BaseUri = "https://maps.googleapis.com/maps/api/distancematrix/json"; + + using (IApiCall client = new ApiCall(BaseUri, + new JsonSerializerSettings { ContractResolver = new UnderscoreContractResolver() })) + { + client.QueryParams.Add("sensor", "false"); + client.QueryParams.Add("origins", "95969"); + client.QueryParams.Add("destinations", "95928"); + IApiResult result = client.Execute(); + } +``` + +**Configuration** + +```json +{ + "Devlord.Utilities": { + "GoogleMapsApiKey": "", + } +} +``` + +### Contributing + +Yes, please! + +### License + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published +by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see . + +Contact [lorddev](https://github.com/lorddev) on GitHub or [@devlord@hachyderm.io](https://hachyderm.io/@devlord) on Mastodon. diff --git a/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs b/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs index 8b38b37..2b590da 100644 --- a/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs +++ b/test/Devlord.Utilities.Tests/DevlordTestConfiguration.cs @@ -9,6 +9,7 @@ // Aaron Lord // -------------------------------------------------------------------------------------------------------------------- +using Devlord.Utilities.Mail; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; diff --git a/test/Devlord.Utilities.Tests/MailTests.cs b/test/Devlord.Utilities.Tests/MailTests.cs index ff63bc2..2a9d55b 100644 --- a/test/Devlord.Utilities.Tests/MailTests.cs +++ b/test/Devlord.Utilities.Tests/MailTests.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Devlord.Utilities.Exceptions; +using Devlord.Utilities.Mail; using Xunit; namespace Devlord.Utilities.Tests From adeb29061af694902b33cd74fc8ccbec21690d98 Mon Sep 17 00:00:00 2001 From: Aaron Lord Date: Sat, 28 Feb 2026 13:19:20 -0800 Subject: [PATCH 13/26] Package config --- .github/workflows/package.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 8741179..475a76f 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -21,10 +21,10 @@ jobs: - name: Pack prerelease with build number if: "github.event.release.prerelease" run: | - dotnet pack src/Devlord.Utilities/Devlord.Utilities.csproj --configuration Release --output ./nupkg \ + dotnet pack --configuration Release --output ./nupkg \ -p:VersionSuffix="preview.${{ github.run_number }}" - name: Pack release if: "!github.event.release.prerelease" run: dotnet pack src/Devlord.Utilities/Devlord.Utilities.csproj --configuration Release --output ./nupkg - - name: Publish the package to NuGet + - name: Publish packages to NuGet run: dotnet nuget push "./nupkg/*.nupkg" --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json \ No newline at end of file From 7b465ee5a523727f8debdb0c0870473d9026da68 Mon Sep 17 00:00:00 2001 From: Aaron Lord Date: Sat, 28 Feb 2026 13:19:37 -0800 Subject: [PATCH 14/26] Package config for 7.0.1 --- .nupkg/Devlord.Utilities.7.0.1-local.nupkg | Bin 0 -> 43130 bytes .nupkg/Devlord.Utilities.Mail.7.0.1-local.nupkg | Bin 0 -> 35674 bytes .../Devlord.Utilities.MapsApi.7.0.1-local.nupkg | Bin 0 -> 32033 bytes Devlord.Utilities.sln | 2 ++ .../Devlord.Utilities.Mail.csproj | 5 +++-- .../Devlord.Utilities.MapsApi.csproj | 5 +++-- src/Devlord.Utilities/Devlord.Utilities.csproj | 3 ++- .../Exceptions/DevlordConfigurationException.cs | 5 ----- 8 files changed, 10 insertions(+), 10 deletions(-) create mode 100644 .nupkg/Devlord.Utilities.7.0.1-local.nupkg create mode 100644 .nupkg/Devlord.Utilities.Mail.7.0.1-local.nupkg create mode 100644 .nupkg/Devlord.Utilities.MapsApi.7.0.1-local.nupkg diff --git a/.nupkg/Devlord.Utilities.7.0.1-local.nupkg b/.nupkg/Devlord.Utilities.7.0.1-local.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..268ad3573bdd6fc3bef2ed49f5d83b6393c82281 GIT binary patch literal 43130 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
jJo91Jb!VIdE;O|n894z@Ix6Xj`f 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 bm;Zkl#A-?~u>TYR|FQFaG&*a=KdJu%_pC-J literal 0 HcmV?d00001 diff --git a/.nupkg/Devlord.Utilities.Mail.7.0.1-local.nupkg b/.nupkg/Devlord.Utilities.Mail.7.0.1-local.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..22ad89652c6edb0d80d8b426000524ff65f18f10 GIT binary patch literal 35674 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 U?Kg;gn?ek@ErCTNbpBiK9}0X}t^fc4 literal 0 HcmV?d00001 diff --git a/.nupkg/Devlord.Utilities.MapsApi.7.0.1-local.nupkg b/.nupkg/Devlord.Utilities.MapsApi.7.0.1-local.nupkg new file mode 100644 index 0000000000000000000000000000000000000000..9351923dde5789a319b6603552f13bf9d7498a00 GIT binary patch literal 32033 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 z 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 j{P!#P9|w~j{~xYrC0R(Q|L6kd>mm6SG={wX - net10.0 + net8.0;net10.0 enable enable 7.0.1 @@ -9,7 +9,7 @@ devlord https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord - https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE + LICENSE devlord-105.png https://github.com/lorddev/utilities Git @@ -20,6 +20,7 @@ + diff --git a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj index 4617119..4703f35 100644 --- a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj +++ b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj @@ -1,7 +1,7 @@  - net10.0 + net8.0;net10.0 enable enable 7.0.1 @@ -9,7 +9,7 @@ devlord https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord - https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE + LICENSE devlord-105.png https://github.com/lorddev/utilities Git @@ -20,6 +20,7 @@ + diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 17dd91b..2067670 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -10,7 +10,7 @@ devlord https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord - https://raw.githubusercontent.com/lorddev/utilities/master/LICENSE + LICENSE devlord-105.png https://github.com/lorddev/utilities Git @@ -36,6 +36,7 @@ + diff --git a/src/Devlord.Utilities/Exceptions/DevlordConfigurationException.cs b/src/Devlord.Utilities/Exceptions/DevlordConfigurationException.cs index 4d3312f..1342151 100644 --- a/src/Devlord.Utilities/Exceptions/DevlordConfigurationException.cs +++ b/src/Devlord.Utilities/Exceptions/DevlordConfigurationException.cs @@ -21,10 +21,5 @@ public class DevlordConfigurationException : Exception public DevlordConfigurationException(string s) : base(s) { } - - protected DevlordConfigurationException(SerializationInfo info, StreamingContext context) : base(info, context) - { - - } } } \ No newline at end of file From d783def757ab638a18a8e3008c3e3040d63babbc Mon Sep 17 00:00:00 2001 From: Aaron Lord Date: Sat, 28 Feb 2026 13:55:11 -0800 Subject: [PATCH 15/26] Nuget License configuration --- .../Devlord.Utilities.MapsApi.7.0.1-local.nupkg | Bin 32033 -> 0 bytes Devlord.Utilities.sln | 2 +- LICENSE => LICENSE.txt | 0 .../Devlord.Utilities.Mail.csproj | 4 ++-- .../Devlord.Utilities.MapsApi.csproj | 4 ++-- src/Devlord.Utilities/Devlord.Utilities.csproj | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 .nupkg/Devlord.Utilities.MapsApi.7.0.1-local.nupkg rename LICENSE => LICENSE.txt (100%) diff --git a/.nupkg/Devlord.Utilities.MapsApi.7.0.1-local.nupkg b/.nupkg/Devlord.Utilities.MapsApi.7.0.1-local.nupkg deleted file mode 100644 index 9351923dde5789a319b6603552f13bf9d7498a00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32033 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 z 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 https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord - LICENSE + GPL-3.0-only devlord-105.png https://github.com/lorddev/utilities Git @@ -20,7 +20,7 @@ - + diff --git a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj index 4703f35..15bc0c3 100644 --- a/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj +++ b/src/Devlord.Utilities.MapsApi/Devlord.Utilities.MapsApi.csproj @@ -9,7 +9,7 @@ devlord https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord - LICENSE + GPL-3.0-only devlord-105.png https://github.com/lorddev/utilities Git @@ -20,7 +20,7 @@ - + diff --git a/src/Devlord.Utilities/Devlord.Utilities.csproj b/src/Devlord.Utilities/Devlord.Utilities.csproj index 2067670..d132c4e 100644 --- a/src/Devlord.Utilities/Devlord.Utilities.csproj +++ b/src/Devlord.Utilities/Devlord.Utilities.csproj @@ -10,7 +10,7 @@ devlord https://github.com/lorddev/utilities Copyright © 2026 Aaron Lord - LICENSE + GPL-3.0-only devlord-105.png https://github.com/lorddev/utilities Git @@ -36,7 +36,7 @@ - + From 3b8a654bfe14ae61ec847771a880893fa2cf6a36 Mon Sep 17 00:00:00 2001 From: Aaron Lord Date: Sat, 28 Feb 2026 14:01:14 -0800 Subject: [PATCH 16/26] Skip unit tests that rely on user secrets --- test/Devlord.Utilities.Tests/DistanceApiTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/Devlord.Utilities.Tests/DistanceApiTests.cs b/test/Devlord.Utilities.Tests/DistanceApiTests.cs index 27f6d0a..02200bc 100644 --- a/test/Devlord.Utilities.Tests/DistanceApiTests.cs +++ b/test/Devlord.Utilities.Tests/DistanceApiTests.cs @@ -26,7 +26,7 @@ private static double ParseDuration(string distanceString) return double.Parse(resultDuration); } - [Fact] + [Fact(Skip = "Needs to be run with user secrets")] public void ReturnsDeserializedResults() { var endPoint = @@ -57,7 +57,7 @@ public void ReturnsDeserializedResults() } } - [Fact] + [Fact(Skip = "Needs to be run with user secrets")] public void ReturnsExpectedResultWithCustomApi() { string endPoint = @@ -135,7 +135,7 @@ public void ReturnsJsonResults() } } - [Fact] + [Fact(Skip = "Needs to be run with user secrets")] public void ReturnsResultWithCustomApiAndQueryParams() { string baseUri = "https://maps.googleapis.com/maps/api/distancematrix/json?key=" From 2d610052791e162f19823bf7134566207dae5ef0 Mon Sep 17 00:00:00 2001 From: Aaron Lord Date: Sat, 28 Feb 2026 14:14:14 -0800 Subject: [PATCH 17/26] help --- .github/workflows/package.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml index 74da637..32bcad6 100644 --- a/.github/workflows/package.yml +++ b/.github/workflows/package.yml @@ -10,6 +10,7 @@ jobs: permissions: packages: write contents: read + id-token: write steps: - uses: actions/checkout@v5 - uses: actions/setup-dotnet@v4 @@ -31,7 +32,7 @@ jobs: uses: NuGet/login@v1 id: login with: - user: ${{ secrets.NUGET_USER }} + user: devlord - name: Publish packages to NuGet - run: dotnet nuget push "./nupkg/*.nupkg" --api-key ${{steps.login.outputs.NUGET_API_KEY}} --source https://api.nuget.org/v3/index.json + run: dotnet nuget push "./nupkg/*.nupkg" --api-key "${{ steps.login.outputs.NUGET_API_KEY }}" --source https://www.nuget.org/api/v2/package From b84941dca9c32950969c7de01db29cd219e8c37b Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:46:31 -0800 Subject: [PATCH 18/26] Update README.md Remove appveyor. --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 69b95b2..cc66721 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,11 @@ Devlord.Utilities ==================== +A useful class library for universal utilities like consuming RESTful APIs. -A useful class library for universal utilities like sending emails and consuming RESTful APIs. - -| Master | Develop | NuGet | -| ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | +| Build | NuGet | +| ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | To install Devlord.Utilities, run the following command in the Package Manager Console: From 6812047b1b00790d1acac325cf4610c6923ec752 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:47:48 -0800 Subject: [PATCH 19/26] Update README.md --- src/Devlord.Utilities.Mail/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Devlord.Utilities.Mail/README.md b/src/Devlord.Utilities.Mail/README.md index 5505f61..fec1bbc 100644 --- a/src/Devlord.Utilities.Mail/README.md +++ b/src/Devlord.Utilities.Mail/README.md @@ -4,9 +4,10 @@ Devlord.Utilities.Mail A useful class library for universal utilities like sending emails and consuming RESTful APIs. -| Master | Develop | NuGet | -| ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | + +| Build | NuGet | +| ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.Mail/) | To install Devlord.Utilities.Mail, run the following command in the Package Manager Console: From 06c1f18ca2c6c74e0b17d19346d12f70ce80ca1f Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:48:13 -0800 Subject: [PATCH 20/26] Update README.md --- src/Devlord.Utilities.MapsApi/README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Devlord.Utilities.MapsApi/README.md b/src/Devlord.Utilities.MapsApi/README.md index 7719326..9906333 100644 --- a/src/Devlord.Utilities.MapsApi/README.md +++ b/src/Devlord.Utilities.MapsApi/README.md @@ -4,9 +4,10 @@ Devlord.Utilities.MapsApi A useful class library for universal utilities like sending emails and consuming RESTful APIs. -| Master | Develop | NuGet | -| ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![Build status](https://ci.appveyor.com/api/projects/status/i0us4v5jxi6llk3e/branch/develop?svg=true)](https://ci.appveyor.com/project/lorddev/utilities/branch/develop) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | + +| Build | NuGet | +| ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.MapsApi/) | To install Devlord.Utilities.MapsApi, run the following command in the Package Manager Console: From 2eb3069fc256851e388f0af8bed028c67bdaa6b8 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:51:22 -0800 Subject: [PATCH 21/26] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index cc66721..ca89052 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ Devlord.Utilities A useful class library for universal utilities like consuming RESTful APIs. -| Build | NuGet | -| ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | +| Main | Develop | NuGet | +| ----- | ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | To install Devlord.Utilities, run the following command in the Package Manager Console: From 60d24d7a1221798517d87ce37d06e6b1fb035791 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:51:47 -0800 Subject: [PATCH 22/26] Update README.md --- src/Devlord.Utilities.Mail/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Devlord.Utilities.Mail/README.md b/src/Devlord.Utilities.Mail/README.md index fec1bbc..e7321c8 100644 --- a/src/Devlord.Utilities.Mail/README.md +++ b/src/Devlord.Utilities.Mail/README.md @@ -4,10 +4,9 @@ Devlord.Utilities.Mail A useful class library for universal utilities like sending emails and consuming RESTful APIs. - -| Build | NuGet | -| ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.Mail/) | +| Main | Develop | NuGet | +| ----- | ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.Mail/) | To install Devlord.Utilities.Mail, run the following command in the Package Manager Console: From d4a39fea2d39c10bb50792246e2447a5a448479d Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:52:03 -0800 Subject: [PATCH 23/26] Update README.md --- src/Devlord.Utilities.MapsApi/README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Devlord.Utilities.MapsApi/README.md b/src/Devlord.Utilities.MapsApi/README.md index 9906333..467b698 100644 --- a/src/Devlord.Utilities.MapsApi/README.md +++ b/src/Devlord.Utilities.MapsApi/README.md @@ -4,10 +4,9 @@ Devlord.Utilities.MapsApi A useful class library for universal utilities like sending emails and consuming RESTful APIs. - -| Build | NuGet | -| ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.MapsApi/) | +| Main | Develop | NuGet | +| ----- | ----- | ----- | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.MapsApi/) | To install Devlord.Utilities.MapsApi, run the following command in the Package Manager Console: From 8fe5e04d3896815e793c29c9821dd0297e97f93d Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:55:37 -0800 Subject: [PATCH 24/26] Update README.md --- src/Devlord.Utilities.Mail/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Devlord.Utilities.Mail/README.md b/src/Devlord.Utilities.Mail/README.md index e7321c8..60b336a 100644 --- a/src/Devlord.Utilities.Mail/README.md +++ b/src/Devlord.Utilities.Mail/README.md @@ -6,7 +6,7 @@ A useful class library for universal utilities like sending emails and consuming | Main | Develop | NuGet | | ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.Mail/) | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![NuGet](https://img.shields.io/badge/nuget-%23004880.svg?style=for-the-badge&logo=nuget&logoColor=white)](https://www.nuget.org/packages/Devlord.Utilities.Mail/) | To install Devlord.Utilities.Mail, run the following command in the Package Manager Console: From e7a719679ad668becf6a1bc442105e7147773a5c Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:55:58 -0800 Subject: [PATCH 25/26] Update README.md --- src/Devlord.Utilities.MapsApi/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Devlord.Utilities.MapsApi/README.md b/src/Devlord.Utilities.MapsApi/README.md index 467b698..6cbf036 100644 --- a/src/Devlord.Utilities.MapsApi/README.md +++ b/src/Devlord.Utilities.MapsApi/README.md @@ -6,7 +6,7 @@ A useful class library for universal utilities like sending emails and consuming | Main | Develop | NuGet | | ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities.MapsApi/) | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![NuGet](https://img.shields.io/badge/nuget-%23004880.svg?style=for-the-badge&logo=nuget&logoColor=white)](https://www.nuget.org/packages/Devlord.Utilities.MapsApi/) | To install Devlord.Utilities.MapsApi, run the following command in the Package Manager Console: From 58827ae568fcc3d4f534a883c3d48e2e89fa9f18 Mon Sep 17 00:00:00 2001 From: Aaron Date: Sat, 28 Feb 2026 14:56:22 -0800 Subject: [PATCH 26/26] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ca89052..9f363ff 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A useful class library for universal utilities like consuming RESTful APIs. | Main | Develop | NuGet | | ----- | ----- | ----- | -| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [NuGet](https://www.nuget.org/packages/Devlord.Utilities/) | +| [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![.NET](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml/badge.svg?branch=develop)](https://github.com/lorddev/utilities/actions/workflows/dotnet.yml) | [![NuGet](https://img.shields.io/badge/nuget-%23004880.svg?style=for-the-badge&logo=nuget&logoColor=white)](https://www.nuget.org/packages/Devlord.Utilities/) | To install Devlord.Utilities, run the following command in the Package Manager Console: