Compare commits
5 Commits
ea6d80918c
...
09df86000b
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
09df86000b | ||
|
|
406ddfb226 | ||
|
|
b01f13fb5f | ||
|
|
00fedc7c4c | ||
|
|
171de98552 |
@@ -21,6 +21,7 @@
|
|||||||
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
<PackageReference Include="DigitalData.EmailProfilerDispatcher" Version="3.0.0" />
|
||||||
<PackageReference Include="MediatR" Version="12.5.0" />
|
<PackageReference Include="MediatR" Version="12.5.0" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
|
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.18" />
|
||||||
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.1" />
|
||||||
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.4" />
|
||||||
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
<PackageReference Include="Otp.NET" Version="1.4.0" />
|
||||||
|
|||||||
@@ -23,6 +23,8 @@
|
|||||||
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
|
<PackageReference Include="DigitalData.Core.API" Version="2.1.1" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.4" />
|
||||||
|
<PackageReference Include="NLog" Version="5.2.5" />
|
||||||
|
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.0" />
|
||||||
<PackageReference Include="Scalar.AspNetCore" Version="2.2.1" />
|
<PackageReference Include="Scalar.AspNetCore" Version="2.2.1" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.1.1" />
|
||||||
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
|
<PackageReference Include="DigitalData.Core.Abstractions" Version="3.6.0" />
|
||||||
|
|||||||
@@ -16,19 +16,30 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using DigitalData.Core.Abstractions.Security.Extensions;
|
using DigitalData.Core.Abstractions.Security.Extensions;
|
||||||
using EnvelopeGenerator.GeneratorAPI.Middleware;
|
using EnvelopeGenerator.GeneratorAPI.Middleware;
|
||||||
|
using NLog.Web;
|
||||||
|
using NLog;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
|
||||||
|
logger.Info("Logging initialized!");
|
||||||
|
|
||||||
var config = builder.Configuration;
|
try
|
||||||
|
{
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
var deferredProvider = new DeferredServiceProvider();
|
builder.Logging.ClearProviders();
|
||||||
|
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||||
|
builder.Host.UseNLog();
|
||||||
|
|
||||||
builder.Services.AddControllers();
|
var config = builder.Configuration;
|
||||||
|
|
||||||
//CORS Policy
|
var deferredProvider = new DeferredServiceProvider();
|
||||||
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
|
|
||||||
throw new InvalidOperationException("AllowedOrigins section is missing in the configuration.");
|
builder.Services.AddControllers();
|
||||||
builder.Services.AddCors(options =>
|
|
||||||
|
//CORS Policy
|
||||||
|
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
|
||||||
|
throw new InvalidOperationException("AllowedOrigins section is missing in the configuration.");
|
||||||
|
builder.Services.AddCors(options =>
|
||||||
{
|
{
|
||||||
options.AddPolicy("AllowSpecificOriginsPolicy", builder =>
|
options.AddPolicy("AllowSpecificOriginsPolicy", builder =>
|
||||||
{
|
{
|
||||||
@@ -40,34 +51,34 @@ builder.Services.AddCors(options =>
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Swagger
|
// Swagger
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerGen(options =>
|
builder.Services.AddSwaggerGen(options =>
|
||||||
{
|
|
||||||
options.SwaggerDoc("v1", new OpenApiInfo
|
|
||||||
{
|
{
|
||||||
Version = "v1",
|
options.SwaggerDoc("v1", new OpenApiInfo
|
||||||
Title = "signFLOW Absender-API",
|
|
||||||
Description = "Eine API zur Verwaltung der Erstellung, des Versands und der Nachverfolgung von Umschlägen in der signFLOW-Anwendung.",
|
|
||||||
Contact = new OpenApiContact
|
|
||||||
{
|
{
|
||||||
Name = "Digital Data GmbH",
|
Version = "v1",
|
||||||
Url = new Uri("https://digitaldata.works/digitale-signatur#kontakt"),
|
Title = "signFLOW Absender-API",
|
||||||
Email = "info-flow@digitaldata.works"
|
Description = "Eine API zur Verwaltung der Erstellung, des Versands und der Nachverfolgung von Umschlägen in der signFLOW-Anwendung.",
|
||||||
},
|
Contact = new OpenApiContact
|
||||||
});
|
{
|
||||||
|
Name = "Digital Data GmbH",
|
||||||
|
Url = new Uri("https://digitaldata.works/digitale-signatur#kontakt"),
|
||||||
|
Email = "info-flow@digitaldata.works"
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Name = "Authorization",
|
Name = "Authorization",
|
||||||
Type = SecuritySchemeType.Http,
|
Type = SecuritySchemeType.Http,
|
||||||
Scheme = "bearer",
|
Scheme = "bearer",
|
||||||
BearerFormat = "JWT",
|
BearerFormat = "JWT",
|
||||||
In = ParameterLocation.Header,
|
In = ParameterLocation.Header,
|
||||||
Description = "JWT-Autorisierungs-Header unter Verwendung des Bearer-Schemas.",
|
Description = "JWT-Autorisierungs-Header unter Verwendung des Bearer-Schemas.",
|
||||||
});
|
});
|
||||||
|
|
||||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
options.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
new OpenApiSecurityScheme
|
new OpenApiSecurityScheme
|
||||||
@@ -82,130 +93,136 @@ builder.Services.AddSwaggerGen(options =>
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
|
var xmlFiles = Directory.GetFiles(AppContext.BaseDirectory, "*.xml");
|
||||||
foreach (var xmlFile in xmlFiles)
|
foreach (var xmlFile in xmlFiles)
|
||||||
{
|
|
||||||
options.IncludeXmlComments(xmlFile);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.Services.AddOpenApi();
|
|
||||||
// DbContext
|
|
||||||
var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
|
|
||||||
|
|
||||||
builder.Services.Configure<ConnectionString>(cs => cs.Value = connStr);
|
|
||||||
|
|
||||||
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
|
||||||
|
|
||||||
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
|
|
||||||
|
|
||||||
var authTokenKeys = config.GetOrDefault<AuthTokenKeys>();
|
|
||||||
|
|
||||||
builder.Services.AddAuthentication(options =>
|
|
||||||
{
|
|
||||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
|
||||||
})
|
|
||||||
.AddJwtBearer(opt =>
|
|
||||||
{
|
|
||||||
opt.TokenValidationParameters = new TokenValidationParameters
|
|
||||||
{
|
{
|
||||||
ValidateIssuerSigningKey = true,
|
options.IncludeXmlComments(xmlFile);
|
||||||
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
|
}
|
||||||
{
|
});
|
||||||
var clientParams = deferredProvider.GetOptions<ClientParams>();
|
builder.Services.AddOpenApi();
|
||||||
var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience);
|
// DbContext
|
||||||
return new List<SecurityKey>() { publicKey.SecurityKey };
|
var connStr = config.GetConnectionString("Default") ?? throw new InvalidOperationException("There is no default connection string in appsettings.json.");
|
||||||
},
|
|
||||||
ValidateIssuer = true,
|
|
||||||
ValidIssuer = authTokenKeys.Issuer,
|
|
||||||
ValidateAudience = true,
|
|
||||||
ValidAudience = authTokenKeys.Audience,
|
|
||||||
};
|
|
||||||
|
|
||||||
opt.Events = new JwtBearerEvents
|
builder.Services.Configure<ConnectionString>(cs => cs.Value = connStr);
|
||||||
|
|
||||||
|
builder.Services.AddDbContext<EGDbContext>(options => options.UseSqlServer(connStr));
|
||||||
|
|
||||||
|
builder.Services.AddAuthHubClient(config.GetSection("AuthClientParams"));
|
||||||
|
|
||||||
|
var authTokenKeys = config.GetOrDefault<AuthTokenKeys>();
|
||||||
|
|
||||||
|
builder.Services.AddAuthentication(options =>
|
||||||
|
{
|
||||||
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
|
})
|
||||||
|
.AddJwtBearer(opt =>
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
opt.TokenValidationParameters = new TokenValidationParameters
|
||||||
{
|
{
|
||||||
// if there is no token read related cookie or query string
|
ValidateIssuerSigningKey = true,
|
||||||
if (context.Token is null) // if there is no token
|
IssuerSigningKeyResolver = (token, securityToken, identifier, parameters) =>
|
||||||
{
|
{
|
||||||
if (context.Request.Cookies.TryGetValue(authTokenKeys.Cookie, out var cookieToken) && cookieToken is not null)
|
var clientParams = deferredProvider.GetOptions<ClientParams>();
|
||||||
context.Token = cookieToken;
|
var publicKey = clientParams!.PublicKeys.Get(authTokenKeys.Issuer, authTokenKeys.Audience);
|
||||||
else if (context.Request.Query.TryGetValue(authTokenKeys.QueryString, out var queryStrToken))
|
return new List<SecurityKey>() { publicKey.SecurityKey };
|
||||||
context.Token = queryStrToken;
|
},
|
||||||
|
ValidateIssuer = true,
|
||||||
|
ValidIssuer = authTokenKeys.Issuer,
|
||||||
|
ValidateAudience = true,
|
||||||
|
ValidAudience = authTokenKeys.Audience,
|
||||||
|
};
|
||||||
|
|
||||||
|
opt.Events = new JwtBearerEvents
|
||||||
|
{
|
||||||
|
OnMessageReceived = context =>
|
||||||
|
{
|
||||||
|
// if there is no token read related cookie or query string
|
||||||
|
if (context.Token is null) // if there is no token
|
||||||
|
{
|
||||||
|
if (context.Request.Cookies.TryGetValue(authTokenKeys.Cookie, out var cookieToken) && cookieToken is not null)
|
||||||
|
context.Token = cookieToken;
|
||||||
|
else if (context.Request.Query.TryGetValue(authTokenKeys.QueryString, out var queryStrToken))
|
||||||
|
context.Token = queryStrToken;
|
||||||
|
}
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
};
|
||||||
}
|
});
|
||||||
};
|
|
||||||
|
// Authentication
|
||||||
|
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
||||||
|
.AddCookie(options =>
|
||||||
|
{
|
||||||
|
options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security
|
||||||
|
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only
|
||||||
|
options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites
|
||||||
|
options.LoginPath = "/api/auth/login";
|
||||||
|
options.LogoutPath = "/api/auth/logout";
|
||||||
|
options.SlidingExpiration = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Authentication
|
// User manager
|
||||||
builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
|
builder.Services.AddUserManager<EGDbContext>();
|
||||||
.AddCookie(options =>
|
|
||||||
{
|
|
||||||
options.Cookie.HttpOnly = true; // Makes the cookie inaccessible to client-side scripts for security
|
|
||||||
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest; // Ensures cookies are sent over HTTPS only
|
|
||||||
options.Cookie.SameSite = SameSiteMode.Strict; // Protects against CSRF attacks by restricting how cookies are sent with requests from external sites
|
|
||||||
options.LoginPath = "/api/auth/login";
|
|
||||||
options.LogoutPath = "/api/auth/logout";
|
|
||||||
options.SlidingExpiration = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
// User manager
|
// LDAP
|
||||||
builder.Services.AddUserManager<EGDbContext>();
|
builder.ConfigureBySection<DirectorySearchOptions>();
|
||||||
|
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
|
||||||
|
|
||||||
// LDAP
|
// Localizer
|
||||||
builder.ConfigureBySection<DirectorySearchOptions>();
|
builder.Services.AddCookieBasedLocalizer();
|
||||||
builder.Services.AddDirectorySearchService(config.GetSection("DirectorySearchOptions"));
|
|
||||||
|
|
||||||
// Localizer
|
// Envelope generator serives
|
||||||
builder.Services.AddCookieBasedLocalizer() ;
|
builder.Services
|
||||||
|
.AddEnvelopeGeneratorInfrastructureServices(sqlExecutorConfigureOptions: executor => executor.ConnectionString = connStr)
|
||||||
|
.AddEnvelopeGeneratorServices(config);
|
||||||
|
|
||||||
// Envelope generator serives
|
var app = builder.Build();
|
||||||
builder.Services
|
|
||||||
.AddEnvelopeGeneratorInfrastructureServices(sqlExecutorConfigureOptions: executor => executor.ConnectionString = connStr)
|
|
||||||
.AddEnvelopeGeneratorServices(config);
|
|
||||||
|
|
||||||
var app = builder.Build();
|
deferredProvider.Factory = () => app.Services;
|
||||||
|
|
||||||
deferredProvider.Factory = () => app.Services;
|
app.UseMiddleware<ExceptionHandlingMiddleware>();
|
||||||
|
|
||||||
app.UseMiddleware<ExceptionHandlingMiddleware>();
|
app.MapOpenApi();
|
||||||
|
|
||||||
app.MapOpenApi();
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment() || (app.IsDevOrDiP() && config.GetValue<bool>("UseSwagger")))
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
app.MapScalarApiReference();
|
||||||
|
}
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
// Set CORS policy
|
||||||
if (app.Environment.IsDevelopment() || (app.IsDevOrDiP() && config.GetValue<bool>("UseSwagger")))
|
app.UseCors("AllowSpecificOriginsPolicy");
|
||||||
{
|
|
||||||
app.UseSwagger();
|
// Localizer
|
||||||
app.UseSwaggerUI();
|
string[] supportedCultureNames = { "de-DE", "en-US" };
|
||||||
app.MapScalarApiReference();
|
IList<CultureInfo> list = supportedCultureNames.Select((string cn) => new CultureInfo(cn)).ToList();
|
||||||
|
CultureInfo cultureInfo = list.FirstOrDefault() ?? throw new ArgumentNullException("supportedCultureNames", "Supported cultures cannot be empty.");
|
||||||
|
RequestLocalizationOptions requestLocalizationOptions = new RequestLocalizationOptions
|
||||||
|
{
|
||||||
|
SupportedCultures = list,
|
||||||
|
SupportedUICultures = list
|
||||||
|
};
|
||||||
|
requestLocalizationOptions.RequestCultureProviders.Add(new QueryStringRequestCultureProvider());
|
||||||
|
app.UseRequestLocalization(requestLocalizationOptions);
|
||||||
|
|
||||||
|
|
||||||
|
app.UseHttpsRedirection();
|
||||||
|
|
||||||
|
app.UseDefaultFiles();
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
app.UseAuthentication();
|
||||||
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
app.Run();
|
||||||
}
|
}
|
||||||
|
catch (Exception ex)
|
||||||
// Set CORS policy
|
|
||||||
app.UseCors("AllowSpecificOriginsPolicy");
|
|
||||||
|
|
||||||
// Localizer
|
|
||||||
string[] supportedCultureNames = { "de-DE", "en-US" };
|
|
||||||
IList<CultureInfo> list = supportedCultureNames.Select((string cn) => new CultureInfo(cn)).ToList();
|
|
||||||
CultureInfo cultureInfo = list.FirstOrDefault() ?? throw new ArgumentNullException("supportedCultureNames", "Supported cultures cannot be empty.");
|
|
||||||
RequestLocalizationOptions requestLocalizationOptions = new RequestLocalizationOptions
|
|
||||||
{
|
{
|
||||||
SupportedCultures = list,
|
logger.Error(ex, "Stopped program because of exception");
|
||||||
SupportedUICultures = list
|
throw;
|
||||||
};
|
}
|
||||||
requestLocalizationOptions.RequestCultureProviders.Add(new QueryStringRequestCultureProvider());
|
|
||||||
app.UseRequestLocalization(requestLocalizationOptions);
|
|
||||||
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
|
|
||||||
app.UseDefaultFiles();
|
|
||||||
app.UseStaticFiles();
|
|
||||||
|
|
||||||
app.UseAuthentication();
|
|
||||||
app.UseAuthorization();
|
|
||||||
|
|
||||||
app.MapControllers();
|
|
||||||
|
|
||||||
app.Run();
|
|
||||||
@@ -39,7 +39,11 @@ public class EnvelopeReceiverRepository : CRUDRepository<EnvelopeReceiver, (int
|
|||||||
=> await ReadWhere(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).ToListAsync();
|
=> await ReadWhere(signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).ToListAsync();
|
||||||
|
|
||||||
public async Task<EnvelopeReceiver?> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true)
|
public async Task<EnvelopeReceiver?> ReadByUuidSignatureAsync(string uuid, string signature, bool withEnvelope = true, bool withReceiver = true, bool readOnly = true)
|
||||||
=> await ReadWhere(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly).FirstOrDefaultAsync();
|
{
|
||||||
|
var query = ReadWhere(uuid: uuid, signature: signature, withEnvelope: withEnvelope, withReceiver: withReceiver, readOnly: readOnly);
|
||||||
|
|
||||||
|
return await query.FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<string?> ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true)
|
public async Task<string?> ReadAccessCodeAsync(string uuid, string signature, bool readOnly = true)
|
||||||
=> await ReadWhere(uuid: uuid, signature: signature, readOnly: readOnly)
|
=> await ReadWhere(uuid: uuid, signature: signature, readOnly: readOnly)
|
||||||
|
|||||||
@@ -96,31 +96,32 @@ public class HomeController : ViewControllerBase
|
|||||||
|
|
||||||
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
ViewData["EnvelopeKey"] = envelopeReceiverId;
|
||||||
|
|
||||||
return await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId: envelopeReceiverId).ThenAsync<EnvelopeReceiverDto, IActionResult>(
|
var er_res = await _envRcvService.ReadByEnvelopeReceiverIdAsync(envelopeReceiverId: envelopeReceiverId);
|
||||||
SuccessAsync: async er =>
|
|
||||||
|
if (er_res.IsFailed)
|
||||||
|
{
|
||||||
|
_logger.LogNotice(er_res.Notices);
|
||||||
|
return this.ViewEnvelopeNotFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
var er = er_res.Data;
|
||||||
|
|
||||||
|
EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId);
|
||||||
|
|
||||||
|
bool accessCodeAlreadyRequested = await _historyService.AccessCodeAlreadyRequested(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress);
|
||||||
|
if (!accessCodeAlreadyRequested)
|
||||||
|
{
|
||||||
|
await _historyService.RecordAsync(er.EnvelopeId, er.Receiver.EmailAddress, EnvelopeStatus.AccessCodeRequested);
|
||||||
|
|
||||||
|
var mailRes = await _mailService.SendAccessCodeAsync(envelopeReceiverDto: er);
|
||||||
|
if (mailRes.IsFailed)
|
||||||
{
|
{
|
||||||
EnvelopeResponse response = await envelopeOldService.LoadEnvelope(envelopeReceiverId);
|
_logger.LogNotice(mailRes);
|
||||||
|
return this.ViewAccessCodeNotSent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool accessCodeAlreadyRequested = await _historyService.AccessCodeAlreadyRequested(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress);
|
return Redirect($"{envelopeReceiverId}/Locked");
|
||||||
if (!accessCodeAlreadyRequested)
|
|
||||||
{
|
|
||||||
await _historyService.RecordAsync(er.EnvelopeId, er.Receiver.EmailAddress, EnvelopeStatus.AccessCodeRequested);
|
|
||||||
|
|
||||||
var mailRes = await _mailService.SendAccessCodeAsync(envelopeReceiverDto: er);
|
|
||||||
if (mailRes.IsFailed)
|
|
||||||
{
|
|
||||||
_logger.LogNotice(mailRes);
|
|
||||||
return this.ViewAccessCodeNotSent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Redirect($"{envelopeReceiverId}/Locked");
|
|
||||||
},
|
|
||||||
Fail: (messages, notices) =>
|
|
||||||
{
|
|
||||||
_logger.LogNotice(notices);
|
|
||||||
return this.ViewEnvelopeNotFound();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch(Exception ex)
|
catch(Exception ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<PackageId>EnvelopeGenerator.Web</PackageId>
|
<PackageId>EnvelopeGenerator.Web</PackageId>
|
||||||
<Version>3.1.2</Version>
|
<Version>3.1.4</Version>
|
||||||
<Authors>Digital Data GmbH</Authors>
|
<Authors>Digital Data GmbH</Authors>
|
||||||
<Company>Digital Data GmbH</Company>
|
<Company>Digital Data GmbH</Company>
|
||||||
<Product>EnvelopeGenerator.Web</Product>
|
<Product>EnvelopeGenerator.Web</Product>
|
||||||
@@ -13,8 +13,8 @@
|
|||||||
<PackageTags>digital data envelope generator web</PackageTags>
|
<PackageTags>digital data envelope generator web</PackageTags>
|
||||||
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
|
<Description>EnvelopeGenerator.Web is an ASP.NET MVC application developed to manage signing processes. It uses Entity Framework Core (EF Core) for database operations. The user interface for signing processes is developed with Razor View Engine (.cshtml files) and JavaScript under wwwroot, integrated with PSPDFKit. This integration allows users to view and sign documents seamlessly.</Description>
|
||||||
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
|
||||||
<AssemblyVersion>3.1.2</AssemblyVersion>
|
<AssemblyVersion>3.1.4</AssemblyVersion>
|
||||||
<FileVersion>3.1.2</FileVersion>
|
<FileVersion>3.1.4</FileVersion>
|
||||||
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
<Copyright>Copyright © 2025 Digital Data GmbH. All rights reserved.</Copyright>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
@@ -2126,7 +2126,7 @@
|
|||||||
<PackageReference Include="Quartz.Serialization.Json" Version="3.8.0" />
|
<PackageReference Include="Quartz.Serialization.Json" Version="3.8.0" />
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
<PackageReference Include="System.Configuration.ConfigurationManager" Version="7.0.0" />
|
||||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
|
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="7.0.0" />
|
||||||
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices" Version="7.0.1" />
|
||||||
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="7.0.1" />
|
||||||
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
<PackageReference Include="System.DirectoryServices.Protocols" Version="7.0.1" />
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ try
|
|||||||
{
|
{
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
builder.Logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
|
||||||
|
|
||||||
|
if (!builder.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
builder.Logging.ClearProviders();
|
||||||
|
builder.Host.UseNLog();
|
||||||
|
}
|
||||||
|
|
||||||
var config = builder.Configuration;
|
var config = builder.Configuration;
|
||||||
|
|
||||||
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
|
var allowedOrigins = config.GetSection("AllowedOrigins").Get<string[]>() ??
|
||||||
@@ -41,15 +49,14 @@ try
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Logging.ClearProviders();
|
|
||||||
builder.Host.UseNLog();
|
|
||||||
|
|
||||||
// Add base services
|
// Add base services
|
||||||
builder.Services.AddScoped<DatabaseService>();
|
builder.Services.AddScoped<DatabaseService>();
|
||||||
|
|
||||||
// Add higher order services
|
// Add higher order services
|
||||||
builder.Services.AddScoped<EnvelopeOldService>();
|
builder.Services.AddScoped<EnvelopeOldService>();
|
||||||
|
|
||||||
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
builder.ConfigureBySection<TFARegParams>();
|
builder.ConfigureBySection<TFARegParams>();
|
||||||
|
|
||||||
// Add controllers and razor views
|
// Add controllers and razor views
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
public ActionService actionService;
|
public ActionService actionService;
|
||||||
public EmailService emailService;
|
public EmailService emailService;
|
||||||
|
|
||||||
public ServiceContainer(State state)
|
public ServiceContainer(State state, MSSQLServer MSSQL)
|
||||||
{
|
{
|
||||||
actionService = new(state);
|
actionService = new(state, MSSQL);
|
||||||
emailService = new(state);
|
emailService = new(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ namespace EnvelopeGenerator.Web.Services
|
|||||||
State.DbConfig = configModel.LoadConfiguration();
|
State.DbConfig = configModel.LoadConfiguration();
|
||||||
|
|
||||||
Models = new(State);
|
Models = new(State);
|
||||||
Services = new(State);
|
Services = new(State, MSSQL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,5 +7,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"AdminPassword": "dd",
|
"AdminPassword": "dd",
|
||||||
"UseCSPInDev": false
|
"UseCSPInDev": false,
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"Default": "Server=sDD-VMP04-SQL19\\CURSORAG;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -39,6 +39,11 @@
|
|||||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
"fileName": "${logDirectory}\\${logFileNamePrefix}-Info.log",
|
||||||
"maxArchiveDays": 30
|
"maxArchiveDays": 30
|
||||||
},
|
},
|
||||||
|
"warningLogs": {
|
||||||
|
"type": "File",
|
||||||
|
"fileName": "${logDirectory}\\${logFileNamePrefix}-Warning.log",
|
||||||
|
"maxArchiveDays": 30
|
||||||
|
},
|
||||||
"errorLogs": {
|
"errorLogs": {
|
||||||
"type": "File",
|
"type": "File",
|
||||||
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
"fileName": "${logDirectory}\\${logFileNamePrefix}-Error.log",
|
||||||
@@ -50,14 +55,17 @@
|
|||||||
"maxArchiveDays": 30
|
"maxArchiveDays": 30
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Trace, Debug, Info, Warn, Error and *Fatal*
|
|
||||||
"rules": [
|
"rules": [
|
||||||
{
|
{
|
||||||
"logger": "*",
|
"logger": "*",
|
||||||
"minLevel": "Info",
|
"level": "Info",
|
||||||
"maxLevel": "Warn",
|
|
||||||
"writeTo": "infoLogs"
|
"writeTo": "infoLogs"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"logger": "*",
|
||||||
|
"level": "Warn",
|
||||||
|
"writeTo": "warningLogs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"logger": "*",
|
"logger": "*",
|
||||||
"level": "Error",
|
"level": "Error",
|
||||||
|
|||||||
Reference in New Issue
Block a user