diff --git a/README.md b/README.md index 6f5af65..b398788 100644 --- a/README.md +++ b/README.md @@ -5,54 +5,67 @@ [![Build](https://github.com/barzin144/Zus/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/barzin144/Zus/actions/workflows/ci.yml) [![Test](https://github.com/barzin144/Zus/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/barzin144/Zus/actions/workflows/test.yml) -# Table of Contents +# Table of Contents + - [Installation](#installation) - [Send Request](#send-request) - - [Send Get Request](#get) - - [Send Post Request](#post) - - [Send A Request With Pre-Request](#pre-request) - - [Resend A Request](#resend) + - [Send Get Request](#get) + - [Send Post Request](#post) + - [Send A Request With Pre-Request](#pre-request) + - [Resend A Request](#resend) - [Variable](#variable) - [Request](#request) - [Base64 Decoder/Encoder](#base64) - [Sha256 Hash](#sha256) - [Guid](#guid) +- [Epoch Time Converter](#epoch-time-converter) - [JWT Decoder](#jwt-decoder) + ## Installation + ```Shell dotnet tool install --global zus ``` + ## Send Request + #### Get + ```Shell zus send get https://example.com/posts/1 ``` -| Options | Description | example | -| ------------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------- | -| -a, --auth | Authentication Bearer Token | zus send get https://example.com/posts/1 -a eyJhbGciOi== | -| -n, --name | Name for saving the request | zus send get https://example.com/posts/1 -n posts | -| -s, --save-response| Save response | zus send get https://example.com/posts/1 -s | -| -h, --header | Add header to request, format: Key:Value,Key:Value and wrap your data in single or double quote. | zus send get https://example.com/posts/1 -h 'api-key:abc' | -| -p, --pre-request | Pre-request name | zus send get https://example.com/posts/1 -p login | -| -f, --force | Overwrite the existing request with same name | zus send get https://example.com/posts/1 -n posts -f | + +| Options | Description | example | +| ------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------- | +| -a, --auth | Authentication Bearer Token | zus send get https://example.com/posts/1 -a eyJhbGciOi== | +| -n, --name | Name for saving the request | zus send get https://example.com/posts/1 -n posts | +| -s, --save-response | Save response | zus send get https://example.com/posts/1 -s | +| -h, --header | Add header to request, format: Key:Value,Key:Value and wrap your data in single or double quote. | zus send get https://example.com/posts/1 -h 'api-key:abc' | +| -p, --pre-request | Pre-request name | zus send get https://example.com/posts/1 -p login | +| -f, --force | Overwrite the existing request with same name | zus send get https://example.com/posts/1 -n posts -f | + #### Post + ```Shell zus send post http://example/api/Account/Login -x -d "username:zus,password:123456" //form-urlencoded format zus send post http://example/api/Account/Login -j -d "username:zus,password:123456" //json format zus send post http://example/api/Account/Login -d '{"username": "zus", "password": "123456"}' //string format ``` -| Options | Description | -| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| -d, --data | Data format: `Key:Value,Key:Value` and wrap your data in single or double quote. Data will be sent in string format by default. By adding -x flag change format to form-urlencoded or -j for Json format | -| -a, --auth | Authentication Bearer Token | -| -n, --name | Name for saving the request | -| -s, --save-response| Save response | -| -h, --header | Add header to request, format: Key:Value,Key:Value and wrap your data in single quote or double quote. | -| -x, --form-format | Convert Key:Value data to form-urlencoded format | -| -j, --json-format | Convert Key:Value data to json format | -| -p, --pre-request | Pre-request name | -| -f, --force | Overwrite the existing request with same name | + +| Options | Description | +| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| -d, --data | Data format: `Key:Value,Key:Value` and wrap your data in single or double quote. Data will be sent in string format by default. By adding -x flag change format to form-urlencoded or -j for Json format | +| -a, --auth | Authentication Bearer Token | +| -n, --name | Name for saving the request | +| -s, --save-response | Save response | +| -h, --header | Add header to request, format: Key:Value,Key:Value and wrap your data in single quote or double quote. | +| -x, --form-format | Convert Key:Value data to form-urlencoded format | +| -j, --json-format | Convert Key:Value data to json format | +| -p, --pre-request | Pre-request name | +| -f, --force | Overwrite the existing request with same name | + #### Pre-Request + ```Shell zus send post http://example/api/Account/Login -n login -d "username:zus,password:123456" //response: { "accessToken": "eyJhbGciOiJI..." } @@ -71,65 +84,107 @@ zus send post http://example/api/Account/UpdateProfile -p get-token -a "{pr.$}" zus send post http://example/api/Account/UpdateProfile -p get-token -d "name:{var.name}" ``` -> *{pr.KEY_OF_RESPONSE_OBJECT}* will be replaced with Pre-request response data.(If Pre-request response data is Json) -> *{pr.$}* will be replaced with Pre-request response data.(If Pre-request response data is String) +> _{pr.KEY_OF_RESPONSE_OBJECT}_ will be replaced with Pre-request response data.(If Pre-request response data is Json) + +> _{pr.$}_ will be replaced with Pre-request response data.(If Pre-request response data is String) + +> _{var.VARIABLE_NAME}_ will be replaced with value of saved variable. -> *{var.VARIABLE_NAME}* will be replaced with value of saved variable. #### Resend -> Send a saved request. + +> Send a saved request. + ```Shell zus resend login ``` + ## Variable -> Manage variables. + +> Manage variables. + #### List + ```Shell zus var list ``` + #### Delete + ```Shell zus var delete SAVED_NAME ``` + ## Request -> Access to saved requests. + +> Access to saved requests. + #### List + ```Shell zus request list ``` + #### Delete + ```Shell zus request delete SAVED_NAME ``` + ## Base64 + #### Encode + ```Shell zus base64 my_text zus base64 -f FILE_PATH ``` + > output: bXlfdGV4dA== + #### Decode + ```Shell zus dbase64 bXlfdGV4dA== zus dbase64 -f bXlfdGV4dA== //store decoded data into txt file ``` + > output: my_text + ## SHA256 + ```Shell zus sha256 my_text ``` + > output: wK5CFkMfgStqjLvxe/h7zaqzNISGyy2xWP9dN893UEI= + ## GUID + ```Shell zus guid ``` -> output: c4a3bb74-bc13-4cfc-8487-8eefe7912c54 + +## Epoch Time Converter + +```Shell +zus dt 1734895248 +``` + +> output: UTC: Sunday, December 22, 2024 7:20:48 PM +00:00 + +> output: Local: Monday, December 23, 2024 3:20:48 AM +08:00 + ## JWT Decoder + ![image](https://raw.githubusercontent.com/barzin144/zus/main/.github/assets/zus-djwt.png) + #### With Secret + ```Shell zus djwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ilp1cyBDTEkgVG9vbCIsImlhdCI6MTUxNjIzOTAyMn0.9BmMva7XRwYtaNkvmobWNNQX8lHyGnSyVRuzgCjEcIY my_secret ``` + ```Json { "alg": "HS256", @@ -142,10 +197,13 @@ zus djwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZS } Signature Verified ``` + #### Without Secret + ```Shell zus djwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ilp1cyBDTEkgVG9vbCIsImlhdCI6MTUxNjIzOTAyMn0.9BmMva7XRwYtaNkvmobWNNQX8lHyGnSyVRuzgCjEcIY ``` + ```Json { "alg": "HS256", @@ -158,4 +216,3 @@ zus djwt eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZS } Invalid Signature ``` - diff --git a/Zus.Cli.Test/Commands/EpochTimeTests.cs b/Zus.Cli.Test/Commands/EpochTimeTests.cs new file mode 100644 index 0000000..2bd901d --- /dev/null +++ b/Zus.Cli.Test/Commands/EpochTimeTests.cs @@ -0,0 +1,51 @@ +using System; +using Zus.Cli.Commands; + +namespace Zus.Cli.Test.Commands; + +public class EpochTimeTests +{ + [Fact] + public void Convert_Should_ReturnUTCDateTime_ForValidEpochTime() + { + // Arrange + string epochTime = "1633072800"; + string expectedDateTime = "UTC: Friday, October 1, 2021 7:20:00 AM +00:00"; + + // Act + var result = EpochTime.Convert(epochTime, false); + + // Assert + Assert.NotNull(result.Result); + Assert.True(result.Success); + Assert.Equal(expectedDateTime, result.Result); + } + + [Fact] + public void Convert_Should_ReturnError_ForInvalidEpochTime() + { + // Arrange + string epochTime = "invalid"; + + // Act + var result = EpochTime.Convert(epochTime, false); + + // Assert + Assert.NotNull(result.Error); + Assert.False(result.Success); + } + + [Fact] + public void Convert_Should_ReturnError_ForEmptyEpochTime() + { + // Arrange + string epochTime = ""; + + // Act + var result = EpochTime.Convert(epochTime, false); + + // Assert + Assert.NotNull(result.Error); + Assert.False(result.Success); + } +} diff --git a/Zus.Cli/Commands/EpochTime.cs b/Zus.Cli/Commands/EpochTime.cs new file mode 100644 index 0000000..000fcb2 --- /dev/null +++ b/Zus.Cli/Commands/EpochTime.cs @@ -0,0 +1,32 @@ +using Zus.Cli.Models; + +namespace Zus.Cli.Commands; + +public static class EpochTime +{ + internal static CommandResult Convert(string epochTime, bool local) + { + try + { + var utcDateTime = DateTimeOffset.FromUnixTimeSeconds(long.Parse(epochTime)).UtcDateTime; + if (local) + { + TimeZoneInfo localTimeZone = TimeZoneInfo.Local; + DateTime localDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, localTimeZone); + return new CommandResult + { + Result = $"Local: {localDateTime:dddd, MMMM d, yyyy h:mm:ss tt zzz}" + }; + } + return new CommandResult + { + Result = $"UTC: {utcDateTime:dddd, MMMM d, yyyy h:mm:ss tt zzz}" + }; + + } + catch (Exception ex) + { + return new CommandResult { Error = ex.Message }; + } + } +} diff --git a/Zus.Cli/Program.cs b/Zus.Cli/Program.cs index ce0a45b..198ba0a 100644 --- a/Zus.Cli/Program.cs +++ b/Zus.Cli/Program.cs @@ -111,4 +111,11 @@ app.AddCommand("guid", () => Display.Result(UniqueID.Generate())) .WithDescription("Generate a Guid"); +app.AddCommand("dt", ([Argument] string epochTime) => +{ + Display.Result(EpochTime.Convert(epochTime, false)); + Display.Result(EpochTime.Convert(epochTime, true)); +}) + .WithDescription("Convert epoch time to date time."); + app.Run(); \ No newline at end of file