From 9a11bbca106f85943c4bdd27f75d962f092d83ed Mon Sep 17 00:00:00 2001 From: Maksym Sadovnychyy Date: Sat, 8 Jun 2024 22:56:51 +0200 Subject: [PATCH] (feature): allow to save contacts to cache on init, then set and retrieve them later --- .gitignore | 5 +- .../BackgroundServices/AutoRenewal.cs | 10 +- .../Controllers/CacheController.cs | 43 + .../Controllers/CertsFlowController.cs | 2 +- .../Services/CacheService.cs | 22 + .../Services/CertsFlowService.cs | 2 +- .../Cache/Requests/SetContactsRequest.cs | 15 + .../Requests/GetCerificatesRequest.cs | 7 + .../CertsFlow/Requests/GetOrderRequest.cs | 7 + .../CertsFlow/Requests/InitRequest.cs | 13 + .../CertsFlow/Requests/NewOrderRequest.cs | 9 + .../Requests/GetCerificatesRequest.cs | 5 - .../Requests/GetOrderRequest.cs | 5 - .../LetsEncryptServer/Requests/InitRequest.cs | 11 - .../Requests/NewOrderRequest.cs | 7 - src/Models/Models.csproj | 3 +- ...Encrypt Production.postman_collection.json | 1033 ++++++++-------- ...etsEncrypt Staging.postman_collection.json | 1035 +++++++++-------- src/{Agent => }/build_and_deploy.sh | 3 + src/docker-compose.override.yml | 3 + 20 files changed, 1249 insertions(+), 991 deletions(-) create mode 100644 src/LetsEncryptServer/Controllers/CacheController.cs create mode 100644 src/Models/LetsEncryptServer/Cache/Requests/SetContactsRequest.cs create mode 100644 src/Models/LetsEncryptServer/CertsFlow/Requests/GetCerificatesRequest.cs create mode 100644 src/Models/LetsEncryptServer/CertsFlow/Requests/GetOrderRequest.cs create mode 100644 src/Models/LetsEncryptServer/CertsFlow/Requests/InitRequest.cs create mode 100644 src/Models/LetsEncryptServer/CertsFlow/Requests/NewOrderRequest.cs delete mode 100644 src/Models/LetsEncryptServer/Requests/GetCerificatesRequest.cs delete mode 100644 src/Models/LetsEncryptServer/Requests/GetOrderRequest.cs delete mode 100644 src/Models/LetsEncryptServer/Requests/InitRequest.cs delete mode 100644 src/Models/LetsEncryptServer/Requests/NewOrderRequest.cs rename src/{Agent => }/build_and_deploy.sh (98%) diff --git a/.gitignore b/.gitignore index ca17f77..2ca12f3 100644 --- a/.gitignore +++ b/.gitignore @@ -259,4 +259,7 @@ paket-files/ # Python Tools for Visual Studio (PTVS) __pycache__/ -*.pyc \ No newline at end of file +*.pyc + + +**/*docker_compose \ No newline at end of file diff --git a/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs b/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs index 657fe6a..3035f81 100644 --- a/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs +++ b/src/LetsEncryptServer/BackgroundServices/AutoRenewal.cs @@ -1,8 +1,10 @@ -using DomainResults.Common; +using Microsoft.Extensions.Options; + +using DomainResults.Common; + + using MaksIT.LetsEncryptServer.Services; -using MaksIT.Models.LetsEncryptServer.Requests; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; +using Models.LetsEncryptServer.CertsFlow.Requests; namespace MaksIT.LetsEncryptServer.BackgroundServices { public class AutoRenewal : BackgroundService { diff --git a/src/LetsEncryptServer/Controllers/CacheController.cs b/src/LetsEncryptServer/Controllers/CacheController.cs new file mode 100644 index 0000000..8a424cd --- /dev/null +++ b/src/LetsEncryptServer/Controllers/CacheController.cs @@ -0,0 +1,43 @@ + + +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Options; + +using DomainResults.Mvc; + +using MaksIT.LetsEncryptServer.Services; +using MaksIT.Models.LetsEncryptServer.Cache.Requests; + +namespace MaksIT.LetsEncryptServer.Controllers; + +[ApiController] +[Route("[controller]")] +public class CacheController { + + private readonly Configuration _appSettings; + private readonly ICacheService _cacheService; + + public CacheController( + IOptions appSettings, + ICacheService cacheService + + ) { + _appSettings = appSettings.Value; + _cacheService = cacheService; + } + + + [HttpGet("[action]/{accountId}")] + public async Task GetContacts(Guid accountId) { + var result = await _cacheService.GetContactsAsync(accountId); + return result.ToActionResult(); + } + + + [HttpPost("[action]/{accountId}")] + public async Task SetContacts(Guid accountId, [FromBody] SetContactsRequest requestData) { + var result = await _cacheService.SetContactsAsync(accountId, requestData); + return result.ToActionResult(); + } +} + diff --git a/src/LetsEncryptServer/Controllers/CertsFlowController.cs b/src/LetsEncryptServer/Controllers/CertsFlowController.cs index 7066997..1628762 100644 --- a/src/LetsEncryptServer/Controllers/CertsFlowController.cs +++ b/src/LetsEncryptServer/Controllers/CertsFlowController.cs @@ -4,7 +4,7 @@ using Microsoft.Extensions.Options; using DomainResults.Mvc; using MaksIT.LetsEncryptServer.Services; -using MaksIT.Models.LetsEncryptServer.Requests; +using Models.LetsEncryptServer.CertsFlow.Requests; namespace MaksIT.LetsEncryptServer.Controllers; diff --git a/src/LetsEncryptServer/Services/CacheService.cs b/src/LetsEncryptServer/Services/CacheService.cs index df1a3b1..2548f4a 100644 --- a/src/LetsEncryptServer/Services/CacheService.cs +++ b/src/LetsEncryptServer/Services/CacheService.cs @@ -3,6 +3,7 @@ using DomainResults.Common; using MaksIT.Core.Extensions; using MaksIT.LetsEncrypt.Entities; +using MaksIT.Models.LetsEncryptServer.Cache.Requests; namespace MaksIT.LetsEncryptServer.Services; @@ -11,6 +12,8 @@ public interface ICacheService { Task SaveToCacheAsync(Guid accountId, RegistrationCache cache); Task DeleteFromCacheAsync(Guid accountId); Task<(Guid[]?, IDomainResult)> ListCachedAccountsAsync(); + Task<(string[]?, IDomainResult)> GetContactsAsync(Guid accountId); + Task SetContactsAsync(Guid accountId, SetContactsRequest requestData); } public class CacheService : ICacheService, IDisposable { @@ -141,6 +144,25 @@ public class CacheService : ICacheService, IDisposable { } } + public async Task<(string[]?, IDomainResult)> GetContactsAsync(Guid accountId) { + var (cache, loadResult) = await LoadFromCacheAsync(accountId); + if (!loadResult.IsSuccess || cache == null) + return (null, loadResult); + + return IDomainResult.Success(cache.Contacts); + } + + + public async Task SetContactsAsync(Guid accountId, SetContactsRequest requestData) { + var (cache, loadResult) = await LoadFromCacheAsync(accountId); + if (!loadResult.IsSuccess || cache == null) + return loadResult; + + cache.Contacts = requestData.Contacts; + return await SaveToCacheAsync(accountId, cache); + } + + public void Dispose() { _cacheLock?.Dispose(); } diff --git a/src/LetsEncryptServer/Services/CertsFlowService.cs b/src/LetsEncryptServer/Services/CertsFlowService.cs index 09bc360..6f53d23 100644 --- a/src/LetsEncryptServer/Services/CertsFlowService.cs +++ b/src/LetsEncryptServer/Services/CertsFlowService.cs @@ -6,7 +6,7 @@ using DomainResults.Common; using MaksIT.LetsEncrypt.Entities; using MaksIT.LetsEncrypt.Services; -using MaksIT.Models.LetsEncryptServer.Requests; +using Models.LetsEncryptServer.CertsFlow.Requests; namespace MaksIT.LetsEncryptServer.Services; diff --git a/src/Models/LetsEncryptServer/Cache/Requests/SetContactsRequest.cs b/src/Models/LetsEncryptServer/Cache/Requests/SetContactsRequest.cs new file mode 100644 index 0000000..00dc7f5 --- /dev/null +++ b/src/Models/LetsEncryptServer/Cache/Requests/SetContactsRequest.cs @@ -0,0 +1,15 @@ +using System.ComponentModel.DataAnnotations; + + +namespace MaksIT.Models.LetsEncryptServer.Cache.Requests { + public class SetContactsRequest : IValidatableObject { + + public required string[] Contacts { get; set; } + + public IEnumerable Validate(ValidationContext validationContext) { + + if (Contacts == null || Contacts.Length == 0) + yield return new ValidationResult("Contacts is required", new[] { nameof(Contacts) }); + } + } +} diff --git a/src/Models/LetsEncryptServer/CertsFlow/Requests/GetCerificatesRequest.cs b/src/Models/LetsEncryptServer/CertsFlow/Requests/GetCerificatesRequest.cs new file mode 100644 index 0000000..60422b4 --- /dev/null +++ b/src/Models/LetsEncryptServer/CertsFlow/Requests/GetCerificatesRequest.cs @@ -0,0 +1,7 @@ +namespace Models.LetsEncryptServer.CertsFlow.Requests +{ + public class GetCertificatesRequest + { + public string[] Hostnames { get; set; } + } +} diff --git a/src/Models/LetsEncryptServer/CertsFlow/Requests/GetOrderRequest.cs b/src/Models/LetsEncryptServer/CertsFlow/Requests/GetOrderRequest.cs new file mode 100644 index 0000000..de6f0ce --- /dev/null +++ b/src/Models/LetsEncryptServer/CertsFlow/Requests/GetOrderRequest.cs @@ -0,0 +1,7 @@ +namespace Models.LetsEncryptServer.CertsFlow.Requests +{ + public class GetOrderRequest + { + public string[] Hostnames { get; set; } + } +} diff --git a/src/Models/LetsEncryptServer/CertsFlow/Requests/InitRequest.cs b/src/Models/LetsEncryptServer/CertsFlow/Requests/InitRequest.cs new file mode 100644 index 0000000..dbf3989 --- /dev/null +++ b/src/Models/LetsEncryptServer/CertsFlow/Requests/InitRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Models.LetsEncryptServer.CertsFlow.Requests +{ + public class InitRequest + { + public string[] Contacts { get; set; } + } +} diff --git a/src/Models/LetsEncryptServer/CertsFlow/Requests/NewOrderRequest.cs b/src/Models/LetsEncryptServer/CertsFlow/Requests/NewOrderRequest.cs new file mode 100644 index 0000000..e787b9f --- /dev/null +++ b/src/Models/LetsEncryptServer/CertsFlow/Requests/NewOrderRequest.cs @@ -0,0 +1,9 @@ +namespace Models.LetsEncryptServer.CertsFlow.Requests +{ + public class NewOrderRequest + { + public string[] Hostnames { get; set; } + + public string ChallengeType { get; set; } + } +} diff --git a/src/Models/LetsEncryptServer/Requests/GetCerificatesRequest.cs b/src/Models/LetsEncryptServer/Requests/GetCerificatesRequest.cs deleted file mode 100644 index cddb599..0000000 --- a/src/Models/LetsEncryptServer/Requests/GetCerificatesRequest.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MaksIT.Models.LetsEncryptServer.Requests { - public class GetCertificatesRequest { - public string[] Hostnames { get; set; } - } -} diff --git a/src/Models/LetsEncryptServer/Requests/GetOrderRequest.cs b/src/Models/LetsEncryptServer/Requests/GetOrderRequest.cs deleted file mode 100644 index 8cde81e..0000000 --- a/src/Models/LetsEncryptServer/Requests/GetOrderRequest.cs +++ /dev/null @@ -1,5 +0,0 @@ -namespace MaksIT.Models.LetsEncryptServer.Requests { - public class GetOrderRequest { - public string[] Hostnames { get; set; } - } -} diff --git a/src/Models/LetsEncryptServer/Requests/InitRequest.cs b/src/Models/LetsEncryptServer/Requests/InitRequest.cs deleted file mode 100644 index 0ae1e9e..0000000 --- a/src/Models/LetsEncryptServer/Requests/InitRequest.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MaksIT.Models.LetsEncryptServer.Requests { - public class InitRequest { - public string[] Contacts { get; set; } - } -} diff --git a/src/Models/LetsEncryptServer/Requests/NewOrderRequest.cs b/src/Models/LetsEncryptServer/Requests/NewOrderRequest.cs deleted file mode 100644 index f1f8820..0000000 --- a/src/Models/LetsEncryptServer/Requests/NewOrderRequest.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace MaksIT.Models.LetsEncryptServer.Requests { - public class NewOrderRequest { - public string[] Hostnames { get; set; } - - public string ChallengeType { get; set; } - } -} diff --git a/src/Models/Models.csproj b/src/Models/Models.csproj index a5e4d8f..4cfcf65 100644 --- a/src/Models/Models.csproj +++ b/src/Models/Models.csproj @@ -8,7 +8,8 @@ - + + diff --git a/src/Postman/LetsEncrypt Production.postman_collection.json b/src/Postman/LetsEncrypt Production.postman_collection.json index d88c4cf..b3cdc71 100644 --- a/src/Postman/LetsEncrypt Production.postman_collection.json +++ b/src/Postman/LetsEncrypt Production.postman_collection.json @@ -7,505 +7,584 @@ }, "item": [ { - "name": "letsencrypt production", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://acme-v02.api.letsencrypt.org/directory", - "protocol": "https", - "host": [ - "acme-v02", - "api", - "letsencrypt", - "org" - ], - "path": [ - "directory" - ] - } - }, - "response": [] - }, - { - "name": "configure client", - "event": [ + "name": "Cache", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "// Ensure the response status code is 200 (OK)\r", - "if (pm.response.code === 200) {\r", - " // Get the plain text response\r", - " let responseBody = pm.response.text();\r", - " \r", - " // Remove the surrounding quotes if present\r", - " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", - " \r", - " // Check if the response body is a valid GUID\r", - " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", - " // Set the environment variable sessionId with the response\r", - " pm.environment.set(\"sessionId\", responseBody);\r", - " console.log(`sessionId set to: ${responseBody}`);\r", - " } else {\r", - " console.log(\"Response body is not a valid GUID\");\r", - " }\r", - "} else {\r", - " console.log(`Request failed with status code: ${pm.response.code}`);\r", - "}\r", - "" + "name": "get cache contacts", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" + "url": { + "raw": "http://localhost:8080/Cache/GetContacts/{{accountId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "Cache", + "GetContacts", + "{{accountId}}" + ] + } }, - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "http://localhost:8080/CertsFlow/ConfigureClient", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "ConfigureClient" - ] - } - }, - "response": [] - }, - { - "name": "terms of service", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8080/CertsFlow/TermsOfService/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "TermsOfService", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "init", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "// Ensure the response status code is 200 (OK)\r", - "if (pm.response.code === 200) {\r", - " // Get the plain text response\r", - " let responseBody = pm.response.text();\r", - " \r", - " // Remove the surrounding quotes if present\r", - " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", - " \r", - " // Check if the response body is a valid GUID\r", - " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", - " // Set the environment variable accountId with the response\r", - " pm.environment.set(\"accountId\", responseBody);\r", - " console.log(`accountId set to: ${responseBody}`);\r", - " } else {\r", - " console.log(\"Response body is not a valid GUID\");\r", - " }\r", - "} else {\r", - " console.log(`Request failed with status code: ${pm.response.code}`);\r", - "}\r", - "" - ], - "type": "text/javascript", - "packages": {} - } + "response": [] }, { - "listen": "prerequest", - "script": { - "exec": [ - "// Retrieve sessionId and accountId from environment variables or global variables\r", - "var sessionId = pm.environment.get(\"sessionId\") || pm.globals.get(\"sessionId\");\r", - "var accountId = pm.environment.get(\"accountId\") || pm.globals.get(\"accountId\");\r", - "\r", - "// Base URL without the optional accountId parameter\r", - "var baseUrl = `http://localhost:8080/CertsFlow/Init/${sessionId}`;\r", - "\r", - "// Append the accountId if it is provided\r", - "if (accountId) {\r", - " pm.request.url = `${baseUrl}/${accountId}`;\r", - "} else {\r", - " pm.request.url = baseUrl;\r", - "}" + "name": "set cache contacts", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"contacts\": [\r\n \"maksym.sadovnychyy@gmail.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "body": { + "mode": "raw", + "raw": "{\r\n \"contacts\": [\r\n \"maksym.sadovnychyy@gmail.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/Cache/SetContacts/{{accountId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "Cache", + "SetContacts", + "{{accountId}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://localhost:8080/CertsFlow/Init/{{sessionId}}/{{accountId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "Init", - "{{sessionId}}", - "{{accountId}}" - ] - } - }, - "response": [] - }, - { - "name": "new order", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "// Ensure the response status code is 200 (OK)\r", - "if (pm.response.code === 200) {\r", - " // Parse the JSON response\r", - " let responseBody;\r", - " try {\r", - " responseBody = pm.response.json();\r", - " } catch (e) {\r", - " console.error(\"Failed to parse JSON response:\", e);\r", - " return;\r", - " }\r", - "\r", - " // Check if the response is an array and has at least one element\r", - " if (Array.isArray(responseBody) && responseBody.length > 0) {\r", - " // Get the first element of the array\r", - " const firstElement = responseBody[0];\r", - " \r", - " // Set the environment variable challenge with the first element\r", - " pm.environment.set(\"challenge\", firstElement);\r", - " console.log(`challenge set to: ${firstElement}`);\r", - " } else {\r", - " console.log(\"Response body is not an array or is empty\");\r", - " }\r", - "} else {\r", - " console.log(`Request failed with status code: ${pm.response.code}`);\r", - "}\r", - "" + "name": "host with upcoming ssl expire", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "disabled": true + }, + { + "key": "Accept", + "value": "application/json", + "disabled": true + } ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ],\r\n \"challengeType\": \"http-01\"\r\n}", - "options": { - "raw": { - "language": "json" + "url": { + "raw": "http://localhost:8080/CertsFlow/HostsWithUpcomingSslExpiry/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "HostsWithUpcomingSslExpiry", + "{{sessionId}}" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/NewOrder/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "NewOrder", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "acme-challenge local", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8080/.well-known/acme-challenge/{{challenge}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - ".well-known", - "acme-challenge", - "{{challenge}}" - ] - } - }, - "response": [] - }, - { - "name": "acme-challenge", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://maks-it.com/.well-known/acme-challenge/{{challenge}}", - "protocol": "http", - "host": [ - "maks-it", - "com" - ], - "path": [ - ".well-known", - "acme-challenge", - "{{challenge}}" - ] - } - }, - "response": [] - }, - { - "name": "complete challenges", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "response": [] + } + ] + }, + { + "name": "Certs Manual Flow", + "item": [ + { + "name": "letsencrypt production", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://acme-v02.api.letsencrypt.org/directory", + "protocol": "https", + "host": [ + "acme-v02", + "api", + "letsencrypt", + "org" + ], + "path": [ + "directory" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/CompleteChallenges/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "CompleteChallenges", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "get order", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "response": [] + }, + { + "name": "configure client", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Ensure the response status code is 200 (OK)\r", + "if (pm.response.code === 200) {\r", + " // Get the plain text response\r", + " let responseBody = pm.response.text();\r", + " \r", + " // Remove the surrounding quotes if present\r", + " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", + " \r", + " // Check if the response body is a valid GUID\r", + " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", + " // Set the environment variable sessionId with the response\r", + " pm.environment.set(\"sessionId\", responseBody);\r", + " console.log(`sessionId set to: ${responseBody}`);\r", + " } else {\r", + " console.log(\"Response body is not a valid GUID\");\r", + " }\r", + "} else {\r", + " console.log(`Request failed with status code: ${pm.response.code}`);\r", + "}\r", + "" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/GetOrder/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" ], - "port": "8080", - "path": [ - "CertsFlow", - "GetOrder", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "get certificates", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "http://localhost:8080/CertsFlow/ConfigureClient", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "ConfigureClient" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/GetCertificates/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "GetCertificates", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "apply certificates", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "response": [] + }, + { + "name": "terms of service", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/CertsFlow/TermsOfService/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "TermsOfService", + "{{sessionId}}" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/ApplyCertificates/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "ApplyCertificates", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "host with upcoming ssl expire", - "request": { - "method": "GET", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "disabled": true }, - { - "key": "Accept", - "value": "application/json", - "disabled": true - } - ], - "url": { - "raw": "http://localhost:8080/CertsFlow/HostsWithUpcomingSslExpiry/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" + "response": [] + }, + { + "name": "init", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Ensure the response status code is 200 (OK)\r", + "if (pm.response.code === 200) {\r", + " // Get the plain text response\r", + " let responseBody = pm.response.text();\r", + " \r", + " // Remove the surrounding quotes if present\r", + " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", + " \r", + " // Check if the response body is a valid GUID\r", + " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", + " // Set the environment variable accountId with the response\r", + " pm.environment.set(\"accountId\", responseBody);\r", + " console.log(`accountId set to: ${responseBody}`);\r", + " } else {\r", + " console.log(\"Response body is not a valid GUID\");\r", + " }\r", + "} else {\r", + " console.log(`Request failed with status code: ${pm.response.code}`);\r", + "}\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "// Retrieve sessionId and accountId from environment variables or global variables\r", + "var sessionId = pm.environment.get(\"sessionId\") || pm.globals.get(\"sessionId\");\r", + "var accountId = pm.environment.get(\"accountId\") || pm.globals.get(\"accountId\");\r", + "\r", + "// Base URL without the optional accountId parameter\r", + "var baseUrl = `http://localhost:8080/CertsFlow/Init/${sessionId}`;\r", + "\r", + "// Append the accountId if it is provided\r", + "if (accountId) {\r", + " pm.request.url = `${baseUrl}/${accountId}`;\r", + "} else {\r", + " pm.request.url = baseUrl;\r", + "}" + ], + "type": "text/javascript", + "packages": {} + } + } ], - "port": "8080", - "path": [ - "CertsFlow", - "HostsWithUpcomingSslExpiry", - "{{sessionId}}" - ] + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"contacts\": [\r\n \"maksym.sadovnychyy@gmail.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/Init/{{sessionId}}/{{accountId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "Init", + "{{sessionId}}", + "{{accountId}}" + ] + } + }, + "response": [] + }, + { + "name": "new order", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Ensure the response status code is 200 (OK)\r", + "if (pm.response.code === 200) {\r", + " // Parse the JSON response\r", + " let responseBody;\r", + " try {\r", + " responseBody = pm.response.json();\r", + " } catch (e) {\r", + " console.error(\"Failed to parse JSON response:\", e);\r", + " return;\r", + " }\r", + "\r", + " // Check if the response is an array and has at least one element\r", + " if (Array.isArray(responseBody) && responseBody.length > 0) {\r", + " // Get the first element of the array\r", + " const firstElement = responseBody[0];\r", + " \r", + " // Set the environment variable challenge with the first element\r", + " pm.environment.set(\"challenge\", firstElement);\r", + " console.log(`challenge set to: ${firstElement}`);\r", + " } else {\r", + " console.log(\"Response body is not an array or is empty\");\r", + " }\r", + "} else {\r", + " console.log(`Request failed with status code: ${pm.response.code}`);\r", + "}\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ],\r\n \"challengeType\": \"http-01\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/NewOrder/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "NewOrder", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "acme-challenge local", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/.well-known/acme-challenge/{{challenge}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + ".well-known", + "acme-challenge", + "{{challenge}}" + ] + } + }, + "response": [] + }, + { + "name": "acme-challenge", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://maks-it.com/.well-known/acme-challenge/{{challenge}}", + "protocol": "http", + "host": [ + "maks-it", + "com" + ], + "path": [ + ".well-known", + "acme-challenge", + "{{challenge}}" + ] + } + }, + "response": [] + }, + { + "name": "complete challenges", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/CompleteChallenges/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "CompleteChallenges", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "get order", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/GetOrder/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "GetOrder", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "get certificates", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/GetCertificates/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "GetCertificates", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "apply certificates", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"maks-it.com\",\r\n \"auth.maks-it.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/ApplyCertificates/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "ApplyCertificates", + "{{sessionId}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] } ] } \ No newline at end of file diff --git a/src/Postman/LetsEncrypt Staging.postman_collection.json b/src/Postman/LetsEncrypt Staging.postman_collection.json index d3eb036..c0f583e 100644 --- a/src/Postman/LetsEncrypt Staging.postman_collection.json +++ b/src/Postman/LetsEncrypt Staging.postman_collection.json @@ -7,507 +7,586 @@ }, "item": [ { - "name": "letsencrypt staging", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "https://acme-staging-v02.api.letsencrypt.org/directory", - "protocol": "https", - "host": [ - "acme-staging-v02", - "api", - "letsencrypt", - "org" - ], - "path": [ - "directory" - ] - }, - "description": "[https://letsencrypt.status.io/](https://letsencrypt.status.io/)" - }, - "response": [] - }, - { - "name": "configure client", - "event": [ + "name": "Cache", + "item": [ { - "listen": "test", - "script": { - "exec": [ - "// Ensure the response status code is 200 (OK)\r", - "if (pm.response.code === 200) {\r", - " // Get the plain text response\r", - " let responseBody = pm.response.text();\r", - " \r", - " // Remove the surrounding quotes if present\r", - " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", - " \r", - " // Check if the response body is a valid GUID\r", - " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", - " // Set the environment variable sessionId with the response\r", - " pm.environment.set(\"sessionId\", responseBody);\r", - " console.log(`sessionId set to: ${responseBody}`);\r", - " } else {\r", - " console.log(\"Response body is not a valid GUID\");\r", - " }\r", - "} else {\r", - " console.log(`Request failed with status code: ${pm.response.code}`);\r", - "}\r", - "" + "name": "get cache contacts", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" + "url": { + "raw": "http://localhost:8080/Cache/GetContacts/{{accountId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "Cache", + "GetContacts", + "{{accountId}}" + ] + } }, - { - "key": "Accept", - "value": "application/json" - } - ], - "url": { - "raw": "http://localhost:8080/CertsFlow/ConfigureClient", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "ConfigureClient" - ] - } - }, - "response": [] - }, - { - "name": "terms of service", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8080/CertsFlow/TermsOfService/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "TermsOfService", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "init", - "event": [ - { - "listen": "test", - "script": { - "exec": [ - "// Ensure the response status code is 200 (OK)\r", - "if (pm.response.code === 200) {\r", - " // Get the plain text response\r", - " let responseBody = pm.response.text();\r", - " \r", - " // Remove the surrounding quotes if present\r", - " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", - " \r", - " // Check if the response body is a valid GUID\r", - " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", - " // Set the environment variable accountId with the response\r", - " pm.environment.set(\"accountId\", responseBody);\r", - " console.log(`accountId set to: ${responseBody}`);\r", - " } else {\r", - " console.log(\"Response body is not a valid GUID\");\r", - " }\r", - "} else {\r", - " console.log(`Request failed with status code: ${pm.response.code}`);\r", - "}\r", - "" - ], - "type": "text/javascript", - "packages": {} - } + "response": [] }, { - "listen": "prerequest", - "script": { - "exec": [ - "// Retrieve sessionId and accountId from environment variables or global variables\r", - "var sessionId = pm.environment.get(\"sessionId\") || pm.globals.get(\"sessionId\");\r", - "var accountId = pm.environment.get(\"accountId\") || pm.globals.get(\"accountId\");\r", - "\r", - "// Base URL without the optional accountId parameter\r", - "var baseUrl = `http://localhost:8080/CertsFlow/Init/${sessionId}`;\r", - "\r", - "// Append the accountId if it is provided\r", - "if (accountId) {\r", - " pm.request.url = `${baseUrl}/${accountId}`;\r", - "} else {\r", - " pm.request.url = baseUrl;\r", - "}" + "name": "set cache contacts", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"contacts\": [\r\n \"maksym.sadovnychyy@gmail.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "body": { + "mode": "raw", + "raw": "{\r\n \"contacts\": [\r\n \"maksym.sadovnychyy@gmail.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/Cache/SetContacts/{{accountId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "Cache", + "SetContacts", + "{{accountId}}" + ] } - } + }, + "response": [] }, - "url": { - "raw": "http://localhost:8080/CertsFlow/Init/{{sessionId}}/{{accountId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "Init", - "{{sessionId}}", - "{{accountId}}" - ] - } - }, - "response": [] - }, - { - "name": "new order", - "event": [ { - "listen": "test", - "script": { - "exec": [ - "// Ensure the response status code is 200 (OK)\r", - "if (pm.response.code === 200) {\r", - " // Parse the JSON response\r", - " let responseBody;\r", - " try {\r", - " responseBody = pm.response.json();\r", - " } catch (e) {\r", - " console.error(\"Failed to parse JSON response:\", e);\r", - " return;\r", - " }\r", - "\r", - " // Check if the response is an array and has at least one element\r", - " if (Array.isArray(responseBody) && responseBody.length > 0) {\r", - " // Get the first element of the array\r", - " const firstElement = responseBody[0];\r", - " \r", - " // Set the environment variable challenge with the first element\r", - " pm.environment.set(\"challenge\", firstElement);\r", - " console.log(`challenge set to: ${firstElement}`);\r", - " } else {\r", - " console.log(\"Response body is not an array or is empty\");\r", - " }\r", - "} else {\r", - " console.log(`Request failed with status code: ${pm.response.code}`);\r", - "}\r", - "" + "name": "host with upcoming ssl expire Copy", + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "disabled": true + }, + { + "key": "Accept", + "value": "application/json", + "disabled": true + } ], - "type": "text/javascript", - "packages": {} - } - } - ], - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ],\r\n \"challengeType\": \"http-01\"\r\n}", - "options": { - "raw": { - "language": "json" + "url": { + "raw": "http://localhost:8080/CertsFlow/HostsWithUpcomingSslExpiry/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "HostsWithUpcomingSslExpiry", + "{{sessionId}}" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/NewOrder/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "NewOrder", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "acme-challenge local", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://localhost:8080/.well-known/acme-challenge/{{challenge}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - ".well-known", - "acme-challenge", - "{{challenge}}" - ] - } - }, - "response": [] - }, - { - "name": "acme-challenge", - "request": { - "method": "GET", - "header": [], - "url": { - "raw": "http://staging.maks-it.com/.well-known/acme-challenge/{{challenge}}", - "protocol": "http", - "host": [ - "staging", - "maks-it", - "com" - ], - "path": [ - ".well-known", - "acme-challenge", - "{{challenge}}" - ] - } - }, - "response": [] - }, - { - "name": "complete challenges", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "", - "options": { - "raw": { - "language": "json" + "response": [] + } + ] + }, + { + "name": "Certs Manual Flow", + "item": [ + { + "name": "letsencrypt staging", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "https://acme-staging-v02.api.letsencrypt.org/directory", + "protocol": "https", + "host": [ + "acme-staging-v02", + "api", + "letsencrypt", + "org" + ], + "path": [ + "directory" + ] + }, + "description": "[https://letsencrypt.status.io/](https://letsencrypt.status.io/)" + }, + "response": [] + }, + { + "name": "configure client", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Ensure the response status code is 200 (OK)\r", + "if (pm.response.code === 200) {\r", + " // Get the plain text response\r", + " let responseBody = pm.response.text();\r", + " \r", + " // Remove the surrounding quotes if present\r", + " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", + " \r", + " // Check if the response body is a valid GUID\r", + " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", + " // Set the environment variable sessionId with the response\r", + " pm.environment.set(\"sessionId\", responseBody);\r", + " console.log(`sessionId set to: ${responseBody}`);\r", + " } else {\r", + " console.log(\"Response body is not a valid GUID\");\r", + " }\r", + "} else {\r", + " console.log(`Request failed with status code: ${pm.response.code}`);\r", + "}\r", + "" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/CompleteChallenges/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" ], - "port": "8080", - "path": [ - "CertsFlow", - "CompleteChallenges", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "get order", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" - }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "http://localhost:8080/CertsFlow/ConfigureClient", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "ConfigureClient" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/GetOrder/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "GetOrder", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "get certificates", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "response": [] + }, + { + "name": "terms of service", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/CertsFlow/TermsOfService/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "TermsOfService", + "{{sessionId}}" + ] } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/GetCertificates/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" - ], - "port": "8080", - "path": [ - "CertsFlow", - "GetCertificates", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "apply certificates", - "request": { - "method": "POST", - "header": [ - { - "key": "Content-Type", - "value": "application/json" }, - { - "key": "Accept", - "value": "application/json" - } - ], - "body": { - "mode": "raw", - "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ]\r\n}", - "options": { - "raw": { - "language": "json" + "response": [] + }, + { + "name": "init", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Ensure the response status code is 200 (OK)\r", + "if (pm.response.code === 200) {\r", + " // Get the plain text response\r", + " let responseBody = pm.response.text();\r", + " \r", + " // Remove the surrounding quotes if present\r", + " responseBody = responseBody.replace(/^\"|\"$/g, '');\r", + " \r", + " // Check if the response body is a valid GUID\r", + " if (/^[0-9a-fA-F-]{36}$/.test(responseBody)) {\r", + " // Set the environment variable accountId with the response\r", + " pm.environment.set(\"accountId\", responseBody);\r", + " console.log(`accountId set to: ${responseBody}`);\r", + " } else {\r", + " console.log(\"Response body is not a valid GUID\");\r", + " }\r", + "} else {\r", + " console.log(`Request failed with status code: ${pm.response.code}`);\r", + "}\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "prerequest", + "script": { + "exec": [ + "// Retrieve sessionId and accountId from environment variables or global variables\r", + "var sessionId = pm.environment.get(\"sessionId\") || pm.globals.get(\"sessionId\");\r", + "var accountId = pm.environment.get(\"accountId\") || pm.globals.get(\"accountId\");\r", + "\r", + "// Base URL without the optional accountId parameter\r", + "var baseUrl = `http://localhost:8080/CertsFlow/Init/${sessionId}`;\r", + "\r", + "// Append the accountId if it is provided\r", + "if (accountId) {\r", + " pm.request.url = `${baseUrl}/${accountId}`;\r", + "} else {\r", + " pm.request.url = baseUrl;\r", + "}" + ], + "type": "text/javascript", + "packages": {} + } } - } - }, - "url": { - "raw": "http://localhost:8080/CertsFlow/ApplyCertificates/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" ], - "port": "8080", - "path": [ - "CertsFlow", - "ApplyCertificates", - "{{sessionId}}" - ] - } - }, - "response": [] - }, - { - "name": "host with upcoming ssl expire Copy", - "request": { - "method": "GET", - "header": [ - { - "key": "Content-Type", - "value": "application/json", - "disabled": true + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"contacts\": [\r\n \"maksym.sadovnychyy@gmail.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/Init/{{sessionId}}/{{accountId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "Init", + "{{sessionId}}", + "{{accountId}}" + ] + } }, - { - "key": "Accept", - "value": "application/json", - "disabled": true - } - ], - "url": { - "raw": "http://localhost:8080/CertsFlow/HostsWithUpcomingSslExpiry/{{sessionId}}", - "protocol": "http", - "host": [ - "localhost" + "response": [] + }, + { + "name": "new order", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "// Ensure the response status code is 200 (OK)\r", + "if (pm.response.code === 200) {\r", + " // Parse the JSON response\r", + " let responseBody;\r", + " try {\r", + " responseBody = pm.response.json();\r", + " } catch (e) {\r", + " console.error(\"Failed to parse JSON response:\", e);\r", + " return;\r", + " }\r", + "\r", + " // Check if the response is an array and has at least one element\r", + " if (Array.isArray(responseBody) && responseBody.length > 0) {\r", + " // Get the first element of the array\r", + " const firstElement = responseBody[0];\r", + " \r", + " // Set the environment variable challenge with the first element\r", + " pm.environment.set(\"challenge\", firstElement);\r", + " console.log(`challenge set to: ${firstElement}`);\r", + " } else {\r", + " console.log(\"Response body is not an array or is empty\");\r", + " }\r", + "} else {\r", + " console.log(`Request failed with status code: ${pm.response.code}`);\r", + "}\r", + "" + ], + "type": "text/javascript", + "packages": {} + } + } ], - "port": "8080", - "path": [ - "CertsFlow", - "HostsWithUpcomingSslExpiry", - "{{sessionId}}" - ] + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ],\r\n \"challengeType\": \"http-01\"\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/NewOrder/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "NewOrder", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "acme-challenge local", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://localhost:8080/.well-known/acme-challenge/{{challenge}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + ".well-known", + "acme-challenge", + "{{challenge}}" + ] + } + }, + "response": [] + }, + { + "name": "acme-challenge", + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "http://staging.maks-it.com/.well-known/acme-challenge/{{challenge}}", + "protocol": "http", + "host": [ + "staging", + "maks-it", + "com" + ], + "path": [ + ".well-known", + "acme-challenge", + "{{challenge}}" + ] + } + }, + "response": [] + }, + { + "name": "complete challenges", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/CompleteChallenges/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "CompleteChallenges", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "get order", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/GetOrder/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "GetOrder", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "get certificates", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/GetCertificates/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "GetCertificates", + "{{sessionId}}" + ] + } + }, + "response": [] + }, + { + "name": "apply certificates", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\r\n \"hostnames\": [\r\n \"staging.maks-it.com\"\r\n ]\r\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "http://localhost:8080/CertsFlow/ApplyCertificates/{{sessionId}}", + "protocol": "http", + "host": [ + "localhost" + ], + "port": "8080", + "path": [ + "CertsFlow", + "ApplyCertificates", + "{{sessionId}}" + ] + } + }, + "response": [] } - }, - "response": [] + ] } ] } \ No newline at end of file diff --git a/src/Agent/build_and_deploy.sh b/src/build_and_deploy.sh similarity index 98% rename from src/Agent/build_and_deploy.sh rename to src/build_and_deploy.sh index 39d9d4e..9c85956 100644 --- a/src/Agent/build_and_deploy.sh +++ b/src/build_and_deploy.sh @@ -33,7 +33,10 @@ if [[ "$1" != "$NO_NEW_KEY_FLAG" ]]; then jq --arg newApiKey "$NEW_API_KEY" '.Configuration.ApiKey = $newApiKey' $APPSETTINGS_FILE > tmp.$$.json && mv tmp.$$.json $APPSETTINGS_FILE fi +cd + # Build and publish the .NET application +cd "$(dirname "$(realpath "$0")")/Agent" sudo dotnet build --configuration Release sudo dotnet publish -c Release -o $INSTALL_DIR diff --git a/src/docker-compose.override.yml b/src/docker-compose.override.yml index 11d3452..1b94e4e 100644 --- a/src/docker-compose.override.yml +++ b/src/docker-compose.override.yml @@ -5,5 +5,8 @@ services: environment: - ASPNETCORE_ENVIRONMENT=Development - ASPNETCORE_HTTP_PORTS=8080 + volumes: + - ./docker_compose/LetsEncryptServer/acme:/app/bin/Debug/net8.0/acme + - ./docker_compose/LetsEncryptServer/cache:/app/bin/Debug/net8.0/cache ports: - "8080:8080"