diff --git a/src/MaksIT.Core/Culture.cs b/src/MaksIT.Core/Culture.cs
index c67ff46..e00ccc1 100644
--- a/src/MaksIT.Core/Culture.cs
+++ b/src/MaksIT.Core/Culture.cs
@@ -1,6 +1,6 @@
-using System;
+using System.Diagnostics.CodeAnalysis;
using System.Globalization;
-using System.Threading;
+
namespace MaksIT.Core;
@@ -15,7 +15,7 @@ public static class Culture {
/// The culture to set. If null or empty, the invariant culture is used.
/// The error message if the operation fails.
/// True if the operation was successful; otherwise, false.
- public static bool TrySet(string? culture, out string? errorMessage) {
+ public static bool TrySet(string? culture, [NotNullWhen(false)] out string? errorMessage) {
try {
var threadCulture = CultureInfo.InvariantCulture;
diff --git a/src/MaksIT.Core/EnvVar.cs b/src/MaksIT.Core/EnvVar.cs
index eb07235..7c12016 100644
--- a/src/MaksIT.Core/EnvVar.cs
+++ b/src/MaksIT.Core/EnvVar.cs
@@ -1,6 +1,7 @@
-using System;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
+
namespace MaksIT.Core;
///
@@ -15,7 +16,7 @@ public static class EnvVar {
/// The new path to add.
/// The error message if the operation fails.
/// True if the operation was successful; otherwise, false.
- public static bool TryAddToPath(string newPath, out string? errorMessage) {
+ public static bool TryAddToPath(string newPath, [NotNullWhen(false)] out string? errorMessage) {
try {
var pathEnvVar = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
char separator = IsWindows ? ';' : ':';
@@ -42,7 +43,7 @@ public static class EnvVar {
/// The target of the environment variable (machine, user, process).
/// The error message if the operation fails.
/// True if the operation was successful; otherwise, false.
- public static bool TrySet(string envName, string envValue, string envTarget, out string? errorMessage) {
+ public static bool TrySet(string envName, string envValue, string envTarget, [NotNullWhen(false)] out string? errorMessage) {
try {
EnvironmentVariableTarget target = GetEnvironmentVariableTarget(envTarget);
if (target == EnvironmentVariableTarget.Machine && !IsWindows) {
@@ -66,7 +67,7 @@ public static class EnvVar {
/// The target of the environment variable (machine, user, process).
/// The error message if the operation fails.
/// True if the operation was successful; otherwise, false.
- public static bool TryUnSet(string envName, string envTarget, out string? errorMessage) {
+ public static bool TryUnSet(string envName, string envTarget, [NotNullWhen(false)] out string? errorMessage) {
try {
EnvironmentVariableTarget target = GetEnvironmentVariableTarget(envTarget);
if (target == EnvironmentVariableTarget.Machine && !IsWindows) {
diff --git a/src/MaksIT.Core/FileSystem.cs b/src/MaksIT.Core/FileSystem.cs
index 4d23fd5..661c433 100644
--- a/src/MaksIT.Core/FileSystem.cs
+++ b/src/MaksIT.Core/FileSystem.cs
@@ -1,6 +1,8 @@
-using System.Runtime.InteropServices;
+using System.Diagnostics.CodeAnalysis;
+using System.Runtime.InteropServices;
using MaksIT.Core.Extensions;
+
namespace MaksIT.Core;
///
@@ -18,7 +20,7 @@ public static class FileSystem {
/// Whether to overwrite existing files.
/// The error message if the operation fails.
/// True if the copy operation was successful; otherwise, false.
- public static bool TryCopyToFolder(string sourcePath, string destDirPath, bool overwrite, out string? errorMessage) {
+ public static bool TryCopyToFolder(string sourcePath, string destDirPath, bool overwrite, [NotNullWhen(false)] out string? errorMessage) {
try {
if (!Directory.Exists(destDirPath)) {
Directory.CreateDirectory(destDirPath);
@@ -58,7 +60,7 @@ public static class FileSystem {
/// File or directory path.
/// The error message if the operation fails.
/// True if the delete operation was successful; otherwise, false.
- public static bool TryDeleteFileOrDirectory(string itemPath, out string? errorMessage) {
+ public static bool TryDeleteFileOrDirectory(string itemPath, [NotNullWhen(false)] out string? errorMessage) {
try {
if (File.Exists(itemPath)) {
File.Delete(itemPath);
@@ -169,7 +171,7 @@ public static class FileSystem {
var count = 1;
while (File.Exists(newFullPath)) {
var tempFileName = $"{fileNameOnly}({count++})";
- newFullPath = Path.Combine(path, tempFileName + extension);
+ newFullPath = Path.Combine(path, $"{tempFileName}{extension}");
}
return newFullPath;
diff --git a/src/MaksIT.Core/MaksIT.Core.csproj b/src/MaksIT.Core/MaksIT.Core.csproj
index e2cc200..ab9b39a 100644
--- a/src/MaksIT.Core/MaksIT.Core.csproj
+++ b/src/MaksIT.Core/MaksIT.Core.csproj
@@ -8,7 +8,7 @@
MaksIT.Core
- 1.1.7
+ 1.1.8
Maksym Sadovnychyy
MAKS-IT
MaksIT.Core
diff --git a/src/MaksIT.Core/Networking/PingPort.cs b/src/MaksIT.Core/Networking/PingPort.cs
index dfe2369..0691c7a 100644
--- a/src/MaksIT.Core/Networking/PingPort.cs
+++ b/src/MaksIT.Core/Networking/PingPort.cs
@@ -1,6 +1,8 @@
using System.Net;
using System.Net.Sockets;
using System.Text;
+using System.Diagnostics.CodeAnalysis;
+
namespace MaksIT.Core.Networking;
@@ -15,7 +17,11 @@ public static class PingPort {
/// The port number.
/// The error message if the operation fails.
/// True if the host is reachable on the specified port; otherwise, false.
- public static bool TryHostPort(string hostUri, int portNumber, out string? errorMessage) {
+ public static bool TryHostPort(
+ string hostUri,
+ int portNumber,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
if (string.IsNullOrEmpty(hostUri)) {
errorMessage = "Host URI cannot be null or empty.";
return false;
@@ -53,7 +59,11 @@ public static class PingPort {
/// The port number.
/// The error message if the operation fails.
/// True if the host is reachable on the specified port; otherwise, false.
- public static bool TryUDPPort(string hostUri, int portNumber, out string? errorMessage) {
+ public static bool TryUDPPort(
+ string hostUri,
+ int portNumber,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
if (string.IsNullOrEmpty(hostUri)) {
errorMessage = "Host URI cannot be null or empty.";
return false;
diff --git a/src/MaksIT.Core/Networking/Windows/NetworkConnection.cs b/src/MaksIT.Core/Networking/Windows/NetworkConnection.cs
index 67799cb..14995d3 100644
--- a/src/MaksIT.Core/Networking/Windows/NetworkConnection.cs
+++ b/src/MaksIT.Core/Networking/Windows/NetworkConnection.cs
@@ -1,7 +1,8 @@
-using Microsoft.Extensions.Logging;
-using System;
+using System.Diagnostics.CodeAnalysis;
using System.Net;
using System.Runtime.InteropServices;
+using Microsoft.Extensions.Logging;
+
namespace MaksIT.Core.Networking.Windows;
@@ -15,11 +16,12 @@ public class NetworkConnection : IDisposable {
}
public static bool TryCreate(
- ILogger logger,
- string networkName,
- NetworkCredential credentials,
- out NetworkConnection? networkConnection,
- out string? errorMessage) {
+ ILogger logger,
+ string networkName,
+ NetworkCredential credentials,
+ [NotNullWhen(true)] out NetworkConnection? networkConnection,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
if (!OperatingSystem.IsWindows()) {
throw new PlatformNotSupportedException("NetworkConnection is only supported on Windows.");
@@ -81,7 +83,7 @@ public class NetworkConnection : IDisposable {
public ResourceDisplayType DisplayType;
public int Usage;
public string? LocalName;
- public string RemoteName;
+ public string? RemoteName;
public string? Comment;
public string? Provider;
}
diff --git a/src/MaksIT.Core/Processes.cs b/src/MaksIT.Core/Processes.cs
index 938165b..2b22556 100644
--- a/src/MaksIT.Core/Processes.cs
+++ b/src/MaksIT.Core/Processes.cs
@@ -1,5 +1,7 @@
using MaksIT.Core.Extensions;
using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+
namespace MaksIT.Core;
@@ -27,7 +29,7 @@ public static class Processes {
/// If true, the process will be started without creating a window.
/// The error message if the operation fails.
/// True if the process started successfully; otherwise, false.
- public static bool TryStart(string fileName, string arguments, int timeout, bool silent, out string? errorMessage) {
+ public static bool TryStart(string fileName, string arguments, int timeout, bool silent, [NotNullWhen(false)] out string? errorMessage) {
try {
var processInfo = new ProcessStartInfo(fileName) {
Arguments = arguments,
@@ -60,7 +62,7 @@ public static class Processes {
/// Process name. Accepts wildcards '*' or '?'
/// The error message if the operation fails.
/// True if at least one process was killed successfully; otherwise, false.
- public static bool TryKill(string process, out string? errorMessage) {
+ public static bool TryKill(string process, [NotNullWhen(false)] out string? errorMessage) {
bool success = false;
errorMessage = null;
foreach (var proc in System.Diagnostics.Process.GetProcesses()) {
diff --git a/src/MaksIT.Core/Security/AESGCMUtility.cs b/src/MaksIT.Core/Security/AESGCMUtility.cs
index 05d4987..bd1e3a8 100644
--- a/src/MaksIT.Core/Security/AESGCMUtility.cs
+++ b/src/MaksIT.Core/Security/AESGCMUtility.cs
@@ -1,4 +1,6 @@
using System.Security.Cryptography;
+using System.Diagnostics.CodeAnalysis;
+
namespace MaksIT.Core.Security;
@@ -9,7 +11,12 @@ public static class AESGCMUtility {
private const int IvLength = 12; // 12 bytes for AES-GCM IV
private const int TagLength = 16; // 16 bytes for AES-GCM Tag
- public static bool TryEncryptData(byte[] data, string base64Key, out byte[]? result, out string? errorMessage) {
+ public static bool TryEncryptData(
+ byte[] data,
+ string base64Key,
+ [NotNullWhen(true)] out byte[]? result,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var key = Convert.FromBase64String(base64Key);
using (AesGcm aesGcm = new AesGcm(key, AesGcm.TagByteSizes.MaxSize)) {
@@ -38,7 +45,12 @@ public static class AESGCMUtility {
}
}
- public static bool TryDecryptData(byte[] data, string base64Key, out byte[]? decryptedData, out string? errorMessage) {
+ public static bool TryDecryptData(
+ byte[] data,
+ string base64Key,
+ [NotNullWhen(true)] out byte[]? decryptedData,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var key = Convert.FromBase64String(base64Key);
diff --git a/src/MaksIT.Core/Security/Base32Encoder.cs b/src/MaksIT.Core/Security/Base32Encoder.cs
index 3356d2f..26e5036 100644
--- a/src/MaksIT.Core/Security/Base32Encoder.cs
+++ b/src/MaksIT.Core/Security/Base32Encoder.cs
@@ -1,7 +1,6 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using System.Text;
+using System.Diagnostics.CodeAnalysis;
+
namespace MaksIT.Core.Security;
@@ -9,7 +8,11 @@ public static class Base32Encoder {
private static readonly char[] Base32Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".ToCharArray();
private const string PaddingChar = "=";
- public static bool TryEncode(byte[] data, out string? encoded, out string? errorMessage) {
+ public static bool TryEncode(
+ byte[] data,
+ [NotNullWhen(true)] out string? encoded,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
if (data == null || data.Length == 0) {
throw new ArgumentNullException(nameof(data));
@@ -57,7 +60,11 @@ public static class Base32Encoder {
}
}
- public static bool TryDecode(string base32, out byte[]? decoded, out string? errorMessage) {
+ public static bool TryDecode(
+ string base32,
+ [NotNullWhen(true)] out byte[]? decoded,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
if (string.IsNullOrEmpty(base32)) {
throw new ArgumentNullException(nameof(base32));
diff --git a/src/MaksIT.Core/Security/ChecksumUtility.cs b/src/MaksIT.Core/Security/ChecksumUtility.cs
index af5c180..41b0818 100644
--- a/src/MaksIT.Core/Security/ChecksumUtility.cs
+++ b/src/MaksIT.Core/Security/ChecksumUtility.cs
@@ -1,7 +1,14 @@
-namespace MaksIT.Core.Security;
+using System.Diagnostics.CodeAnalysis;
+
+namespace MaksIT.Core.Security;
+
public static class ChecksumUtility {
- public static bool TryCalculateCRC32Checksum(byte[] data, out string? checksum, out string? errorMessage) {
+ public static bool TryCalculateCRC32Checksum(
+ byte[] data,
+ [NotNullWhen(true)] out string? checksum,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
if (Crc32.TryCompute(data, out var result, out errorMessage)) {
checksum = BitConverter.ToString(BitConverter.GetBytes(result)).Replace("-", "").ToLower();
return true;
@@ -26,7 +33,12 @@ public static class ChecksumUtility {
}
}
- public static bool TryCalculateCRC32ChecksumFromFileInChunks(string filePath, out string? checksum, out string? errorMessage, int chunkSize = 8192) {
+ public static bool TryCalculateCRC32ChecksumFromFileInChunks(
+ string filePath,
+ [NotNullWhen(true)] out string? checksum,
+ [NotNullWhen(false)] out string? errorMessage,
+ int chunkSize = 8192
+ ) {
try {
using var crc32 = new Crc32();
using var stream = File.OpenRead(filePath);
diff --git a/src/MaksIT.Core/Security/Crc32.cs b/src/MaksIT.Core/Security/Crc32.cs
index 9d959a3..9bceca9 100644
--- a/src/MaksIT.Core/Security/Crc32.cs
+++ b/src/MaksIT.Core/Security/Crc32.cs
@@ -1,4 +1,5 @@
-using System.Security.Cryptography;
+using System.Diagnostics.CodeAnalysis;
+using System.Security.Cryptography;
namespace MaksIT.Core.Security;
@@ -37,7 +38,11 @@ public class Crc32 : HashAlgorithm {
public override int HashSize => 32;
- public static bool TryCompute(byte[] buffer, out uint result, out string? errorMessage) {
+ public static bool TryCompute(
+ byte[] buffer,
+ out uint result,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
result = Compute(DefaultPolynomial, DefaultSeed, buffer);
errorMessage = null;
@@ -50,7 +55,12 @@ public class Crc32 : HashAlgorithm {
}
}
- public static bool TryCompute(uint seed, byte[] buffer, out uint result, out string? errorMessage) {
+ public static bool TryCompute(
+ uint seed,
+ byte[] buffer,
+ out uint result,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
result = Compute(DefaultPolynomial, seed, buffer);
errorMessage = null;
@@ -63,7 +73,13 @@ public class Crc32 : HashAlgorithm {
}
}
- public static bool TryCompute(uint polynomial, uint seed, byte[] buffer, out uint result, out string? errorMessage) {
+ public static bool TryCompute(
+ uint polynomial,
+ uint seed,
+ byte[] buffer,
+ out uint result,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
result = Compute(polynomial, seed, buffer);
errorMessage = null;
diff --git a/src/MaksIT.Core/Security/JwtGenerator.cs b/src/MaksIT.Core/Security/JwtGenerator.cs
index 1eba54b..e79a532 100644
--- a/src/MaksIT.Core/Security/JwtGenerator.cs
+++ b/src/MaksIT.Core/Security/JwtGenerator.cs
@@ -3,6 +3,7 @@ using System.Security.Claims;
using System.Security.Cryptography;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
+using System.Diagnostics.CodeAnalysis;
namespace MaksIT.Core.Security;
@@ -14,7 +15,16 @@ public class JWTTokenClaims {
}
public static class JwtGenerator {
- public static bool TryGenerateToken(string secret, string issuer, string audience, double expiration, string username, List roles, out (string, JWTTokenClaims)? tokenData, out string? errorMessage) {
+ public static bool TryGenerateToken(
+ string secret,
+ string issuer,
+ string audience,
+ double expiration,
+ string username,
+ List roles,
+ [NotNullWhen(true)] out (string, JWTTokenClaims)? tokenData,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var secretKey = GetSymmetricSecurityKey(secret);
var credentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
@@ -62,7 +72,14 @@ public static class JwtGenerator {
public static string GenerateSecret(int keySize = 32) => Convert.ToBase64String(GetRandomBytes(keySize));
- public static bool TryValidateToken(string secret, string issuer, string audience, string token, out JWTTokenClaims? tokenClaims, out string? errorMessage) {
+ public static bool TryValidateToken(
+ string secret,
+ string issuer,
+ string audience,
+ string token,
+ out JWTTokenClaims? tokenClaims,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var key = Encoding.UTF8.GetBytes(secret);
var tokenHandler = new JwtSecurityTokenHandler();
diff --git a/src/MaksIT.Core/Security/PasswordHasher.cs b/src/MaksIT.Core/Security/PasswordHasher.cs
index d714039..ae858c1 100644
--- a/src/MaksIT.Core/Security/PasswordHasher.cs
+++ b/src/MaksIT.Core/Security/PasswordHasher.cs
@@ -1,4 +1,5 @@
-using System.Security.Cryptography;
+using System.Diagnostics.CodeAnalysis;
+using System.Security.Cryptography;
using Microsoft.AspNetCore.Cryptography.KeyDerivation;
namespace MaksIT.Core.Security;
@@ -23,7 +24,11 @@ public static class PasswordHasher {
return Convert.ToBase64String(valueBytes);
}
- public static bool TryCreateSaltedHash(string value, out (string Salt, string Hash)? saltedHash, out string? errorMessage) {
+ public static bool TryCreateSaltedHash(
+ string value,
+ [NotNullWhen(true)] out (string Salt, string Hash)? saltedHash,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var saltBytes = CreateSaltBytes();
var hash = CreateHash(value, saltBytes);
@@ -40,7 +45,13 @@ public static class PasswordHasher {
}
}
- public static bool TryValidateHash(string value, string salt, string hash, out bool isValid, out string? errorMessage) {
+ public static bool TryValidateHash(
+ string value,
+ string salt,
+ string hash,
+ [NotNullWhen(true)] out bool isValid,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var saltBytes = Convert.FromBase64String(salt);
var hashToCompare = CreateHash(value, saltBytes);
diff --git a/src/MaksIT.Core/Security/TotpGenerator.cs b/src/MaksIT.Core/Security/TotpGenerator.cs
index f1690d4..be23f89 100644
--- a/src/MaksIT.Core/Security/TotpGenerator.cs
+++ b/src/MaksIT.Core/Security/TotpGenerator.cs
@@ -1,4 +1,5 @@
-using System.Security.Cryptography;
+using System.Diagnostics.CodeAnalysis;
+using System.Security.Cryptography;
namespace MaksIT.Core.Security;
@@ -6,7 +7,13 @@ public static class TotpGenerator {
private const int Timestep = 30; // Time step in seconds (standard is 30 seconds)
private const int TotpDigits = 6; // Standard TOTP length is 6 digits
- public static bool TryValidate(string totpCode, string base32Secret, int timeTolerance, out bool isValid, out string? errorMessage) {
+ public static bool TryValidate(
+ string totpCode,
+ string base32Secret,
+ int timeTolerance,
+ out bool isValid,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
// Convert the Base32 encoded secret to a byte array
if (!Base32Encoder.TryDecode(base32Secret, out byte[]? secretBytes, out errorMessage)) {
@@ -38,7 +45,12 @@ public static class TotpGenerator {
}
}
- public static bool TryGenerate(string base32Secret, long timestep, out string? totpCode, out string? errorMessage) {
+ public static bool TryGenerate(
+ string base32Secret,
+ long timestep,
+ [NotNullWhen(true)] out string? totpCode,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
// Convert the Base32 encoded secret to a byte array
if (!Base32Encoder.TryDecode(base32Secret, out byte[]? secretBytes, out errorMessage)) {
@@ -86,7 +98,10 @@ public static class TotpGenerator {
return unixTimestamp / Timestep;
}
- public static bool TryGenerateSecret(out string? secret, out string? errorMessage) {
+ public static bool TryGenerateSecret(
+ [NotNullWhen(true)] out string? secret,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
// Example of generating a 32-character base32 secret for TOTP
var random = new byte[20];
@@ -108,7 +123,11 @@ public static class TotpGenerator {
}
}
- public static bool TryGenerateRecoveryCodes(int defaultCodeCount, out List? recoveryCodes, out string? errorMessage) {
+ public static bool TryGenerateRecoveryCodes(
+ int defaultCodeCount,
+ [NotNullWhen(true)] out List? recoveryCodes,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
recoveryCodes = new List();
@@ -128,7 +147,17 @@ public static class TotpGenerator {
}
}
- public static bool TryGenerateTotpAuthLink(string label, string username, string twoFactoSharedKey, string issuer, string? algorithm, int? digits, int? period, out string? authLink, out string? errorMessage) {
+ public static bool TryGenerateTotpAuthLink(
+ string label,
+ string username,
+ string twoFactoSharedKey,
+ string issuer,
+ string? algorithm,
+ int? digits,
+ int? period,
+ [NotNullWhen(true)] out string? authLink,
+ [NotNullWhen(false)] out string? errorMessage
+ ) {
try {
var queryParams = new List {
$"secret={Uri.EscapeDataString(twoFactoSharedKey)}",