fix active membership, 2fa webauthn
This commit is contained in:
+1
-1
@@ -356,7 +356,7 @@ public class MembershipManager {
|
||||
|
||||
for (JsonObject membershipOrderPosition : membershipOrderPositions) {
|
||||
Instant active = getDateAnswer(membershipOrderPosition, membershipActiveQuestion);
|
||||
if (active.isAfter(InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS))
|
||||
if (active != null && active.isAfter(InstantHelper.truncate(Instant.now(), ChronoUnit.YEARS))
|
||||
&& InstantHelper.minus(active, membershipfeeOrderDays, ChronoUnit.DAYS).isBefore(Instant.now())) {
|
||||
expireMemberships.add(membershipOrderPosition);
|
||||
} else {
|
||||
|
||||
@@ -210,7 +210,7 @@ public class WebAuthnManager implements UserDataProvider {
|
||||
|
||||
StartAssertionOptions.StartAssertionOptionsBuilder optionsBuilder = StartAssertionOptions.builder()
|
||||
.username(user.getUsername())
|
||||
.userVerification(UserVerificationRequirement.REQUIRED);
|
||||
.userVerification(UserVerificationRequirement.PREFERRED);
|
||||
|
||||
AssertionRequest request = relyingParty.startAssertion(optionsBuilder.build());
|
||||
|
||||
@@ -253,6 +253,54 @@ public class WebAuthnManager implements UserDataProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean validateRequest(String assertionJson, WebAuthnUsage usage) {
|
||||
try {
|
||||
JsonNode assertionNode = objectMapper.readTree(assertionJson);
|
||||
|
||||
PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> pkc = PublicKeyCredential
|
||||
.parseAssertionResponseJson(assertionJson);
|
||||
WebAuthnCredential credential = credentialRepository.findByCredentialId(pkc.getId().getBase64Url());
|
||||
|
||||
if (credential == null || !credential.isEnabled() || (credential.getUsage() != usage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Long userId = credential.getTarget();
|
||||
|
||||
String clientDataBase64 = assertionNode.get("response").get("clientDataJSON").asText();
|
||||
ByteArray clientDataBytes = ByteArray.fromBase64Url(clientDataBase64);
|
||||
JsonNode clientData = objectMapper.readTree(clientDataBytes.getBytes());
|
||||
String challengeBase64 = clientData.get("challenge").asText();
|
||||
|
||||
WebAuthnChallenge storedChallenge = challengeRepository
|
||||
.findByUserIdAndChallengeAndTypeAndExpiresAtAfter(userId, challengeBase64,
|
||||
"authentication", Instant.now());
|
||||
|
||||
if (storedChallenge == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AssertionRequest filteredRequest = AssertionRequest.fromJson(storedChallenge.getRequestJson());
|
||||
|
||||
AssertionResult result = relyingParty.finishAssertion(FinishAssertionOptions.builder()
|
||||
.request(filteredRequest)
|
||||
.response(pkc).build());
|
||||
|
||||
if (result.isSuccess()) {
|
||||
credential.setSignatureCount(result.getSignatureCount());
|
||||
credential.setLastUsedAt(Instant.now());
|
||||
credentialRepository.save(credential);
|
||||
challengeRepository.delete(storedChallenge);
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to generate WebAuthn challenge", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public String createLoginRequest() {
|
||||
try {
|
||||
StartAssertionOptions.StartAssertionOptionsBuilder optionsBuilder = StartAssertionOptions.builder()
|
||||
@@ -318,54 +366,6 @@ public class WebAuthnManager implements UserDataProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean validateRequest(String assertionJson, WebAuthnUsage usage) {
|
||||
try {
|
||||
JsonNode assertionNode = objectMapper.readTree(assertionJson);
|
||||
|
||||
PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> pkc = PublicKeyCredential
|
||||
.parseAssertionResponseJson(assertionJson);
|
||||
WebAuthnCredential credential = credentialRepository.findByCredentialId(pkc.getId().getBase64Url());
|
||||
|
||||
if (credential == null || !credential.isEnabled() || (credential.getUsage() != usage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Long userId = credential.getTarget();
|
||||
|
||||
String clientDataBase64 = assertionNode.get("response").get("clientDataJSON").asText();
|
||||
ByteArray clientDataBytes = ByteArray.fromBase64Url(clientDataBase64);
|
||||
JsonNode clientData = objectMapper.readTree(clientDataBytes.getBytes());
|
||||
String challengeBase64 = clientData.get("challenge").asText();
|
||||
|
||||
WebAuthnChallenge storedChallenge = challengeRepository
|
||||
.findByUserIdAndChallengeAndTypeAndExpiresAtAfter(userId, challengeBase64,
|
||||
"authentication", Instant.now());
|
||||
|
||||
if (storedChallenge == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
AssertionRequest filteredRequest = AssertionRequest.fromJson(storedChallenge.getRequestJson());
|
||||
|
||||
AssertionResult result = relyingParty.finishAssertion(FinishAssertionOptions.builder()
|
||||
.request(filteredRequest)
|
||||
.response(pkc).build());
|
||||
|
||||
if (result.isSuccess()) {
|
||||
credential.setSignatureCount(result.getSignatureCount());
|
||||
credential.setLastUsedAt(Instant.now());
|
||||
credentialRepository.save(credential);
|
||||
challengeRepository.delete(storedChallenge);
|
||||
return true;
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to generate WebAuthn challenge", e);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public WebAuthnCredential getCredentialForAssertionJson(String assertionJson) {
|
||||
try {
|
||||
PublicKeyCredential<AuthenticatorAssertionResponse, ClientAssertionExtensionOutputs> pkc = PublicKeyCredential
|
||||
|
||||
Reference in New Issue
Block a user