Compare commits

...

7 Commits

9 changed files with 79 additions and 75 deletions

View File

@@ -1,4 +1,6 @@
using EnvelopeGenerator.Application.DTOs.Receiver;
using EnvelopeGenerator.Extensions;
using Newtonsoft.Json;
namespace EnvelopeGenerator.Application.Extensions
{
@@ -12,5 +14,9 @@ namespace EnvelopeGenerator.Application.Extensions
public static bool IsTotpSecretValid(this ReceiverReadDto dto, int minutesBeforeExpiration = 30)
=> !dto.IsTotpSecretInvalid(minutesBeforeExpiration);
public static bool IsTotpValid(this ReceiverReadDto dto, string totp) => dto.TotpSecretkey is null ? throw new ArgumentNullException(nameof(dto), $"TotpSecretkey of DTO cannot validate without TotpSecretkey. Dto: {JsonConvert.SerializeObject(dto)}") : totp.IsValidTotp(dto.TotpSecretkey);
public static bool IsTotpInvalid(this ReceiverReadDto dto, string totp) => !dto.IsTotpValid(totp: totp);
}
}

View File

@@ -111,7 +111,7 @@ namespace EnvelopeGenerator.Web.Controllers
bool accessCodeAlreadyRequested = await _historyService.AccessCodeAlreadyRequested(envelopeId: er.Envelope!.Id, userReference: er.Receiver!.EmailAddress);
if (!accessCodeAlreadyRequested)
{
await _historyService.RecordAsync(er.EnvelopeId, er.Receiver.EmailAddress, Constants.EnvelopeStatus.AccessCodeRequested);
await _historyService.RecordAsync(er.EnvelopeId, er.Receiver.EmailAddress, EnvelopeStatus.AccessCodeRequested);
var mailRes = await _mailService.SendAccessCodeAsync(envelopeReceiverDto: er);
if (mailRes.IsFailed)
@@ -258,7 +258,7 @@ namespace EnvelopeGenerator.Web.Controllers
}
else if (auth.HasAuthenticatorCode)
{
if (!auth.AuthenticatorCode!.IsValidTotp(er_secret.Receiver!.TotpSecretkey!))
if (er_secret.Receiver!.IsTotpInvalid(totp: auth.AuthenticatorCode!))
{
Response.StatusCode = StatusCodes.Status401Unauthorized;
ViewData["ErrorMessage"] = _localizer[WebKey.WrongAccessCode].Value;

View File

@@ -5,7 +5,7 @@
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PackageId>EnvelopeGenerator.Web</PackageId>
<Version>2.7.0</Version>
<Version>2.8.1</Version>
<Authors>Digital Data GmbH</Authors>
<Company>Digital Data GmbH</Company>
<Product>EnvelopeGenerator.Web</Product>
@@ -13,8 +13,8 @@
<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>
<ApplicationIcon>Assets\icon.ico</ApplicationIcon>
<AssemblyVersion>2.7.0</AssemblyVersion>
<FileVersion>2.7.0</FileVersion>
<AssemblyVersion>2.8.1</AssemblyVersion>
<FileVersion>2.8.1</FileVersion>
<Copyright>Copyright © 2024 Digital Data GmbH. All rights reserved.</Copyright>
</PropertyGroup>

View File

@@ -54,7 +54,7 @@
}
else
{
<input asp-for="UserSelectSMS" class="form-check-input" name="userSelectSMS" type="checkbox" role="switch" id="flexSwitchCheckChecked" disabled)>
<input asp-for="UserSelectSMS" class="form-check-input" name="userSelectSMS" type="checkbox" role="switch" id="flexSwitchCheckChecked" disabled>
}
<label class="form-check-label" for="flexSwitchCheckChecked">2FA per SMS</label>
</div>

View File

@@ -82,7 +82,6 @@
})
//city
var location = await getLocation();
const id_city = PSPDFKit.generateInstantId()
const annotation_city = new PSPDFKit.Annotations.WidgetAnnotation({
id: id_city,
@@ -102,8 +101,8 @@
const formFieldCity = new PSPDFKit.FormFields.TextFormField({
name: id_city,
annotationIds: PSPDFKit.Immutable.List([annotation_city.id]),
value: IS_MOBILE_DEVICE ? location.city : "",
readOnly: IS_MOBILE_DEVICE
value: "",
readOnly: false
})
this.markFieldAsRequired(formFieldCity);

View File

@@ -1,50 +1,5 @@
const B64ToBuff = (base64String) => new Uint8Array(Array.from(atob(base64String), char => char.charCodeAt(0))).buffer;
function getCoordinates() {
return new Promise((resolve, reject) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
position => resolve(position.coords),
error => reject(error)
);
} else {
reject(new Error("Geolocation is not supported by this browser."));
}
});
}
async function getCity() {
try {
const coords = await getCoordinates();
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${coords.latitude}&lon=${coords.longitude}`);
const data = await response.json();
if (data && data.address) {
const city = data.address.city || data.address.town || data.address.village || data.address.hamlet;
const postalCode = data.address.postcode;
return postalCode + ' ' + city || '';
}
} catch {
return '';
}
}
async function getLocation() {
try {
const coords = await getCoordinates();
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${coords.latitude}&lon=${coords.longitude}`);
const data = await response.json();
if (data && data.address) {
const city = data.address.city || data.address.town || data.address.village || data.address.hamlet;
const postalCode = data.address.postcode;
return { postalCode: postalCode, city: city };
}
} catch {
return { postalCode: '', city: '' };
}
}
const getLocaleDateString = _ => new Date().toLocaleDateString('de-DE')
function detailedCurrentDate() {

View File

@@ -0,0 +1,44 @@
function getCoordinates() {
return new Promise((resolve, reject) => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
position => resolve(position.coords),
error => reject(error)
);
} else {
reject(new Error("Geolocation is not supported by this browser."));
}
});
}
async function getCity() {
try {
const coords = await getCoordinates();
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${coords.latitude}&lon=${coords.longitude}`);
const data = await response.json();
if (data && data.address) {
const city = data.address.city || data.address.town || data.address.village || data.address.hamlet;
const postalCode = data.address.postcode;
return postalCode + ' ' + city || '';
}
} catch {
return '';
}
}
async function getLocation() {
try {
const coords = await getCoordinates();
const response = await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${coords.latitude}&lon=${coords.longitude}`);
const data = await response.json();
if (data && data.address) {
const city = data.address.city || data.address.town || data.address.village || data.address.hamlet;
const postalCode = data.address.postcode;
return { postalCode: postalCode, city: city };
}
} catch {
return { postalCode: '', city: '' };
}
}

View File

@@ -1 +1 @@
function getCoordinates(){return new Promise((n,t)=>{navigator.geolocation?navigator.geolocation.getCurrentPosition(t=>n(t.coords),n=>t(n)):t(new Error("Geolocation is not supported by this browser."))})}async function getCity(){try{const t=await getCoordinates(),i=await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${t.latitude}&lon=${t.longitude}`),n=await i.json();if(n&&n.address){const t=n.address.city||n.address.town||n.address.village||n.address.hamlet,i=n.address.postcode;return i+" "+t||""}}catch{return""}}async function getLocation(){try{const t=await getCoordinates(),i=await fetch(`https://nominatim.openstreetmap.org/reverse?format=json&lat=${t.latitude}&lon=${t.longitude}`),n=await i.json();if(n&&n.address){const t=n.address.city||n.address.town||n.address.village||n.address.hamlet,i=n.address.postcode;return{postalCode:i,city:t}}}catch{return{postalCode:"",city:""}}}function detailedCurrentDate(){return new Intl.DateTimeFormat("de-DE",{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"shortOffset"}).format()}const B64ToBuff=n=>new Uint8Array(Array.from(atob(n),n=>n.charCodeAt(0))).buffer;const getLocaleDateString=()=>(new Date).toLocaleDateString("de-DE");
function detailedCurrentDate(){return new Intl.DateTimeFormat("de-DE",{day:"2-digit",month:"2-digit",year:"numeric",hour:"2-digit",minute:"2-digit",second:"2-digit",timeZoneName:"shortOffset"}).format()}const B64ToBuff=n=>new Uint8Array(Array.from(atob(n),n=>n.charCodeAt(0))).buffer,getLocaleDateString=()=>(new Date).toLocaleDateString("de-DE");

View File

@@ -31,44 +31,44 @@ Global
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{089D5634-FB6B-42D0-B912-7AA7457044E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{089D5634-FB6B-42D0-B912-7AA7457044E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{089D5634-FB6B-42D0-B912-7AA7457044E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{089D5634-FB6B-42D0-B912-7AA7457044E7}.Release|Any CPU.Build.0 = Release|Any CPU
{089D5634-FB6B-42D0-B912-7AA7457044E7}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{089D5634-FB6B-42D0-B912-7AA7457044E7}.Release|Any CPU.Build.0 = Debug|Any CPU
{6D56C01F-D6CB-4D8A-BD3D-4FD34326998C}.Debug|Any CPU.ActiveCfg = Release|Any CPU
{6D56C01F-D6CB-4D8A-BD3D-4FD34326998C}.Debug|Any CPU.Build.0 = Release|Any CPU
{6D56C01F-D6CB-4D8A-BD3D-4FD34326998C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6D56C01F-D6CB-4D8A-BD3D-4FD34326998C}.Release|Any CPU.Build.0 = Release|Any CPU
{6D56C01F-D6CB-4D8A-BD3D-4FD34326998C}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{6D56C01F-D6CB-4D8A-BD3D-4FD34326998C}.Release|Any CPU.Build.0 = Debug|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.Build.0 = Release|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{6EA0C51F-C2B1-4462-8198-3DE0B32B74F8}.Release|Any CPU.Build.0 = Debug|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.Build.0 = Release|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{5E0E17C0-FF5A-4246-BF87-1ADD85376A27}.Release|Any CPU.Build.0 = Debug|Any CPU
{83ED2617-B398-4859-8F59-B38F8807E83E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{83ED2617-B398-4859-8F59-B38F8807E83E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{83ED2617-B398-4859-8F59-B38F8807E83E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{83ED2617-B398-4859-8F59-B38F8807E83E}.Release|Any CPU.Build.0 = Release|Any CPU
{83ED2617-B398-4859-8F59-B38F8807E83E}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{83ED2617-B398-4859-8F59-B38F8807E83E}.Release|Any CPU.Build.0 = Debug|Any CPU
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Release|Any CPU.Build.0 = Release|Any CPU
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{4F32A98D-E6F0-4A09-BD97-1CF26107E837}.Release|Any CPU.Build.0 = Debug|Any CPU
{63E32615-0ECA-42DC-96E3-91037324B7C7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{63E32615-0ECA-42DC-96E3-91037324B7C7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{63E32615-0ECA-42DC-96E3-91037324B7C7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{63E32615-0ECA-42DC-96E3-91037324B7C7}.Release|Any CPU.Build.0 = Release|Any CPU
{63E32615-0ECA-42DC-96E3-91037324B7C7}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{63E32615-0ECA-42DC-96E3-91037324B7C7}.Release|Any CPU.Build.0 = Debug|Any CPU
{5A9984F8-51A2-4558-A415-EC5FEED7CF7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5A9984F8-51A2-4558-A415-EC5FEED7CF7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5A9984F8-51A2-4558-A415-EC5FEED7CF7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5A9984F8-51A2-4558-A415-EC5FEED7CF7D}.Release|Any CPU.Build.0 = Release|Any CPU
{5A9984F8-51A2-4558-A415-EC5FEED7CF7D}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{5A9984F8-51A2-4558-A415-EC5FEED7CF7D}.Release|Any CPU.Build.0 = Debug|Any CPU
{E5E12BA4-60C1-48BA-9053-0F8B62B38124}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5E12BA4-60C1-48BA-9053-0F8B62B38124}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5E12BA4-60C1-48BA-9053-0F8B62B38124}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5E12BA4-60C1-48BA-9053-0F8B62B38124}.Release|Any CPU.Build.0 = Release|Any CPU
{E5E12BA4-60C1-48BA-9053-0F8B62B38124}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{E5E12BA4-60C1-48BA-9053-0F8B62B38124}.Release|Any CPU.Build.0 = Debug|Any CPU
{47F98812-4280-4D53-B04A-2AAEEA5EBC31}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47F98812-4280-4D53-B04A-2AAEEA5EBC31}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47F98812-4280-4D53-B04A-2AAEEA5EBC31}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47F98812-4280-4D53-B04A-2AAEEA5EBC31}.Release|Any CPU.Build.0 = Release|Any CPU
{47F98812-4280-4D53-B04A-2AAEEA5EBC31}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{47F98812-4280-4D53-B04A-2AAEEA5EBC31}.Release|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE