+
Android Sample Project
+
by walt.id
+
Sample project showcasing key & DID creation, text signing, and signed content verification.
+
+
+
+
+
+
+
## Features
-1. **Key Generation**: The application allows you to generate keys using different algorithms such as RSA and Secp256r1.
+1. **Key Generation**: Generate keys using different algorithms (RSA, Secp256r1).
-2. **Signing Text**: You can sign any text using the generated keys. The application supports both raw and JWS signing options.
+2. **Text Signing**: Sign text with RAW or JWS signing options.
-3. **DID Creation**: The application can generate DIDs using the generated keys. It supports both 'key' and 'jwk' methods for DID creation.
+3. **DID Creation**: Create DIDs (did:key, did:jwk) based on generated keys.
-4. **Verification**: The application can verify the signed text using the generated keys and DIDs.
+4. **Verification**: Verify signed text using generated keys and DIDs.
## Screenshots
@@ -26,8 +34,8 @@ This project showcases the capabilities of the WALT ID library, demonstrating ho
## Join the community
-* Connect and get the latest updates: Discord | Newsletter | YouTube | Twitter
-* Get help, request features and report bugs: GitHub Discussions
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
## License
From 7938bdb2865ddb1b154924a3564a4654bad5300d Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 09:27:17 +0100
Subject: [PATCH 17/91] fix: update join community section
---
waltid-applications/waltid-web-portal/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/waltid-applications/waltid-web-portal/README.md b/waltid-applications/waltid-web-portal/README.md
index e8aeb7683..2d0023d03 100644
--- a/waltid-applications/waltid-web-portal/README.md
+++ b/waltid-applications/waltid-web-portal/README.md
@@ -48,8 +48,8 @@ docker run -p 7102:7102 -i -t waltid/portal
## Join the community
-* Connect and get the latest updates: Discord | Newsletter | YouTube | Twitter
-* Get help, request features and report bugs: GitHub Discussions
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
## License
From fb6328a0dde8ff817591b09dbb3ab91cd8e242d8 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 09:27:48 +0100
Subject: [PATCH 18/91] fix: update join community section
---
waltid-applications/waltid-web-wallet/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/waltid-applications/waltid-web-wallet/README.md b/waltid-applications/waltid-web-wallet/README.md
index 7a1ea7a34..b4c8e14f1 100644
--- a/waltid-applications/waltid-web-wallet/README.md
+++ b/waltid-applications/waltid-web-wallet/README.md
@@ -66,8 +66,8 @@ Features are provided by our libraries SSI-Kit and NFT-Kit to enable SSI and NFT
## Join the community
-* Connect and get the latest updates: Discord | Newsletter | YouTube | Twitter
-* Get help, request features and report bugs: GitHub Discussions
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
## License
From ccacd29291a6355fa47fe4e48b48a9c1db7ba537 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 09:31:03 +0100
Subject: [PATCH 19/91] feat: add join community section
---
.../credentials/waltid-mdoc-credentials/README.md | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/waltid-libraries/credentials/waltid-mdoc-credentials/README.md b/waltid-libraries/credentials/waltid-mdoc-credentials/README.md
index e06447398..4cdd5992e 100644
--- a/waltid-libraries/credentials/waltid-mdoc-credentials/README.md
+++ b/waltid-libraries/credentials/waltid-mdoc-credentials/README.md
@@ -438,6 +438,12 @@ Namespace: org.iso.18013.5.1
)
```
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
## License
Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
From 88fd0275f44464c2b6af4f4137ad2253bbc6cf07 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 09:38:24 +0100
Subject: [PATCH 20/91] feat: add join community section
---
.../credentials/waltid-verifiable-credentials/README.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/waltid-libraries/credentials/waltid-verifiable-credentials/README.md b/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
index 0c65d507d..ed6556b18 100644
--- a/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
+++ b/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
@@ -191,3 +191,8 @@ val validationResult = Verifier.verifyPresentation(
)
)
```
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
From 774e3cd1d0f51f60c215a7af8f4387d3014fdd52 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 09:41:14 +0100
Subject: [PATCH 21/91] feat: add license section
---
.../credentials/waltid-verifiable-credentials/README.md | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/waltid-libraries/credentials/waltid-verifiable-credentials/README.md b/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
index ed6556b18..dcd464599 100644
--- a/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
+++ b/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
@@ -196,3 +196,8 @@ val validationResult = Verifier.verifyPresentation(
* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
From 09dc5a65b093baca7c80b91ba23571f27830b3ff Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 09:41:50 +0100
Subject: [PATCH 22/91] feat: add community & license section
---
waltid-libraries/crypto/waltid-crypto/README.md | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/waltid-libraries/crypto/waltid-crypto/README.md b/waltid-libraries/crypto/waltid-crypto/README.md
index 440f7d429..67630f525 100644
--- a/waltid-libraries/crypto/waltid-crypto/README.md
+++ b/waltid-libraries/crypto/waltid-crypto/README.md
@@ -737,3 +737,13 @@ data class AWSKeyMetadata(
For usage examples on _create_, _sign_, _verify_, _import_ and _export_ functions see
[Working with JWKKey](#working-with-jwkKey).
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
From 9e9e9ef77cd04d7daf699d2fd3350a1c8652aa42 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 10:08:06 +0100
Subject: [PATCH 23/91] feat: add header & community & license section
---
.../crypto/waltid-crypto-android/README.md | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/waltid-libraries/crypto/waltid-crypto-android/README.md b/waltid-libraries/crypto/waltid-crypto-android/README.md
index 105dd4d7e..9aeb71577 100644
--- a/waltid-libraries/crypto/waltid-crypto-android/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-android/README.md
@@ -1,4 +1,15 @@
-# Android optional extension for waltid-crypto
+
+
Optional Android extension for waltid-crypto
+
by walt.id
+
Adds support for `AndroidKey`, an Android Keystore backed `Key`.
+
+
+
+
+
+
+
+
Platforms: Android-only
@@ -7,3 +18,13 @@ Adds support for `AndroidKey`, an Android Keystore backed `Key`.
## Build instructions
Set your `sdk.dir` in `local.properties` and then enable the Android build
with `enableAndroidBuild=true` in `gradle.properties`.
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
From 7a4823e3fbbd471e4776f0cc5334ff80a1129c2a Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 10:09:15 +0100
Subject: [PATCH 24/91] feat: add header & community & license section
---
.../crypto/waltid-crypto-aws/README.md | 25 ++++++++++++++++---
1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/waltid-libraries/crypto/waltid-crypto-aws/README.md b/waltid-libraries/crypto/waltid-crypto-aws/README.md
index 32c32e901..abfeb539f 100644
--- a/waltid-libraries/crypto/waltid-crypto-aws/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-aws/README.md
@@ -1,6 +1,15 @@
-# AWS SDK Extension for walt.id Crypto
-
-A Kotlin-based extension that enhances walt.id crypto with native AWS key management capabilities.
+
+
AWS SDK Extension for walt.id Crypto
+
by walt.id
+
A Kotlin-based extension that enhances walt.id crypto with native AWS key management capabilities.
+
+
+
+
+
+
+
+
## Overview
@@ -31,3 +40,13 @@ While the base `AWSKeyRestAPI` offers cross-platform compatibility through REST
- Enhanced error handling
- Native integration with AWS services
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+
From 1e1763d787b6281ee1fa3dc54e2187f3c008bacd Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 10:10:01 +0100
Subject: [PATCH 25/91] feat: add community & license section
---
waltid-libraries/crypto/waltid-crypto-ios/README.md | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/waltid-libraries/crypto/waltid-crypto-ios/README.md b/waltid-libraries/crypto/waltid-crypto-ios/README.md
index 4543518b0..295c74989 100644
--- a/waltid-libraries/crypto/waltid-crypto-ios/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-ios/README.md
@@ -53,3 +53,13 @@ val key = IosKey.create("kid", KeyType.secp256r1)
#### Implementation details
Module references `:waltid-libraries:waltid-target-ios` that is exposing functionality from static library built by `:waltid-libraries:waltid-target-ios:implementation' module. This module acts as an umbrella for iOS related functionaltiy - for now only crypto things.
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
From fe5698aacc7e5cb93e178fee152c39c6b3e17577 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:24:20 +0100
Subject: [PATCH 26/91] feat: add header & community & license section
---
.../crypto/waltid-crypto-oci/README.md | 23 ++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/waltid-libraries/crypto/waltid-crypto-oci/README.md b/waltid-libraries/crypto/waltid-crypto-oci/README.md
index 66e808252..5cdc63ce0 100644
--- a/waltid-libraries/crypto/waltid-crypto-oci/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-oci/README.md
@@ -1,4 +1,15 @@
-# OCI optional extension for waltid-crypto
+
+
OCI optional extension for waltid-crypto
+
by walt.id
+
Adds support for `OCIKey`, an OCI SDK backed `Key`.
+
+
+
+
+
+
+
+
Platforms: JVM-only
@@ -6,3 +17,13 @@ Adds support for `OCIKey`, an OCI SDK backed `Key`.
This is an alternative to the `OCIRestKey` of base waltid-crypto, which works on all platforms and uses the OCI REST API.
This module uses the Java OCI SDK instead of the REST API.
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
\ No newline at end of file
From b571c822e323e33a2014e07f93a5e6af53c55713 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:25:27 +0100
Subject: [PATCH 27/91] feat: add community & license section
---
.../protocols/waltid-openid4vc/README.md | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/waltid-libraries/protocols/waltid-openid4vc/README.md b/waltid-libraries/protocols/waltid-openid4vc/README.md
index 36a3dd34a..9e210a55e 100644
--- a/waltid-libraries/protocols/waltid-openid4vc/README.md
+++ b/waltid-libraries/protocols/waltid-openid4vc/README.md
@@ -414,10 +414,6 @@ For the full demo verifier implementation, refer to `/src/jvmTest/kotlin/id/walt
#### Business logic
-## License
-
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-xyzkit/blob/master/LICENSE)
-
# Example flows:
## EBSI conformance test: Credential issuance:
@@ -448,3 +444,13 @@ Issuer -->> Wallet: Credential (and updated c_nonce)
end
```
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
\ No newline at end of file
From 44baf572cab5799c93df77f652c5db04a852cb81 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:28:17 +0100
Subject: [PATCH 28/91] feat: add community & license section
---
waltid-libraries/sdjwt/waltid-sdjwt/README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/waltid-libraries/sdjwt/waltid-sdjwt/README.md b/waltid-libraries/sdjwt/waltid-sdjwt/README.md
index 99088f24c..0121c0aa5 100644
--- a/waltid-libraries/sdjwt/waltid-sdjwt/README.md
+++ b/waltid-libraries/sdjwt/waltid-sdjwt/README.md
@@ -354,10 +354,10 @@ console.log("SDMap reconstructed", presentedJwt2.sdMap)
## Join the community
-* Connect and get the latest
- updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
-* Get help, request features and report bugs: [GitHub Discussions](https://github.com/walt-id/.github/discussions)
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-nftkit/blob/main/LICENSE)
+Licensed under the Apache License, Version 2.0
From 318897f94b3b422fd6083128cc39a964bf43a919 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:32:57 +0100
Subject: [PATCH 29/91] fix: license link
---
waltid-libraries/credentials/waltid-mdoc-credentials/README.md | 2 +-
.../credentials/waltid-verifiable-credentials/README.md | 2 +-
waltid-libraries/crypto/waltid-crypto-android/README.md | 2 +-
waltid-libraries/crypto/waltid-crypto-aws/README.md | 2 +-
waltid-libraries/crypto/waltid-crypto-ios/README.md | 2 +-
waltid-libraries/crypto/waltid-crypto-oci/README.md | 2 +-
waltid-libraries/crypto/waltid-crypto/README.md | 2 +-
waltid-libraries/protocols/waltid-openid4vc/README.md | 2 +-
8 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/waltid-libraries/credentials/waltid-mdoc-credentials/README.md b/waltid-libraries/credentials/waltid-mdoc-credentials/README.md
index 4cdd5992e..f081cca8c 100644
--- a/waltid-libraries/credentials/waltid-mdoc-credentials/README.md
+++ b/waltid-libraries/credentials/waltid-mdoc-credentials/README.md
@@ -446,4 +446,4 @@ Namespace: org.iso.18013.5.1
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
diff --git a/waltid-libraries/credentials/waltid-verifiable-credentials/README.md b/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
index dcd464599..5db2432a5 100644
--- a/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
+++ b/waltid-libraries/credentials/waltid-verifiable-credentials/README.md
@@ -200,4 +200,4 @@ val validationResult = Verifier.verifyPresentation(
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
diff --git a/waltid-libraries/crypto/waltid-crypto-android/README.md b/waltid-libraries/crypto/waltid-crypto-android/README.md
index 9aeb71577..b02accd37 100644
--- a/waltid-libraries/crypto/waltid-crypto-android/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-android/README.md
@@ -27,4 +27,4 @@ with `enableAndroidBuild=true` in `gradle.properties`.
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
diff --git a/waltid-libraries/crypto/waltid-crypto-aws/README.md b/waltid-libraries/crypto/waltid-crypto-aws/README.md
index abfeb539f..db1e72986 100644
--- a/waltid-libraries/crypto/waltid-crypto-aws/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-aws/README.md
@@ -48,5 +48,5 @@ While the base `AWSKeyRestAPI` offers cross-platform compatibility through REST
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
diff --git a/waltid-libraries/crypto/waltid-crypto-ios/README.md b/waltid-libraries/crypto/waltid-crypto-ios/README.md
index 295c74989..c37980bae 100644
--- a/waltid-libraries/crypto/waltid-crypto-ios/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-ios/README.md
@@ -62,4 +62,4 @@ Module references `:waltid-libraries:waltid-target-ios` that is exposing functio
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
diff --git a/waltid-libraries/crypto/waltid-crypto-oci/README.md b/waltid-libraries/crypto/waltid-crypto-oci/README.md
index 5cdc63ce0..ade5eae8f 100644
--- a/waltid-libraries/crypto/waltid-crypto-oci/README.md
+++ b/waltid-libraries/crypto/waltid-crypto-oci/README.md
@@ -26,4 +26,4 @@ This module uses the Java OCI SDK instead of the REST API.
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
\ No newline at end of file
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
\ No newline at end of file
diff --git a/waltid-libraries/crypto/waltid-crypto/README.md b/waltid-libraries/crypto/waltid-crypto/README.md
index 67630f525..780b40121 100644
--- a/waltid-libraries/crypto/waltid-crypto/README.md
+++ b/waltid-libraries/crypto/waltid-crypto/README.md
@@ -746,4 +746,4 @@ For usage examples on _create_, _sign_, _verify_, _import_ and _export_ function
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
diff --git a/waltid-libraries/protocols/waltid-openid4vc/README.md b/waltid-libraries/protocols/waltid-openid4vc/README.md
index 9e210a55e..1d0d9ae40 100644
--- a/waltid-libraries/protocols/waltid-openid4vc/README.md
+++ b/waltid-libraries/protocols/waltid-openid4vc/README.md
@@ -453,4 +453,4 @@ end
## License
-Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-mdoc/blob/master/LICENSE)
\ No newline at end of file
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
\ No newline at end of file
From f0fa12fdf488b623f7c272fa5ac8363f56e6ada8 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:34:29 +0100
Subject: [PATCH 30/91] feat: add community & license section
---
waltid-libraries/waltid-did/README.md | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/waltid-libraries/waltid-did/README.md b/waltid-libraries/waltid-did/README.md
index f9bb3e800..876d596d6 100644
--- a/waltid-libraries/waltid-did/README.md
+++ b/waltid-libraries/waltid-did/README.md
@@ -335,3 +335,14 @@ implementation (jwk_jcs-pub encoding) according https://hub.ebsi.eu/tools/librar
According Universal Resolver: https://github.com/decentralized-identity/universal-resolver/
According Universal Registrar: https://github.com/decentralized-identity/universal-registrar/
+
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
\ No newline at end of file
From f99d99ffb34cee149bdd1eac4da64657f2653fcf Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:40:44 +0100
Subject: [PATCH 31/91] feat: add community & license section & expand feature
list with SD-JWT VC
---
waltid-services/waltid-issuer-api/README.md | 22 +++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/waltid-services/waltid-issuer-api/README.md b/waltid-services/waltid-issuer-api/README.md
index cbe776c05..0a2251f18 100644
--- a/waltid-services/waltid-issuer-api/README.md
+++ b/waltid-services/waltid-issuer-api/README.md
@@ -50,7 +50,7 @@ can be found in the table below:
- w3c |
+ W3C |
jwt |
✓ |
✓ |
@@ -61,13 +61,21 @@ can be found in the table below:
sd-jwt |
✓ |
+ ✓ |
+ ✗ |
✗ |
+
+
+
+ SD-JWT VC (IETF) |
+ ✓ |
+ ✓ |
✗ |
✗ |
- mdoc |
+ mDL/mdoc |
‐ |
‐ |
✗ |
@@ -121,3 +129,13 @@ Or, run with local config directory:
```shell
docker run -p 7002:7002 -v $PWD/waltid-services/waltid-issuer-api/config:/waltid-issuer-api/config -t waltid/issuer-api
```
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
From 1a386e8db3c9e80df2b5d134246e5405e21339c5 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:43:04 +0100
Subject: [PATCH 32/91] feat: add community & license section & expand feature
list with SD-JWT VC
---
waltid-services/waltid-verifier-api/README.md | 20 +++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/waltid-services/waltid-verifier-api/README.md b/waltid-services/waltid-verifier-api/README.md
index 85fc481e7..2ad332c88 100644
--- a/waltid-services/waltid-verifier-api/README.md
+++ b/waltid-services/waltid-verifier-api/README.md
@@ -39,7 +39,7 @@ can be found in the table below:
- w3c |
+ W3C |
jwt |
✓ |
✗ |
@@ -50,9 +50,15 @@ can be found in the table below:
✓ |
✗ |
+
+
+ SD-JWT VC (IETF) |
+ ✓ |
+ ✗ |
+
- mdoc |
+ mDL/mdoc |
✗ |
‐ |
@@ -131,3 +137,13 @@ https://verifier.portal.walt-test.cloud/swagger/index.html
```jsx
mdoc-openid4vp://?response_type=vp_token&client_id=&response_mode=direct_post.jwt&state=AqkYhRmbHpEX&presentation_definition_uri=http%3A%2F%2Flocalhost%3A7003%2Fopenid4vc%2Fpd%2FAqkYhRmbHpEX&client_id_scheme=redirect_uri&client_metadata=%7B%22jwks%22%3A%7B%22keys%22%3A%5B%7B%22kty%22%3A%22EC%22%2C%22crv%22%3A%22P-256%22%2C%22kid%22%3A%22b6ERrLYBSfsJ_nFLMgw6jtPGgzWSxyZX91RlRTvL-c4%22%2C%22x%22%3A%22lZMnJXRAgZ3YQAtFpqSaAywEb34XsWkP2aN3C9ZJwz8%22%2C%22y%22%3A%22rHNeTy9wUOmb4RH2R8YRKZxMadc55qWe_0TGUwgc0Hk%22%2C%22use%22%3A%22enc%22%2C%22alg%22%3A%22ECDH-ES%22%7D%5D%7D%2C%22authorization_encrypted_response_alg%22%3A%22ECDH-ES%22%2C%22authorization_encrypted_response_enc%22%3A%22A256GCM%22%7D&nonce=af1b4ddd-db15-47b8-bcf7-7773c4d75e82&response_uri=http%3A%2F%2Flocalhost%3A7003%2Fopenid4vc%2Fverify%2FAqkYhRmbHpEX
```
+
+## Join the community
+
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
+
+## License
+
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
\ No newline at end of file
From c8112647bd488ad955ee3ef34e09dcb5518a9ed8 Mon Sep 17 00:00:00 2001
From: Tamino
Date: Thu, 9 Jan 2025 11:44:58 +0100
Subject: [PATCH 33/91] fix: update community & license section
---
waltid-services/waltid-wallet-api/README.md | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/README.md b/waltid-services/waltid-wallet-api/README.md
index 5fc8333c3..6c046c76e 100644
--- a/waltid-services/waltid-wallet-api/README.md
+++ b/waltid-services/waltid-wallet-api/README.md
@@ -116,13 +116,10 @@ docker run --name mssql -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=p@ssw0rd" -p 14
## Join the community
-* Connect and get the latest updates:
- Discord |
- Newsletter |
- YouTube | Twitter
-* Get help, request features and report bugs:
- GitHub Discussions
+* Connect and get the latest updates: [Discord](https://discord.gg/AW8AgqJthZ) | [Newsletter](https://walt.id/newsletter) | [YouTube](https://www.youtube.com/channel/UCXfOzrv3PIvmur_CmwwmdLA) | [Twitter](https://mobile.twitter.com/walt_id)
+* Get help, request features and report bugs: [GitHub Issues ](https://github.com/walt-id/waltid-identity/issues)
+
## License
-**Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-ssikit/blob/master/LICENSE).**
+Licensed under the [Apache License, Version 2.0](https://github.com/walt-id/waltid-identity/blob/main/LICENSE)
From 1581079cdbc5a9cf41bb37b3356ba9e4b1cefa30 Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Sun, 12 Jan 2025 15:49:56 +0100
Subject: [PATCH 34/91] add AuthenticationService
---
.../account/authnz/AuthenticationService.kt | 189 ++++++++++++++++++
1 file changed, 189 insertions(+)
create mode 100644 waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
new file mode 100644
index 000000000..ba69d0d69
--- /dev/null
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
@@ -0,0 +1,189 @@
+import AccountIdentifiers.userId
+import id.walt.ktorauthnz.accounts.EditableAccountStore
+import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
+import id.walt.ktorauthnz.methods.AuthenticationMethod
+import id.walt.ktorauthnz.methods.data.AuthMethodStoredData
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import org.jetbrains.exposed.sql.*
+import org.jetbrains.exposed.sql.transactions.transaction
+import java.util.*
+import kotlin.uuid.ExperimentalUuidApi
+
+object Users : Table() {
+ val id = uuid("id").autoGenerate()
+ val publicKey = varchar("public_key", 42).uniqueIndex() // Ethereum addresses are 42 chars including '0x'
+
+ override val primaryKey = PrimaryKey(id)
+}
+
+object AccountIdentifiers : Table() {
+ val id = uuid("id").autoGenerate()
+ val userId = uuid("user_id").references(Users.id)
+ val identifier = varchar("identifier", 255)
+ val method = varchar("method", 50)
+
+ override val primaryKey = PrimaryKey(id)
+}
+
+
+object StoredData : Table() {
+ val id = uuid("id").autoGenerate()
+ val accountId = uuid("account_id").references(Users.id)
+ val method = varchar("method", 50)
+ val data = text("data")
+
+ override val primaryKey = PrimaryKey(id)
+}
+
+
+@OptIn(ExperimentalUuidApi::class)
+class AuthenticationService(private val database: Database) {
+
+ init {
+ transaction(database) {
+ SchemaUtils.create(Users, AccountIdentifiers, StoredData)
+ }
+ }
+
+
+ val editableAccountStore = object : EditableAccountStore {
+ override suspend fun addAccountIdentifierToAccount(
+ accountId: String,
+ newAccountIdentifier: AccountIdentifier
+ ): Unit = withContext(Dispatchers.IO) {
+ transaction(database) {
+ AccountIdentifiers.insert {
+ it[userId] = UUID.fromString(accountId)
+ it[identifier] = newAccountIdentifier.accountIdentifierName
+ }
+ Unit // Explicitly return Unit
+ }
+ }
+
+ override suspend fun removeAccountIdentifierFromAccount(accountIdentifier: AccountIdentifier) {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun addAccountIdentifierStoredData(
+ accountIdentifier: AccountIdentifier,
+ method: String,
+ data: AuthMethodStoredData
+ ): Unit = withContext(Dispatchers.IO) {
+ transaction(database) {
+ val userId = AccountIdentifiers
+ .select(userId)
+ .where { AccountIdentifiers.identifier eq accountIdentifier.accountIdentifierName }
+ .singleOrNull()?.get(AccountIdentifiers.userId)
+ ?: throw IllegalStateException("Account not found")
+
+ StoredData.insert {
+ it[accountId] = userId
+ it[StoredData.method] = method
+ it[StoredData.data] = data.toString()
+ }
+ Unit
+ }
+ }
+
+
+ override suspend fun addAccountStoredData(
+ accountId: String,
+ method: String,
+ data: AuthMethodStoredData
+ ): Unit = withContext(Dispatchers.IO) {
+ transaction(database) {
+ StoredData.insert {
+ it[StoredData.accountId] = UUID.fromString(accountId)
+ it[StoredData.method] = method
+ it[StoredData.data] = data.toString()
+ }
+ Unit
+ }
+ }
+
+ override suspend fun updateAccountIdentifierStoredData(
+ accountIdentifier: AccountIdentifier,
+ method: String,
+ data: AuthMethodStoredData
+ ) {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun updateAccountStoredData(
+ accountId: String,
+ method: String,
+ data: AuthMethodStoredData
+ ) {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun deleteAccountIdentifierStoredData(
+ accountIdentifier: AccountIdentifier,
+ method: String
+ ) {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun deleteAccountStoredData(accountId: String, method: String) {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun lookupStoredDataForAccount(
+ accountId: String,
+ method: AuthenticationMethod
+ ): AuthMethodStoredData? {
+ TODO()
+ }
+
+
+ override suspend fun lookupStoredDataForAccountIdentifier(
+ identifier: AccountIdentifier,
+ method: AuthenticationMethod
+ ): AuthMethodStoredData? {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun lookupAccountUuid(identifier: AccountIdentifier): String =
+ withContext(Dispatchers.IO) {
+ transaction(database) {
+ AccountIdentifiers
+ .selectAll().where { AccountIdentifiers.identifier eq identifier.accountIdentifierName }
+ .map { it[userId].toString() }
+ .firstOrNull() ?: throw IllegalStateException("Account not found")
+ }
+ }
+
+
+ override suspend fun hasStoredDataFor(
+ identifier: AccountIdentifier,
+ method: AuthenticationMethod
+ ): Boolean = withContext(Dispatchers.IO) {
+ transaction(database) {
+ val userId = AccountIdentifiers
+ .select(userId)
+ .map { it[userId] }
+ .firstOrNull() ?: return@transaction false
+
+ StoredData.selectAll().where {
+ (StoredData.accountId eq userId) and (StoredData.method eq method.id)
+ }.count() > 0
+ }
+ }
+
+ suspend fun createOrGetUserByPublicKey(publicKey: String): String = withContext(Dispatchers.IO) {
+ transaction(database) {
+ val existingUser = Users
+ .selectAll().where { Users.publicKey eq publicKey }
+ .map { it[Users.id].toString() }
+ .firstOrNull()
+
+ existingUser ?: Users.insert {
+ it[Users.publicKey] = publicKey
+ }[Users.id].toString()
+ }
+ }
+ }
+
+}
+
From f6783b17253482da498f11b02a0b6026c790add2 Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Mon, 13 Jan 2025 18:59:55 +0100
Subject: [PATCH 35/91] add tables for web3 auth
---
.../src/main/kotlin/id/walt/webwallet/db/Db.kt | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt
index 85fc3a380..6f49657b5 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt
@@ -6,6 +6,9 @@ import id.walt.commons.config.ConfigManager
import id.walt.webwallet.config.DatasourceConfiguration
import id.walt.webwallet.db.models.*
import id.walt.webwallet.service.account.AccountsService
+import id.walt.webwallet.service.account.authnz.AccountIdentifiers
+import id.walt.webwallet.service.account.authnz.StoredData
+import id.walt.webwallet.service.account.authnz.Users
import id.walt.webwallet.web.model.EmailAccountRequest
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.runBlocking
@@ -81,7 +84,7 @@ object Db {
SchemaUtils.drop(*(tables.reversedArray()))
SchemaUtils.create(*tables)
-
+ SchemaUtils.create(Users, AccountIdentifiers, StoredData)
runBlocking {
AccountsService.register(request = EmailAccountRequest("Max Mustermann", "string@string.string", "string"))
From a6d166d07b273de174155da153842805a308c920 Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Mon, 13 Jan 2025 19:00:38 +0100
Subject: [PATCH 36/91] use editableAccountStore when
ktorAuthnzAuthenticationFeature enabled
---
.../src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt
index bee13e592..5b69252db 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt
@@ -13,6 +13,7 @@ import id.walt.webwallet.config.AuthConfig
import id.walt.webwallet.config.KtorAuthnzConfig
import id.walt.webwallet.service.OidcLoginService
import id.walt.webwallet.service.WalletServiceManager.oidcConfig
+import id.walt.webwallet.service.account.authnz.AuthenticationService
import id.walt.webwallet.web.controllers.auth.*
import id.walt.webwallet.web.model.EmailAccountRequest
import id.walt.webwallet.web.model.KeycloakAccountRequest
@@ -97,7 +98,7 @@ fun Application.configureSecurity() {
val walletAuthenticationPluginAmendment: suspend () -> Unit = suspend {
if (FeatureManager.isFeatureEnabled(FeatureCatalog.ktorAuthnzAuthenticationFeature)) {
- //KtorAuthnzManager.accountStore = AuthenticationService.editableAccountStore
+ KtorAuthnzManager.accountStore = AuthenticationService().editableAccountStore
val config = ConfigManager.getConfig()
val configSigningKey = config.configuredSigningKey
From 896eaa7e6a6d58e4267b1a04721b5b8178dcdc2c Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Mon, 13 Jan 2025 19:01:07 +0100
Subject: [PATCH 37/91] fix AuthenticationService.kt
---
.../account/authnz/AuthenticationService.kt | 52 +++++++++----------
1 file changed, 25 insertions(+), 27 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
index ba69d0d69..0bf14d007 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
@@ -1,11 +1,17 @@
-import AccountIdentifiers.userId
+package id.walt.webwallet.service.account.authnz
+
import id.walt.ktorauthnz.accounts.EditableAccountStore
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
import id.walt.ktorauthnz.methods.AuthenticationMethod
import id.walt.ktorauthnz.methods.data.AuthMethodStoredData
+import id.walt.webwallet.service.account.authnz.AccountIdentifiers.userId
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-import org.jetbrains.exposed.sql.*
+import kotlinx.serialization.json.Json
+import org.jetbrains.exposed.sql.Table
+import org.jetbrains.exposed.sql.insert
+import org.jetbrains.exposed.sql.json.json
+import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
import java.util.*
import kotlin.uuid.ExperimentalUuidApi
@@ -31,20 +37,16 @@ object StoredData : Table() {
val id = uuid("id").autoGenerate()
val accountId = uuid("account_id").references(Users.id)
val method = varchar("method", 50)
- val data = text("data")
+ val data = json("data", Json, AuthMethodStoredData.serializer())
override val primaryKey = PrimaryKey(id)
}
@OptIn(ExperimentalUuidApi::class)
-class AuthenticationService(private val database: Database) {
+class AuthenticationService {
+
- init {
- transaction(database) {
- SchemaUtils.create(Users, AccountIdentifiers, StoredData)
- }
- }
val editableAccountStore = object : EditableAccountStore {
@@ -52,7 +54,7 @@ class AuthenticationService(private val database: Database) {
accountId: String,
newAccountIdentifier: AccountIdentifier
): Unit = withContext(Dispatchers.IO) {
- transaction(database) {
+ transaction {
AccountIdentifiers.insert {
it[userId] = UUID.fromString(accountId)
it[identifier] = newAccountIdentifier.accountIdentifierName
@@ -70,7 +72,8 @@ class AuthenticationService(private val database: Database) {
method: String,
data: AuthMethodStoredData
): Unit = withContext(Dispatchers.IO) {
- transaction(database) {
+ val savableStoredData = data.transformSavable()
+ transaction {
val userId = AccountIdentifiers
.select(userId)
.where { AccountIdentifiers.identifier eq accountIdentifier.accountIdentifierName }
@@ -80,25 +83,25 @@ class AuthenticationService(private val database: Database) {
StoredData.insert {
it[accountId] = userId
it[StoredData.method] = method
- it[StoredData.data] = data.toString()
+ it[StoredData.data] = savableStoredData
}
- Unit
}
}
+
override suspend fun addAccountStoredData(
accountId: String,
method: String,
data: AuthMethodStoredData
): Unit = withContext(Dispatchers.IO) {
- transaction(database) {
+ val savableStoredData = data.transformSavable()
+ transaction {
StoredData.insert {
it[StoredData.accountId] = UUID.fromString(accountId)
it[StoredData.method] = method
- it[StoredData.data] = data.toString()
+ it[StoredData.data] = savableStoredData
}
- Unit
}
}
@@ -146,7 +149,7 @@ class AuthenticationService(private val database: Database) {
override suspend fun lookupAccountUuid(identifier: AccountIdentifier): String =
withContext(Dispatchers.IO) {
- transaction(database) {
+ transaction {
AccountIdentifiers
.selectAll().where { AccountIdentifiers.identifier eq identifier.accountIdentifierName }
.map { it[userId].toString() }
@@ -159,20 +162,15 @@ class AuthenticationService(private val database: Database) {
identifier: AccountIdentifier,
method: AuthenticationMethod
): Boolean = withContext(Dispatchers.IO) {
- transaction(database) {
- val userId = AccountIdentifiers
- .select(userId)
- .map { it[userId] }
- .firstOrNull() ?: return@transaction false
-
- StoredData.selectAll().where {
- (StoredData.accountId eq userId) and (StoredData.method eq method.id)
- }.count() > 0
+ transaction {
+ StoredData
+ .selectAll().where { StoredData.method eq method.toString() }
+ .count() > 0
}
}
suspend fun createOrGetUserByPublicKey(publicKey: String): String = withContext(Dispatchers.IO) {
- transaction(database) {
+ transaction {
val existingUser = Users
.selectAll().where { Users.publicKey eq publicKey }
.map { it[Users.id].toString() }
From 3a410d6f831cee48747a94df4eefef0194b18a07 Mon Sep 17 00:00:00 2001
From: Hoan Hoang
Date: Mon, 13 Jan 2025 22:43:25 +0100
Subject: [PATCH 38/91] Fix path processing logic in addToMdocRequest
---
.../id/walt/oid4vc/data/dif/InputDescriptorField.kt | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/waltid-libraries/protocols/waltid-openid4vc/src/commonMain/kotlin/id/walt/oid4vc/data/dif/InputDescriptorField.kt b/waltid-libraries/protocols/waltid-openid4vc/src/commonMain/kotlin/id/walt/oid4vc/data/dif/InputDescriptorField.kt
index 7db6738df..a912c75fc 100644
--- a/waltid-libraries/protocols/waltid-openid4vc/src/commonMain/kotlin/id/walt/oid4vc/data/dif/InputDescriptorField.kt
+++ b/waltid-libraries/protocols/waltid-openid4vc/src/commonMain/kotlin/id/walt/oid4vc/data/dif/InputDescriptorField.kt
@@ -28,10 +28,11 @@ data class InputDescriptorField(
}
fun addToMdocRequest(mDocRequestBuilder: MDocRequestBuilder, intentToRetain: Boolean = false): MDocRequestBuilder {
- path.firstOrNull()?.trimStart('$')?.replace("['", "")?.replace("']", ".")?.trimEnd('.')?.split('.')
- ?.also { pathSegments ->
- mDocRequestBuilder.addDataElementRequest(pathSegments.first(), pathSegments.last(), intentToRetain)
- }
+ path.firstOrNull()?.trimStart('$')?.replace("['", "")?.replace("']", ".")?.trimEnd('.')
+ ?.let { it.substringBeforeLast('.') to it.substringAfterLast('.') }
+ ?.also { (namespace, lastSegment) ->
+ mDocRequestBuilder.addDataElementRequest(namespace, lastSegment, intentToRetain)
+ }
return mDocRequestBuilder
}
}
From c0a1477d418e834c06be50f8755f29e3ded6f66c Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Tue, 14 Jan 2025 05:27:19 +0100
Subject: [PATCH 39/91] Major work on web3 login
---
.../waltid-dev-wallet/src/pages/login.vue | 919 +++++++++---------
.../walt/ktorauthnz/accounts/AccountStore.kt | 2 +-
.../identifiers/methods/AccountIdentifier.kt | 3 +-
.../identifiers/methods/Web3Identifier.kt | 11 +-
.../AuthMethodFunctionAmendments.kt | 5 +
.../methods/AuthenticationMethod.kt | 27 +-
.../id/walt/ktorauthnz/methods/EmailPass.kt | 6 +-
.../kotlin/id/walt/ktorauthnz/methods/JWT.kt | 6 +-
.../kotlin/id/walt/ktorauthnz/methods/LDAP.kt | 6 +-
.../kotlin/id/walt/ktorauthnz/methods/OIDC.kt | 6 +-
.../id/walt/ktorauthnz/methods/RADIUS.kt | 6 +-
.../kotlin/id/walt/ktorauthnz/methods/TOTP.kt | 6 +-
.../id/walt/ktorauthnz/methods/UserPass.kt | 6 +-
.../methods/VerifiableCredential.kt | 6 +-
.../kotlin/id/walt/ktorauthnz/methods/Web3.kt | 170 +++-
.../methods/virtual/GlobalIdentify.kt | 6 +-
.../src/test/kotlin/id/walt/ExampleWeb.kt | 10 +-
.../waltid-wallet-api/config/_features.conf | 3 +-
.../waltid-wallet-api/config/ktor-authnz.conf | 2 +
.../waltid-wallet-api/config/web.conf | 2 +-
.../id/walt/webwallet/FeatureCatalog.kt | 2 +
.../src/main/kotlin/id/walt/webwallet/Main.kt | 2 +
.../walt/webwallet/config/KtorAuthnzConfig.kt | 4 +-
.../main/kotlin/id/walt/webwallet/db/Db.kt | 12 +-
.../models/authnz/AuthnzAccountIdentifiers.kt | 12 +
.../db/models/authnz/AuthnzStoredData.kt | 15 +
.../webwallet/db/models/authnz/AuthnzUsers.kt | 9 +
.../account/authnz/AuthenticationService.kt | 96 +-
.../controllers/auth/KtorAuthnzController.kt | 25 +-
.../auth/KtorAuthnzFrontendController.kt | 69 ++
.../id/walt/webwallet/web/plugins/Security.kt | 4 +-
31 files changed, 869 insertions(+), 589 deletions(-)
create mode 100644 waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/amendmends/AuthMethodFunctionAmendments.kt
create mode 100644 waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzAccountIdentifiers.kt
create mode 100644 waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzStoredData.kt
create mode 100644 waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzUsers.kt
create mode 100644 waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
index 3594161d4..3303153a2 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
@@ -1,45 +1,45 @@
-
-
-
-
-
![walt.id logo]()
-
-
- Sign in to your SSI wallet
-
-
- Or {{ " " }}
- sign up for your SSI wallet
-
+
+
+
+
![walt.id logo]()
+
+
+ Sign in to your SSI wallet
+
+
+ Or {{ " " }}
+ sign up for your SSI wallet
+
+ !
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
![]()
+
+
+
+
+
+
+
-
-
-
-
![]()
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
+
+
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/AccountStore.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/AccountStore.kt
index 1afde5c4d..ced8c7409 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/AccountStore.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/AccountStore.kt
@@ -13,7 +13,7 @@ interface AccountStore {
/**
* Resolve account uuid for account identifier
*/
- suspend fun lookupAccountUuid(identifier: AccountIdentifier): String
+ suspend fun lookupAccountUuid(identifier: AccountIdentifier): String?
suspend fun hasStoredDataFor(identifier: AccountIdentifier, method: AuthenticationMethod): Boolean
}
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/AccountIdentifier.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/AccountIdentifier.kt
index 68a7b0025..0c566576e 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/AccountIdentifier.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/AccountIdentifier.kt
@@ -25,7 +25,8 @@ sealed class AccountIdentifier {
return true
}
- suspend fun resolveToAccountId() = KtorAuthnzManager.accountStore.lookupAccountUuid(this)
+ suspend fun resolveToAccountId() = KtorAuthnzManager.accountStore.lookupAccountUuid(this) ?: throw IllegalStateException("Account does not exist")
+ suspend fun resolveIfExists() = KtorAuthnzManager.accountStore.lookupAccountUuid(this)
abstract class AccountIdentifierFactory
(val identifierName: String) {
abstract fun fromAccountIdentifierDataString(dataString: String): T
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/Web3Identifier.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/Web3Identifier.kt
index 011a46d16..6964933d4 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/Web3Identifier.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/accounts/identifiers/methods/Web3Identifier.kt
@@ -6,16 +6,15 @@ import kotlinx.serialization.Serializable
@Serializable
@SerialName("web3")
data class Web3Identifier(
- val publicKey: String
+ val address: String
) : AccountIdentifier() {
- override fun identifierName() = "web3" // SerialName and identifierName should match
+ override fun identifierName() = "web3"
- override fun toDataString() = publicKey // what is part of this identifier? In this case just the string "publicKey"
+ override fun toDataString() = address
- companion object :
- AccountIdentifierFactory("web3") { // this creator id also has to match with identifierName
+ companion object : AccountIdentifierFactory("web3") {
override fun fromAccountIdentifierDataString(dataString: String) = Web3Identifier(dataString)
- val EXAMPLE = Web3Identifier("0xABCDEF0123456789") // Define a nice example for the docs
+ val EXAMPLE = Web3Identifier("0xABCDEF0123456789")
}
}
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/amendmends/AuthMethodFunctionAmendments.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/amendmends/AuthMethodFunctionAmendments.kt
new file mode 100644
index 000000000..7c61fdfa5
--- /dev/null
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/amendmends/AuthMethodFunctionAmendments.kt
@@ -0,0 +1,5 @@
+package id.walt.ktorauthnz.amendmends
+
+enum class AuthMethodFunctionAmendments {
+ Registration
+}
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/AuthenticationMethod.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/AuthenticationMethod.kt
index 94452d58d..8a51db578 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/AuthenticationMethod.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/AuthenticationMethod.kt
@@ -3,6 +3,7 @@ package id.walt.ktorauthnz.methods
import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.KtorAuthnzManager
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.methods.config.AuthMethodConfiguration
import id.walt.ktorauthnz.methods.data.AuthMethodStoredData
import id.walt.ktorauthnz.sessions.AuthSession
@@ -35,7 +36,10 @@ abstract class AuthenticationMethod(open val id: String) {
// Auth
/** Login routes */
- abstract fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext)
+ abstract fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>? = null
+ )
/**
* Helper function, called when login was successful, will handle the proceeding actions.
@@ -64,21 +68,21 @@ abstract class AuthenticationMethod(open val id: String) {
* - authentication and registration has to be a combined step ([authenticationHandlesRegistration] set to true), or
* - automatic registration routes have to be provided ([registerRegistrationRoutes] implemented)
*/
-// abstract val supportsRegistration: Boolean
+ open val supportsRegistration: Boolean = false
/**
* Is login and registration a combined step (e.g.: most signature-based challenge-response methods)?
* -> in this case, no separate registration routes ([registerRegistrationRoutes]) are needed.
*/
-// open val authenticationHandlesRegistration: Boolean = false
+ open val authenticationHandlesRegistration: Boolean = supportsRegistration
/**
* Automatic registration routes (if this method supports automatic registration routes), requires:
* - [supportsRegistration] does this method support automatic registration (set to true)
* - [authenticationHandlesRegistration] Login & registration is not a combined step (set to false)
*/
-/* open fun Route.registerRegistrationRoutes(authContext: PipelineContext.() -> AuthContext): Unit =
- throw NotImplementedError("Authentication method ${this::class.simpleName} does not offer registration routes. Authentication routes handle registration: $authenticationHandlesRegistration")*/
+ open fun Route.registerRegistrationRoutes(authContext: PipelineContext.() -> AuthContext): Unit =
+ throw NotImplementedError("Authentication method ${this::class.simpleName} does not offer registration routes. Authentication routes handle registration: $authenticationHandlesRegistration")
// Data functions
@@ -117,20 +121,21 @@ abstract class AuthenticationMethod(open val id: String) {
fun Route.registerAuthenticationMethod(
method: AuthenticationMethod,
authContext: PipelineContext.() -> AuthContext,
-
- ) {
+ functionAmendments: Map Unit>? = null
+) {
method.apply {
- registerAuthenticationRoutes(authContext)
+ registerAuthenticationRoutes(authContext, functionAmendments)
}
}
fun Route.registerAuthenticationMethods(
methods: List,
authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>>? = null
) {
- methods.forEach {
- it.apply {
- registerAuthenticationRoutes(authContext)
+ methods.forEach { method ->
+ method.apply {
+ registerAuthenticationRoutes(authContext, functionAmendments?.get(method))
}
}
}
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/EmailPass.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/EmailPass.kt
index 44ce987c4..92fbea279 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/EmailPass.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/EmailPass.kt
@@ -4,6 +4,7 @@ import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.KtorAuthnzManager
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
import id.walt.ktorauthnz.accounts.identifiers.methods.EmailIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authCheck
import id.walt.ktorauthnz.methods.data.EmailPassStoredData
import id.walt.ktorauthnz.security.PasswordHash
@@ -60,7 +61,10 @@ object EmailPass : UserPassBasedAuthMethod("email", usernameName = "email") {
@Serializable
data class EmailPassCredentials(val email: String, val password: String)
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
post("emailpass", {
request { body() }
response { HttpStatusCode.OK to { body() } }
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/JWT.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/JWT.kt
index 353ea3577..3c90869d6 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/JWT.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/JWT.kt
@@ -4,6 +4,7 @@ import com.nimbusds.jose.JWSObject
import com.nimbusds.jose.crypto.MACVerifier
import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.accounts.identifiers.methods.JWTIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authCheck
import id.walt.ktorauthnz.methods.config.JwtAuthConfiguration
import id.walt.ktorauthnz.sessions.AuthSessionInformation
@@ -28,7 +29,10 @@ object JWT : AuthenticationMethod("jwt") {
return JWTIdentifier(id)
}
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
post("jwt", {
request { body() }
response { HttpStatusCode.OK to { body() } }
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/LDAP.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/LDAP.kt
index a6af534fc..f4b5c70c7 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/LDAP.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/LDAP.kt
@@ -3,6 +3,7 @@ package id.walt.ktorauthnz.methods
import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
import id.walt.ktorauthnz.accounts.identifiers.methods.LDAPIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authFailure
import id.walt.ktorauthnz.methods.config.LDAPConfiguration
import id.walt.ktorauthnz.sessions.AuthSession
@@ -43,7 +44,10 @@ object LDAP : UserPassBasedAuthMethod("ldap") {
}
}
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
post("ldap", {
request { body() }
response { HttpStatusCode.OK to { body() } }
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/OIDC.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/OIDC.kt
index d3a9b00c7..879dca440 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/OIDC.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/OIDC.kt
@@ -2,6 +2,7 @@ package id.walt.ktorauthnz.methods
import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.accounts.identifiers.methods.OIDCIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.methods.config.OidcAuthConfiguration
import io.github.smiley4.ktorswaggerui.dsl.routing.route
import io.ktor.client.*
@@ -149,7 +150,10 @@ object OIDC : AuthenticationMethod("oidc") {
}.body()
}
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
route("oidc") {
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/RADIUS.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/RADIUS.kt
index c9e733d0a..0e3ac948a 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/RADIUS.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/RADIUS.kt
@@ -3,6 +3,7 @@ package id.walt.ktorauthnz.methods
import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
import id.walt.ktorauthnz.accounts.identifiers.methods.RADIUSIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authCheck
import id.walt.ktorauthnz.methods.config.RADIUSConfiguration
import id.walt.ktorauthnz.sessions.AuthSession
@@ -54,7 +55,10 @@ object RADIUS : UserPassBasedAuthMethod("radius") {
}
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
post("radius", {
request { body() }
response { HttpStatusCode.OK to { body() } }
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/TOTP.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/TOTP.kt
index a4a84cec8..75585efcf 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/TOTP.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/TOTP.kt
@@ -7,6 +7,7 @@ import com.atlassian.onetime.model.Issuer
import com.atlassian.onetime.model.TOTPSecret
import com.atlassian.onetime.service.DefaultTOTPService
import id.walt.ktorauthnz.AuthContext
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authCheck
import id.walt.ktorauthnz.methods.data.TOTPStoredData
import id.walt.ktorauthnz.sessions.AuthSession
@@ -38,7 +39,10 @@ object TOTP : AuthenticationMethod("totp") {
@Serializable
data class TOTPCode(val code: String)
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
post("totp", {
request { body() }
response { HttpStatusCode.OK to { body() } }
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/UserPass.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/UserPass.kt
index 561573768..b77c21577 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/UserPass.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/UserPass.kt
@@ -4,6 +4,7 @@ import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.KtorAuthnzManager
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
import id.walt.ktorauthnz.accounts.identifiers.methods.UsernameIdentifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authCheck
import id.walt.ktorauthnz.methods.data.UserPassStoredData
import id.walt.ktorauthnz.security.PasswordHash
@@ -42,7 +43,10 @@ object UserPass : UserPassBasedAuthMethod("userpass") {
return identifier
}
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
post("userpass", {
request { body() }
response { HttpStatusCode.OK to { body() } }
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/VerifiableCredential.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/VerifiableCredential.kt
index 97ea09874..23c04c5ca 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/VerifiableCredential.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/VerifiableCredential.kt
@@ -3,6 +3,7 @@ package id.walt.ktorauthnz.methods
import com.nfeld.jsonpathkt.JsonPath
import com.nfeld.jsonpathkt.kotlinx.resolveAsStringOrNull
import id.walt.ktorauthnz.AuthContext
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.methods.config.VerifiableCredentialAuthConfiguration
import io.github.smiley4.ktorswaggerui.dsl.routing.route
import io.ktor.client.*
@@ -31,7 +32,10 @@ object VerifiableCredential : AuthenticationMethod("vc") {
// TODO:
val verifierUrl = "http://localhost:7003"
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
route("vc", {
}) {
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/Web3.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/Web3.kt
index 78697efa5..5a35ce4ce 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/Web3.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/Web3.kt
@@ -5,10 +5,12 @@ import id.walt.crypto.keys.jwk.JWKKey
import id.walt.crypto.utils.JwsUtils.decodeJws
import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.accounts.identifiers.methods.Web3Identifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.exceptions.authCheck
import id.walt.ktorauthnz.exceptions.authFailure
import id.walt.ktorauthnz.tokens.jwttoken.JwtTokenHandler
import io.github.smiley4.ktorswaggerui.dsl.routing.post
+import io.klogging.logger
import io.ktor.server.application.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
@@ -25,9 +27,11 @@ import java.math.BigInteger
import java.security.SecureRandom
+@OptIn(ExperimentalStdlibApi::class)
object Web3 : AuthenticationMethod("web3") {
- private val jwtHandler = JwtTokenHandler().apply {
+ private val log = logger()
+ private val jwtHandler = JwtTokenHandler().apply {
signingKey = runBlocking { JWKKey.generate(KeyType.Ed25519) }
verificationKey = signingKey
}
@@ -44,9 +48,11 @@ object Web3 : AuthenticationMethod("web3") {
}.toString().toByteArray()
return jwtHandler.signingKey.signJws(payload)
-
}
+ override val supportsRegistration = true
+ override val authenticationHandlesRegistration = true
+
@Serializable
data class SiweRequest(
val challenge: String,
@@ -54,21 +60,7 @@ object Web3 : AuthenticationMethod("web3") {
val publicKey: String
)
- fun verifySiwe(siwe: SiweRequest): String {
- val decodedJwt = siwe.challenge.decodeJws()
- val jwtPayload = decodedJwt.payload.jsonObject
-
- val nonce = jwtPayload["nonce"]?.jsonPrimitive?.content
- ?: authFailure("No nonce in token")
-
- val exp = jwtPayload["exp"]?.jsonPrimitive?.long
- ?: authFailure("No exp in token")
-
- val now = Clock.System.now().epochSeconds
- if (now > exp) {
- authFailure("Token expired")
- }
-
+ suspend fun verifyEthereum2(nonce: String, signature: String, expectedAddress: String): String {
// formatting the message according to the EIP-191 standard
val prefix = "\u0019Ethereum Signed Message:\n"
val messageLength = nonce.length.toString()
@@ -77,7 +69,7 @@ object Web3 : AuthenticationMethod("web3") {
val messageHash = Sign.getEthereumMessageHash(prefixedMessage.toByteArray())
// Parse signature components
- val signatureBytes = Numeric.hexStringToByteArray(siwe.signed.removePrefix("0x"))
+ val signatureBytes = Numeric.hexStringToByteArray(signature.removePrefix("0x"))
val r = BigInteger(1, signatureBytes.copyOfRange(0, 32))
val s = BigInteger(1, signatureBytes.copyOfRange(32, 64))
@@ -98,16 +90,135 @@ object Web3 : AuthenticationMethod("web3") {
val recoveredAddress = "0x" + Keys.getAddress(recoveredKey)
- authCheck(recoveredAddress.equals(siwe.publicKey, ignoreCase = true)) {
- "Recovered address ($recoveredAddress) does not match provided address (${siwe.publicKey})"
+ authCheck(recoveredAddress.equals(expectedAddress, ignoreCase = true)) {
+ "Recovered address ($recoveredAddress) does not match provided address (${expectedAddress})"
}
return recoveredAddress
}
+ suspend fun verifyEthereum(nonce: String, signature: String, expectedAddress: String): String {
+ log.trace { "Provided signature (hex): $signature" }
+
+ // Step 1: Compute the Ethereum message hash
+ log.trace { "Challenge nonce: $nonce" }
+ val messageHashX = Sign.getEthereumMessageHash(nonce.toByteArray())
+
+ val prefix = "\u0019Ethereum Signed Message:\n"
+ val prefixedMessage = prefix + nonce.length.toString() + nonce
+ val messageHash = Sign.getEthereumMessageHash(prefixedMessage.toByteArray())
+
+ log.trace { "Unprefixed message hash: ${messageHashX.toHexString()}" }
+ log.trace { "Prefixed message hash : ${messageHash.toHexString()}" }
+
+ log.trace { "Ethereum hash (hex) for challenge nonce: ${messageHash.toHexString()}" }
+
+ // Step 2: Decode the signature
+ val signatureBytes = Numeric.hexStringToByteArray(signature)
+ if (signatureBytes.size != 65) throw IllegalArgumentException("Invalid signature length")
+
+ val r = signatureBytes.copyOfRange(0, 32)
+ val s = signatureBytes.copyOfRange(32, 64)
+ val v = signatureBytes[64].toInt() and 0xFF
+
+ // Adjust `v` value to Ethereum standard (27 or 28)
+ val vCorrected = if (v < 27) v + 27 else v
+ log.trace { "Original v: $v, corrected v: $vCorrected" }
+
+
+ // Step 3: Recover the public key from the signature
+ val signatureData = Sign.SignatureData(vCorrected.toByte(), r, s)
+ log.trace { "Decoded signature, getting public key from signature..." }
+
+ val publicKey: BigInteger = try {
+ Sign.signedMessageToKey(messageHash, signatureData)
+ } catch (e: Exception) {
+ throw IllegalArgumentException("Invalid signature", e)
+ }
+
+ // Step 4: Derive the Ethereum address from the public key
+ val recoveredAddress = "0x" + Keys.getAddress(publicKey)
+ log.trace { "Recovered address from challenge signature: $recoveredAddress" }
+
+ // Step 5: Compare the recovered address to the expected address
+ authCheck(recoveredAddress.equals(expectedAddress, ignoreCase = true)) {
+ "Recovered address ($recoveredAddress) does not match provided address (${expectedAddress})"
+ }
+ log.trace { "Recovered address ($recoveredAddress) matches expected address." }
+
+ return recoveredAddress
+ }
+
+ suspend fun verifySiweLogin(siweReq: SiweRequest): String {
+ log.trace { "Verifying SIWE request: $siweReq" }
+
+ val challenge = siweReq.challenge
+ log.trace { "Challenge was: $challenge. Verifying challenge authenticity..." }
+
+ authCheck(jwtHandler.validateToken(challenge)) { "Cannot verify that nonce was supplied by system." }
+ log.trace { "Challenge is authentic. Verifying challenge timestamp..." }
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ val decodedJwt = challenge.decodeJws()
+ val jwtPayload = decodedJwt.payload.jsonObject
+
+ val nonce = jwtPayload["nonce"]?.jsonPrimitive?.content ?: authFailure("No nonce in token")
+ val exp = jwtPayload["exp"]?.jsonPrimitive?.long ?: authFailure("No exp in token")
+
+ val now = Clock.System.now().epochSeconds
+ if (now > exp) {
+ authFailure("Token expired")
+ }
+
+ log.trace { "Challenge did not yet expire. Verifying challenge signature..." }
+
+ val address = verifyEthereum2(nonce, siweReq.signed, siweReq.publicKey)
+ return address
+
+ /*// formatting the message according to the EIP-191 standard
+ val prefix = "\u0019Ethereum Signed Message:\n"
+ val messageLength = nonce.length.toString()
+ val prefixedMessage = prefix + messageLength + nonce
+
+ val messageHash = Sign.getEthereumMessageHash(prefixedMessage.toByteArray())
+
+ // Parse signature components
+ val signatureBytes = Numeric.hexStringToByteArray(siweReq.signed.removePrefix("0x"))
+ val r = signatureBytes.copyOfRange(0, 32)
+ val s = signatureBytes.copyOfRange(32, 64)
+ val vUncorrected = signatureBytes[64].toInt() and 0xFF
+
+ // Adjust `v` value to fit the Ethereum convention (27 or 28)
+ val v = if (vUncorrected < 27) vUncorrected + 27 else vUncorrected
+
+ val signatureData = Sign.SignatureData(v.toByte(), r, s)
+
+ val publicKey: BigInteger? = try {
+ Sign.signedMessageToKey(messageHash, signatureData)
+ } catch (e: Exception) {
+ null
+ }
+
+
+ val signature = ECDSASignature(r, s)
+
+ // Recover the public key
+ val recoveredPublicKey = Sign.recoverFromSignature(
+ v.toByte().toInt(), signature, messageHash
+ ) ?: authFailure("Could not recover public key from signature")
+
+
+ val recoveredAddress = "0x" + Keys.getAddress(recoveredPublicKey)
+
+ authCheck(recoveredAddress.equals(siweReq.publicKey, ignoreCase = true)) {
+ "Recovered address ($recoveredAddress) does not match provided address (${siweReq.publicKey})"
+ }*/
+ }
+
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
route("web3") {
get("nonce") {
val newNonce = makeNonce()
@@ -117,17 +228,18 @@ object Web3 : AuthenticationMethod("web3") {
post("signed", {
request { body() }
}) { req ->
-
val session = getSession(authContext)
- val account = verifySiwe(req)
+ val address = verifySiweLogin(req)
+
+ val identifier = Web3Identifier(address)
+ val identifierResolved = identifier.resolveIfExists()
- val identifier =
- Web3Identifier(account) // select identifier (= who logged in with this method now?)
+ if (identifierResolved == null) {
+ val registrationFunction = functionAmendments?.get(AuthMethodFunctionAmendments.Registration) ?: error("Missing registration function amendment for web3 method")
+ registrationFunction.invoke(identifier)
+ }
- context.handleAuthSuccess(
- session,
- identifier.resolveToAccountId()
- ) // handleAuthSuccess() -> session is now logged in
+ context.handleAuthSuccess(session, identifierResolved ?: identifier.resolveToAccountId())
}
}
}
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/virtual/GlobalIdentify.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/virtual/GlobalIdentify.kt
index 6a91c512d..79c784f1f 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/virtual/GlobalIdentify.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/methods/virtual/GlobalIdentify.kt
@@ -1,13 +1,17 @@
package id.walt.ktorauthnz.methods.virtual
import id.walt.ktorauthnz.AuthContext
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import io.ktor.server.application.*
import io.ktor.server.routing.*
import io.ktor.util.pipeline.*
object GlobalIdentify : IdentifyVirtualAuth("identify-global") {
- override fun Route.registerAuthenticationRoutes(authContext: PipelineContext.() -> AuthContext) {
+ override fun Route.registerAuthenticationRoutes(
+ authContext: PipelineContext.() -> AuthContext,
+ functionAmendments: Map Unit>?
+ ) {
throw NotImplementedError("This method is internally referenced and not to be used by the caller.")
}
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt
index 70f62d93b..c6f3cc7f3 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt
@@ -42,7 +42,7 @@ fun Route.globalMultistepExample() {
)
}
- registerAuthenticationMethod(Web3, contextFunction)
+ registerAuthenticationMethod(Web3, contextFunction, functionAmendments)
}
}
@@ -68,7 +68,7 @@ fun Route.globalImplicitSingleStep() {
)
}
- registerAuthenticationMethod(UserPass, contextFunction)
+ registerAuthenticationMethod(UserPass, contextFunction, functionAmendments)
}
}
@@ -96,9 +96,9 @@ fun Route.globalImplicitMultiStep() {
)
}
- registerAuthenticationMethod(UserPass, contextFunction)
+ registerAuthenticationMethod(UserPass, contextFunction, functionAmendments)
route("{sessionId}") {
- registerAuthenticationMethod(TOTP, contextFunction)
+ registerAuthenticationMethod(TOTP, contextFunction, functionAmendments)
}
}
}
@@ -165,7 +165,7 @@ fun Route.globalImplicitVc() {
)
}
- registerAuthenticationMethod(VerifiableCredential, contextFunction)
+ registerAuthenticationMethod(VerifiableCredential, contextFunction, functionAmendments)
}
diff --git a/waltid-services/waltid-wallet-api/config/_features.conf b/waltid-services/waltid-wallet-api/config/_features.conf
index 5db02e4aa..5d4d185b0 100644
--- a/waltid-services/waltid-wallet-api/config/_features.conf
+++ b/waltid-services/waltid-wallet-api/config/_features.conf
@@ -3,7 +3,8 @@ enabledFeatures = [
# trusted-ca,
# entra,
# ...
- ktor-authnz
+ ktor-authnz,
+ dev-mode
]
disabledFeatures = [
auth
diff --git a/waltid-services/waltid-wallet-api/config/ktor-authnz.conf b/waltid-services/waltid-wallet-api/config/ktor-authnz.conf
index 0a0fe8035..93957c032 100644
--- a/waltid-services/waltid-wallet-api/config/ktor-authnz.conf
+++ b/waltid-services/waltid-wallet-api/config/ktor-authnz.conf
@@ -22,6 +22,8 @@ authFlow = {
ok: true # Auth flow ends successfuly with this step
}
+cookieDomain = null
+
# If you previously used other (older) password hash algorithms, you
# can use this function to migrate old hashes to new hash algorithms. This
# works at login-time: When a user logs in with a password that uses a hash algorithm
diff --git a/waltid-services/waltid-wallet-api/config/web.conf b/waltid-services/waltid-wallet-api/config/web.conf
index 713d8a3ea..b49cb5e42 100644
--- a/waltid-services/waltid-wallet-api/config/web.conf
+++ b/waltid-services/waltid-wallet-api/config/web.conf
@@ -1,3 +1,3 @@
-webHost = "0.0.0.0"
+webHost = "localhost"
webPort = 7001
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/FeatureCatalog.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/FeatureCatalog.kt
index 1192af09e..7002393fb 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/FeatureCatalog.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/FeatureCatalog.kt
@@ -62,6 +62,8 @@ object FeatureCatalog : ServiceFeatureCatalog {
databaseFeature
)
override val optionalFeatures = listOf(
+ devModeFeature,
+
legacyAuthenticationFeature,
ktorAuthnzAuthenticationFeature,
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/Main.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/Main.kt
index 01f16e928..086f990ab 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/Main.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/Main.kt
@@ -16,6 +16,7 @@ import id.walt.webwallet.web.controllers.NotificationController.notifications
import id.walt.webwallet.web.controllers.PushController.push
import id.walt.webwallet.web.controllers.auth.defaultAuthRoutes
import id.walt.webwallet.web.controllers.auth.keycloak.keycloakAuthRoutes
+import id.walt.webwallet.web.controllers.auth.ktorAuthnzFrontendRoutes
import id.walt.webwallet.web.controllers.auth.ktorAuthnzRoutes
import id.walt.webwallet.web.controllers.auth.oidc.oidcAuthRoutes
import id.walt.webwallet.web.controllers.auth.x5c.x5cAuthRoutes
@@ -77,6 +78,7 @@ fun Application.webWalletModule(withPlugins: Boolean = true) {
{
ktorAuthnzRoutes()
+ ktorAuthnzFrontendRoutes()
} whenFeature FeatureCatalog.ktorAuthnzAuthenticationFeature
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/config/KtorAuthnzConfig.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/config/KtorAuthnzConfig.kt
index 92b7c4dd8..8a73c5df2 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/config/KtorAuthnzConfig.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/config/KtorAuthnzConfig.kt
@@ -39,7 +39,9 @@ data class KtorAuthnzConfig(
/** (waltid-crypto) Key for signing the login token */
val signingKey: JsonObject?,
/** (waltid-crypto) Key for verifying received login tokens */
- val verificationKey: JsonObject
+ val verificationKey: JsonObject,
+
+ val cookieDomain: String?
) {
val configuredSigningKey by lazy { signingKey?.let { KeyManager.resolveSerializedKeyBlocking(it.toString()) } }
val configuredVerificationKey by lazy { KeyManager.resolveSerializedKeyBlocking(verificationKey.toString()) }
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt
index 6f49657b5..cbac46d17 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/Db.kt
@@ -5,10 +5,10 @@ import com.zaxxer.hikari.HikariDataSource
import id.walt.commons.config.ConfigManager
import id.walt.webwallet.config.DatasourceConfiguration
import id.walt.webwallet.db.models.*
+import id.walt.webwallet.db.models.authnz.AuthnzAccountIdentifiers
+import id.walt.webwallet.db.models.authnz.AuthnzStoredData
+import id.walt.webwallet.db.models.authnz.AuthnzUsers
import id.walt.webwallet.service.account.AccountsService
-import id.walt.webwallet.service.account.authnz.AccountIdentifiers
-import id.walt.webwallet.service.account.authnz.StoredData
-import id.walt.webwallet.service.account.authnz.Users
import id.walt.webwallet.web.model.EmailAccountRequest
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.runBlocking
@@ -39,8 +39,8 @@ object Db {
log.info { "Will use sqlite database (${datasourceConfig.jdbcUrl}), working directory: ${Path(".").absolutePathString()}" }
}
- val hikariDataSourceConfig =runCatching {
- createHikariDataSource(datasourceConfig.dataSource)
+ val hikariDataSourceConfig = runCatching {
+ createHikariDataSource(datasourceConfig.dataSource)
}.getOrElse { ex ->
throw IllegalArgumentException("Could not initialize hikari database connection pool configuration: ${ex.message}", ex)
}
@@ -84,7 +84,7 @@ object Db {
SchemaUtils.drop(*(tables.reversedArray()))
SchemaUtils.create(*tables)
- SchemaUtils.create(Users, AccountIdentifiers, StoredData)
+ SchemaUtils.create(AuthnzUsers, AuthnzAccountIdentifiers, AuthnzStoredData)
runBlocking {
AccountsService.register(request = EmailAccountRequest("Max Mustermann", "string@string.string", "string"))
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzAccountIdentifiers.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzAccountIdentifiers.kt
new file mode 100644
index 000000000..2f2f3f9e3
--- /dev/null
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzAccountIdentifiers.kt
@@ -0,0 +1,12 @@
+package id.walt.webwallet.db.models.authnz
+
+import org.jetbrains.exposed.sql.Table
+
+object AuthnzAccountIdentifiers : Table() {
+ val id = uuid("id").autoGenerate()
+ val userId = uuid("user_id").references(AuthnzUsers.id)
+ val identifier = varchar("identifier", 255)
+ //val method = varchar("method", 50)
+
+ override val primaryKey = PrimaryKey(id)
+}
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzStoredData.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzStoredData.kt
new file mode 100644
index 000000000..af405b4bb
--- /dev/null
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzStoredData.kt
@@ -0,0 +1,15 @@
+package id.walt.webwallet.db.models.authnz
+
+import id.walt.ktorauthnz.methods.data.AuthMethodStoredData
+import kotlinx.serialization.json.Json
+import org.jetbrains.exposed.sql.Table
+import org.jetbrains.exposed.sql.json.json
+
+object AuthnzStoredData : Table() {
+ val id = uuid("id").autoGenerate()
+ val accountId = uuid("account_id").references(AuthnzUsers.id)
+ val method = varchar("method", 50)
+ val data = json("data", Json.Default, AuthMethodStoredData.serializer())
+
+ override val primaryKey = PrimaryKey(id)
+}
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzUsers.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzUsers.kt
new file mode 100644
index 000000000..5867da119
--- /dev/null
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/db/models/authnz/AuthnzUsers.kt
@@ -0,0 +1,9 @@
+package id.walt.webwallet.db.models.authnz
+
+import org.jetbrains.exposed.sql.Table
+
+object AuthnzUsers : Table() {
+ val id = uuid("id").autoGenerate()
+
+ override val primaryKey = PrimaryKey(id)
+}
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
index 0bf14d007..93acc1d32 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
@@ -4,60 +4,30 @@ import id.walt.ktorauthnz.accounts.EditableAccountStore
import id.walt.ktorauthnz.accounts.identifiers.methods.AccountIdentifier
import id.walt.ktorauthnz.methods.AuthenticationMethod
import id.walt.ktorauthnz.methods.data.AuthMethodStoredData
-import id.walt.webwallet.service.account.authnz.AccountIdentifiers.userId
+import id.walt.webwallet.db.models.authnz.AuthnzAccountIdentifiers
+import id.walt.webwallet.db.models.authnz.AuthnzAccountIdentifiers.userId
+import id.walt.webwallet.db.models.authnz.AuthnzStoredData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
-import kotlinx.serialization.json.Json
-import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.insert
-import org.jetbrains.exposed.sql.json.json
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
-import java.util.*
+import java.util.UUID
import kotlin.uuid.ExperimentalUuidApi
-object Users : Table() {
- val id = uuid("id").autoGenerate()
- val publicKey = varchar("public_key", 42).uniqueIndex() // Ethereum addresses are 42 chars including '0x'
-
- override val primaryKey = PrimaryKey(id)
-}
-
-object AccountIdentifiers : Table() {
- val id = uuid("id").autoGenerate()
- val userId = uuid("user_id").references(Users.id)
- val identifier = varchar("identifier", 255)
- val method = varchar("method", 50)
-
- override val primaryKey = PrimaryKey(id)
-}
-
-
-object StoredData : Table() {
- val id = uuid("id").autoGenerate()
- val accountId = uuid("account_id").references(Users.id)
- val method = varchar("method", 50)
- val data = json("data", Json, AuthMethodStoredData.serializer())
-
- override val primaryKey = PrimaryKey(id)
-}
-
-
@OptIn(ExperimentalUuidApi::class)
class AuthenticationService {
-
-
-
val editableAccountStore = object : EditableAccountStore {
override suspend fun addAccountIdentifierToAccount(
accountId: String,
newAccountIdentifier: AccountIdentifier
): Unit = withContext(Dispatchers.IO) {
transaction {
- AccountIdentifiers.insert {
- it[userId] = UUID.fromString(accountId)
- it[identifier] = newAccountIdentifier.accountIdentifierName
+ AuthnzAccountIdentifiers.insert {
+ it[AuthnzAccountIdentifiers.userId] = UUID.fromString(accountId)
+ it[AuthnzAccountIdentifiers.identifier] = newAccountIdentifier.accountIdentifierName
+ //it[AuthnzAccountIdentifiers.method] =
}
Unit // Explicitly return Unit
}
@@ -74,22 +44,21 @@ class AuthenticationService {
): Unit = withContext(Dispatchers.IO) {
val savableStoredData = data.transformSavable()
transaction {
- val userId = AccountIdentifiers
- .select(userId)
- .where { AccountIdentifiers.identifier eq accountIdentifier.accountIdentifierName }
- .singleOrNull()?.get(AccountIdentifiers.userId)
+ val userId = AuthnzAccountIdentifiers
+ .select(AuthnzAccountIdentifiers.userId)
+ .where { AuthnzAccountIdentifiers.identifier eq accountIdentifier.accountIdentifierName }
+ .singleOrNull()?.get(AuthnzAccountIdentifiers.userId)
?: throw IllegalStateException("Account not found")
- StoredData.insert {
+ AuthnzStoredData.insert {
it[accountId] = userId
- it[StoredData.method] = method
- it[StoredData.data] = savableStoredData
+ it[AuthnzStoredData.method] = method
+ it[AuthnzStoredData.data] = savableStoredData
}
}
}
-
override suspend fun addAccountStoredData(
accountId: String,
method: String,
@@ -97,10 +66,10 @@ class AuthenticationService {
): Unit = withContext(Dispatchers.IO) {
val savableStoredData = data.transformSavable()
transaction {
- StoredData.insert {
- it[StoredData.accountId] = UUID.fromString(accountId)
- it[StoredData.method] = method
- it[StoredData.data] = savableStoredData
+ AuthnzStoredData.insert {
+ it[AuthnzStoredData.accountId] = UUID.fromString(accountId)
+ it[AuthnzStoredData.method] = method
+ it[AuthnzStoredData.data] = savableStoredData
}
}
}
@@ -147,41 +116,26 @@ class AuthenticationService {
TODO("Not yet implemented")
}
- override suspend fun lookupAccountUuid(identifier: AccountIdentifier): String =
+ override suspend fun lookupAccountUuid(identifier: AccountIdentifier): String? =
withContext(Dispatchers.IO) {
transaction {
- AccountIdentifiers
- .selectAll().where { AccountIdentifiers.identifier eq identifier.accountIdentifierName }
+ AuthnzAccountIdentifiers
+ .selectAll().where { AuthnzAccountIdentifiers.identifier eq identifier.accountIdentifierName }
.map { it[userId].toString() }
- .firstOrNull() ?: throw IllegalStateException("Account not found")
+ .firstOrNull()
}
}
-
override suspend fun hasStoredDataFor(
identifier: AccountIdentifier,
method: AuthenticationMethod
): Boolean = withContext(Dispatchers.IO) {
transaction {
- StoredData
- .selectAll().where { StoredData.method eq method.toString() }
+ AuthnzStoredData
+ .selectAll().where { AuthnzStoredData.method eq method.toString() }
.count() > 0
}
}
-
- suspend fun createOrGetUserByPublicKey(publicKey: String): String = withContext(Dispatchers.IO) {
- transaction {
- val existingUser = Users
- .selectAll().where { Users.publicKey eq publicKey }
- .map { it[Users.id].toString() }
- .firstOrNull()
-
- existingUser ?: Users.insert {
- it[Users.publicKey] = publicKey
- }[Users.id].toString()
- }
- }
}
-
}
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt
index 156cd2cb6..0ace36389 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt
@@ -2,19 +2,40 @@ package id.walt.webwallet.web.controllers.auth
import id.walt.commons.config.ConfigManager
import id.walt.ktorauthnz.AuthContext
+import id.walt.ktorauthnz.KtorAuthnzManager
+import id.walt.ktorauthnz.accounts.identifiers.methods.Web3Identifier
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
import id.walt.ktorauthnz.methods.AuthMethodManager
import id.walt.ktorauthnz.methods.AuthenticationMethod
+import id.walt.ktorauthnz.methods.Web3
import id.walt.ktorauthnz.methods.registerAuthenticationMethod
import id.walt.webwallet.config.KtorAuthnzConfig
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments.*
+import id.walt.webwallet.db.models.authnz.AuthnzUsers
import io.github.smiley4.ktorswaggerui.dsl.routing.route
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
import io.ktor.util.pipeline.*
+import org.jetbrains.exposed.sql.insert
+import org.jetbrains.exposed.sql.transactions.transaction
private val authConfig = ConfigManager.getConfig()
private val flowConfig = authConfig.authFlow
+
+
+private val web3Registration: suspend (any: Any) -> Unit = { any ->
+ val identifier = any as? Web3Identifier ?: error("Provided argument is not web3 identifier")
+ val newAuthnzUserId = transaction { AuthnzUsers.insert{}[AuthnzUsers.id] }.toString()
+ KtorAuthnzManager.accountStore.addAccountIdentifierToAccount(newAuthnzUserId, identifier)
+}
+
+private val authMethodFunctionAmendments: Map Unit>> =
+ mapOf(
+ Web3 to mapOf(Registration to web3Registration)
+ )
+
fun Application.ktorAuthnzRoutes() {
routing {
route("auth", {
@@ -36,7 +57,9 @@ fun Application.ktorAuthnzRoutes() {
val methodId: String = flowConfig.method
val authenticationMethod: AuthenticationMethod = AuthMethodManager.getAuthenticationMethodById(methodId)
- registerAuthenticationMethod(authenticationMethod, contextFunction)
+ val functionAmendments = authMethodFunctionAmendments[authenticationMethod]
+
+ registerAuthenticationMethod(authenticationMethod, contextFunction, functionAmendments)
}
}
}
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt
new file mode 100644
index 000000000..dc72d8721
--- /dev/null
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt
@@ -0,0 +1,69 @@
+package id.walt.webwallet.web.controllers.auth
+
+import id.walt.commons.web.UnauthorizedException
+import id.walt.ktorauthnz.KtorAuthnzManager
+import id.walt.ktorauthnz.auth.getAuthenticatedAccount
+import id.walt.ktorauthnz.auth.getAuthenticatedSession
+import id.walt.webwallet.db.models.Account
+import id.walt.webwallet.web.plugins.KTOR_AUTHNZ_CONFIG_NAME
+import io.github.smiley4.ktorswaggerui.dsl.routing.get
+import io.github.smiley4.ktorswaggerui.dsl.routing.route
+import io.ktor.http.*
+import io.ktor.server.application.*
+import io.ktor.server.auth.*
+import io.ktor.server.request.*
+import io.ktor.server.response.*
+import io.ktor.server.routing.*
+import kotlinx.serialization.json.*
+
+fun Application.ktorAuthnzFrontendRoutes() {
+ routing {
+ route("/wallet-api/auth", {
+ tags("Frontend authentication")
+ }) {
+ authenticate(KTOR_AUTHNZ_CONFIG_NAME) {
+ get("user-info", {
+ summary = "Return user ID if logged in"
+ response {
+ HttpStatusCode.OK to {
+ body()
+ }
+ }
+ }) {
+ call.respond(getAuthenticatedAccount())
+ }
+ get("session", { summary = "Return session ID if logged in" }) {
+ val token = getAuthenticatedSession().token ?: throw UnauthorizedException("Invalid session")
+ call.respond(mapOf("token" to mapOf("accessToken" to token)))
+ }
+ }
+
+ post("login") { // also in authenticate {} block as it just relays authnz auth
+ //call.sessions.set(LoginTokenSession(token))
+
+ val providedToken = call.receiveText()
+ println("providedToken: $providedToken")
+
+ val (account, token) = if (providedToken.isNotEmpty()) {
+ val token = Json.decodeFromString(providedToken)["token"]?.jsonPrimitive?.content ?: error("Missing token")
+ val session = KtorAuthnzManager.tokenHandler.resolveTokenToSession(token)
+ val account = session.accountId
+ val sessionToken = session.token
+ account to sessionToken
+
+ } else {
+ val authenticatedAccount = getAuthenticatedAccount()
+ val authenticatedSessionToken = getAuthenticatedSession().token
+ authenticatedAccount to authenticatedSessionToken
+ }
+
+ context.respond(
+ buildJsonObject {
+ put("id", account)
+ put("token", token)
+ }
+ )
+ }
+ }
+ }
+}
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt
index 5b69252db..54943c48a 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/plugins/Security.kt
@@ -34,7 +34,7 @@ import kotlinx.serialization.json.JsonPrimitive
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.seconds
-private val KTOR_AUTHNZ_CONFIG_NAME: String? = null
+val KTOR_AUTHNZ_CONFIG_NAME: String? = null
val authConfigNames by lazy {
when {
@@ -112,7 +112,7 @@ val walletAuthenticationPluginAmendment: suspend () -> Unit = suspend {
}
val webConfig = ConfigManager.getConfig()
- SessionTokenCookieHandler.domain = webConfig.webHost
+ SessionTokenCookieHandler.domain = config.cookieDomain
// if not in dev mode, add extra cookie security:
if (!FeatureManager.isFeatureEnabled(FeatureCatalog.devModeFeature)) {
From b70ea4a1c3de5328492cd1583b2034c5fb36bbc8 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Tue, 14 Jan 2025 13:47:12 +0100
Subject: [PATCH 40/91] Fix tests (non-required argument)
---
.../src/test/kotlin/id/walt/ExampleWeb.kt | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt
index c6f3cc7f3..70f62d93b 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/test/kotlin/id/walt/ExampleWeb.kt
@@ -42,7 +42,7 @@ fun Route.globalMultistepExample() {
)
}
- registerAuthenticationMethod(Web3, contextFunction, functionAmendments)
+ registerAuthenticationMethod(Web3, contextFunction)
}
}
@@ -68,7 +68,7 @@ fun Route.globalImplicitSingleStep() {
)
}
- registerAuthenticationMethod(UserPass, contextFunction, functionAmendments)
+ registerAuthenticationMethod(UserPass, contextFunction)
}
}
@@ -96,9 +96,9 @@ fun Route.globalImplicitMultiStep() {
)
}
- registerAuthenticationMethod(UserPass, contextFunction, functionAmendments)
+ registerAuthenticationMethod(UserPass, contextFunction)
route("{sessionId}") {
- registerAuthenticationMethod(TOTP, contextFunction, functionAmendments)
+ registerAuthenticationMethod(TOTP, contextFunction)
}
}
}
@@ -165,7 +165,7 @@ fun Route.globalImplicitVc() {
)
}
- registerAuthenticationMethod(VerifiableCredential, contextFunction, functionAmendments)
+ registerAuthenticationMethod(VerifiableCredential, contextFunction)
}
From 1c4077b96766f6cd73eb7d79f1af2cfb67fb6859 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:02:32 +0100
Subject: [PATCH 41/91] - Login cookie was not correctly set - on local
run, API server and Frontend server are on different ports, thus different
hosts, so this was blocked by the browser. In production they are on the same
host, so it should work there - support auth.token in addition (set by
frontend auth lib), so to work in both cases
---
.../id/walt/ktorauthnz/auth/DefaultKtorAuthnzAuthentication.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/auth/DefaultKtorAuthnzAuthentication.kt b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/auth/DefaultKtorAuthnzAuthentication.kt
index 3106b8c39..ef7f26d86 100644
--- a/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/auth/DefaultKtorAuthnzAuthentication.kt
+++ b/waltid-libraries/auth/waltid-ktor-authnz/src/main/kotlin/id/walt/ktorauthnz/auth/DefaultKtorAuthnzAuthentication.kt
@@ -33,7 +33,7 @@ class DefaultKtorAuthnzAuthentication internal constructor(
val call = context.call
val ktorAuthnzHeader = call.request.headers.get("ktor-authnz-auth")
- val cookie = call.request.cookies.get("ktor-authnz-auth")
+ val cookie = call.request.cookies["ktor-authnz-auth"] ?: call.request.cookies["auth.token"]
val authHeader = call.request.headers[HttpHeaders.Authorization]?.removePrefix("Bearer ")
val effectiveToken = ktorAuthnzHeader ?: cookie ?: authHeader
From ecb75c740cc354fc635ada08baaf33b8cee9c259 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:02:51 +0100
Subject: [PATCH 42/91] Disable currently unavailable EBSI tests
---
.../src/jvmTest/kotlin/resolvers/DidEbsiResolverTest.kt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/waltid-libraries/waltid-did/src/jvmTest/kotlin/resolvers/DidEbsiResolverTest.kt b/waltid-libraries/waltid-did/src/jvmTest/kotlin/resolvers/DidEbsiResolverTest.kt
index 6ef0109c5..4a1359863 100644
--- a/waltid-libraries/waltid-did/src/jvmTest/kotlin/resolvers/DidEbsiResolverTest.kt
+++ b/waltid-libraries/waltid-did/src/jvmTest/kotlin/resolvers/DidEbsiResolverTest.kt
@@ -16,7 +16,7 @@ import java.util.stream.Stream
class DidEbsiResolverTest : DidResolverTestBase() {
override val resolver: LocalResolverMethod = DidEbsiResolver(HttpClient())
- @ParameterizedTest
+ // @ParameterizedTest // FIXME: did:ebsi server not available
@MethodSource
override fun `given a did String, when calling resolve, then the result is a valid did document`(
did: String, key: JsonObject, assert: resolverAssertion
@@ -24,7 +24,7 @@ class DidEbsiResolverTest : DidResolverTestBase() {
super.`given a did String, when calling resolve, then the result is a valid did document`(did, key, assert)
}
- @ParameterizedTest
+ // @ParameterizedTest // FIXME: did:ebsi server not available
@MethodSource
override fun `given a did String, when calling resolveToKey, then the result is valid key`(
did: String,
@@ -258,4 +258,4 @@ class DidEbsiResolverTest : DidResolverTestBase() {
)
}
-}
\ No newline at end of file
+}
From 08c19d4d04aeb4ea776615642903e9c1777ba920 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:03:36 +0100
Subject: [PATCH 43/91] Also automatically create wallet in
register-during-authenticate registrations
---
.../service/account/AccountsService.kt | 86 +++++++++----------
1 file changed, 39 insertions(+), 47 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/AccountsService.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/AccountsService.kt
index 710ae97d5..a5bf7691b 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/AccountsService.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/AccountsService.kt
@@ -30,34 +30,29 @@ import kotlin.uuid.toKotlinUuid
@OptIn(ExperimentalUuidApi::class)
object AccountsService {
- private suspend fun initializeUserAccount(tenant: String, name: String?, registrationResult: RegistrationResult) =
- let {
- val registeredUserId = registrationResult.id
-
- val createdInitialWalletId = transaction {
- WalletServiceManager.createWallet(tenant, registeredUserId)
- }
+ internal suspend fun initializeUserAccount(tenant: String = "", name: String?, registeredUserId: Uuid) {
+ val createdInitialWalletId = transaction {
+ WalletServiceManager.createWallet(tenant, registeredUserId)
+ }
- val walletService = WalletServiceManager.getWalletService(tenant, registeredUserId, createdInitialWalletId)
- (suspend {
- ConfigManager.getConfig()
- } whenFeatureSuspend (FeatureCatalog.registrationDefaultsFeature))?.run {
- tryAddDefaultData(walletService, this)
- }
- registrationResult.also {
- WalletServiceManager.eventUseCase.log(
- action = EventType.Account.Create,
- originator = "wallet",
- tenant = tenant,
- accountId = registeredUserId,
- walletId = createdInitialWalletId,
- data = AccountEventData(accountId = name)
- )
- }
+ val walletService = WalletServiceManager.getWalletService(tenant, registeredUserId, createdInitialWalletId)
+ (suspend {
+ ConfigManager.getConfig()
+ } whenFeatureSuspend (FeatureCatalog.registrationDefaultsFeature))?.run {
+ tryAddDefaultData(walletService, this)
}
+ WalletServiceManager.eventUseCase.log(
+ action = EventType.Account.Create,
+ originator = "wallet",
+ tenant = tenant,
+ accountId = registeredUserId,
+ walletId = createdInitialWalletId,
+ data = AccountEventData(accountId = name)
+ )
+ }
- suspend fun register(tenant: String = "", request: AccountRequest): Result = runCatching {
- when (request) {
+ suspend fun register(tenant: String = "", request: AccountRequest): Result {
+ val result = when (request) {
is EmailAccountRequest -> EmailAccountStrategy.register(tenant, request)
// is AddressAccountRequest -> Web3WalletAccountStrategy.register(tenant, request)
is OidcAccountRequest -> OidcAccountStrategy.register(tenant, request)
@@ -65,11 +60,8 @@ object AccountsService {
is OidcUniqueSubjectRequest -> OidcUniqueSubjectStrategy.register(tenant, request)
is X5CAccountRequest -> X5CAccountStrategy.register(tenant, request)
else -> throw NotImplementedError("unknown auth method")
- }.fold(onSuccess = {
- initializeUserAccount(tenant, request.name, it)
- }, onFailure = {
- throw it
- })
+ }
+ return result.also { initializeUserAccount(tenant, request.name, it.getOrThrow().id) }
}
@@ -100,23 +92,23 @@ object AccountsService {
AccountWalletListing(
account,
wallets =
- transaction {
- AccountWalletMappings.innerJoin(Wallets)
- .selectAll()
- .where {
- (AccountWalletMappings.tenant eq tenant) and
- (AccountWalletMappings.accountId eq account)
- }
- .map {
- AccountWalletListing.WalletListing(
- id = it[AccountWalletMappings.wallet].value.toKotlinUuid(),
- name = it[Wallets.name],
- createdOn = it[Wallets.createdOn].toKotlinInstant(),
- addedOn = it[AccountWalletMappings.addedOn].toKotlinInstant(),
- permission = it[AccountWalletMappings.permissions]
- )
- }
- })
+ transaction {
+ AccountWalletMappings.innerJoin(Wallets)
+ .selectAll()
+ .where {
+ (AccountWalletMappings.tenant eq tenant) and
+ (AccountWalletMappings.accountId eq account)
+ }
+ .map {
+ AccountWalletListing.WalletListing(
+ id = it[AccountWalletMappings.wallet].value.toKotlinUuid(),
+ name = it[Wallets.name],
+ createdOn = it[Wallets.createdOn].toKotlinInstant(),
+ addedOn = it[AccountWalletMappings.addedOn].toKotlinInstant(),
+ permission = it[AccountWalletMappings.permissions]
+ )
+ }
+ })
fun getAccountForWallet(wallet: Uuid) = transaction {
AccountWalletMappings.select(AccountWalletMappings.accountId)
From 1cac468ed3085a8f98125124f7d5de6a523f2efd Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:04:19 +0100
Subject: [PATCH 44/91] Use account name instead of account email for wallet
name
---
.../kotlin/id/walt/webwallet/service/WalletServiceManager.kt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/WalletServiceManager.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/WalletServiceManager.kt
index 3031d6b21..1d4d5ba2b 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/WalletServiceManager.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/WalletServiceManager.kt
@@ -179,7 +179,7 @@ object WalletServiceManager {
}
fun createWallet(tenant: String, forAccount: Uuid): Uuid {
- val accountName = AccountsService.get(forAccount).email ?: "wallet name not defined"
+ val accountName = AccountsService.get(forAccount).name ?: "wallet name not defined"
// TODO: remove testing code / lock behind dev-mode
if (accountName.contains("multi-wallet")) {
From edecafb313881ff659631ee210e67b5e49d725be Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:05:51 +0100
Subject: [PATCH 45/91] Update getUserUUID to support both legacy and authnz
auth, same for getWalletService
---
.../web/controllers/auth/AuthController.kt | 21 +++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/AuthController.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/AuthController.kt
index 0850c90e3..0fdefaccf 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/AuthController.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/AuthController.kt
@@ -9,12 +9,15 @@ import com.nimbusds.jose.Payload
import com.nimbusds.jose.crypto.MACSigner
import com.nimbusds.jose.crypto.MACVerifier
import id.walt.commons.config.ConfigManager
+import id.walt.commons.featureflag.FeatureManager
import id.walt.commons.web.ForbiddenException
import id.walt.commons.web.UnauthorizedException
import id.walt.commons.web.WebException
import id.walt.crypto.keys.jwk.JWKKey
import id.walt.crypto.utils.JsonUtils.toJsonElement
+import id.walt.ktorauthnz.auth.getAuthenticatedAccount
import id.walt.oid4vc.definitions.JWTClaims
+import id.walt.webwallet.FeatureCatalog
import id.walt.webwallet.config.AuthConfig
import id.walt.webwallet.db.models.AccountWalletMappings
import id.walt.webwallet.db.models.AccountWalletPermissions
@@ -31,6 +34,7 @@ import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.sessions.*
import io.ktor.util.pipeline.*
+import kotlinx.coroutines.runBlocking
import kotlinx.datetime.Clock
import kotlinx.datetime.toJavaInstant
import kotlinx.serialization.Serializable
@@ -162,9 +166,14 @@ fun PipelineContext.getUserId() =
?: call.principal() // bearer is registered with no name for some reason
?: throw UnauthorizedException("Could not find user authorization within request.")
-fun PipelineContext.getUserUUID() =
- runCatching { Uuid.parse(getUserId().name) }
- .getOrElse { throw IllegalArgumentException("Invalid user id: $it") }
+suspend fun PipelineContext.getUserUUID() =
+ runCatching {
+ when {
+ FeatureManager.isFeatureEnabled(FeatureCatalog.legacyAuthenticationFeature) -> Uuid.parse(getUserId().name)
+ FeatureManager.isFeatureEnabled(FeatureCatalog.ktorAuthnzAuthenticationFeature) -> Uuid.parse(getAuthenticatedAccount())
+ else -> error("No authentication feature enabled")
+ }
+ }.getOrElse { throw IllegalArgumentException("Invalid user id: $it") }
fun PipelineContext.getWalletId() =
runCatching {
@@ -174,10 +183,10 @@ fun PipelineContext.getWalletId() =
ensurePermissionsForWallet(AccountWalletPermissions.READ_ONLY, walletId = it)
}
-fun PipelineContext.getWalletService(walletId: Uuid) =
+suspend fun PipelineContext.getWalletService(walletId: Uuid) =
WalletServiceManager.getWalletService("", getUserUUID(), walletId) // FIXME -> TENANT HERE
-fun PipelineContext.getWalletService() =
+suspend fun PipelineContext.getWalletService() =
WalletServiceManager.getWalletService("", getUserUUID(), getWalletId()) // FIXME -> TENANT HERE
fun PipelineContext.getUsersSessionToken(): String? =
@@ -187,7 +196,7 @@ fun PipelineContext.getUsersSessionToken(): String? =
fun PipelineContext.ensurePermissionsForWallet(
required: AccountWalletPermissions,
- userId: Uuid = getUserUUID(),
+ userId: Uuid = runBlocking { getUserUUID() },
walletId: Uuid = getWalletId(),
): Boolean {
From 4be17a5ff45ec30ed8a61fc1925a336544c99ae6 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:06:55 +0100
Subject: [PATCH 46/91] Add account registration for web3Registration
---
.../controllers/auth/KtorAuthnzController.kt | 29 +++++++++++++++++--
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt
index 0ace36389..f99566de6 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzController.kt
@@ -1,3 +1,5 @@
+@file:OptIn(ExperimentalUuidApi::class)
+
package id.walt.webwallet.web.controllers.auth
import id.walt.commons.config.ConfigManager
@@ -5,30 +7,51 @@ import id.walt.ktorauthnz.AuthContext
import id.walt.ktorauthnz.KtorAuthnzManager
import id.walt.ktorauthnz.accounts.identifiers.methods.Web3Identifier
import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments
+import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments.Registration
import id.walt.ktorauthnz.methods.AuthMethodManager
import id.walt.ktorauthnz.methods.AuthenticationMethod
import id.walt.ktorauthnz.methods.Web3
import id.walt.ktorauthnz.methods.registerAuthenticationMethod
import id.walt.webwallet.config.KtorAuthnzConfig
-import id.walt.ktorauthnz.amendmends.AuthMethodFunctionAmendments.*
+import id.walt.webwallet.db.models.Accounts
import id.walt.webwallet.db.models.authnz.AuthnzUsers
+import id.walt.webwallet.service.account.AccountsService.initializeUserAccount
import io.github.smiley4.ktorswaggerui.dsl.routing.route
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
import io.ktor.util.pipeline.*
+import kotlinx.datetime.Clock
+import kotlinx.datetime.toJavaInstant
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.transactions.transaction
+import kotlin.uuid.ExperimentalUuidApi
+import kotlin.uuid.Uuid
private val authConfig = ConfigManager.getConfig()
private val flowConfig = authConfig.authFlow
-
private val web3Registration: suspend (any: Any) -> Unit = { any ->
val identifier = any as? Web3Identifier ?: error("Provided argument is not web3 identifier")
- val newAuthnzUserId = transaction { AuthnzUsers.insert{}[AuthnzUsers.id] }.toString()
+ val web3Address = identifier.address
+
+ val newAuthnzUserId = transaction { AuthnzUsers.insert {}[AuthnzUsers.id] }.toString()
+ val newAuthnzUserUuid = Uuid.parse(newAuthnzUserId)
+
+
KtorAuthnzManager.accountStore.addAccountIdentifierToAccount(newAuthnzUserId, identifier)
+
+ transaction {
+ val accountId = Accounts.insert {
+ it[tenant] = ""
+ it[id] = newAuthnzUserUuid
+ it[name] = web3Address
+ it[createdOn] = Clock.System.now().toJavaInstant()
+ }[Accounts.id]
+ }
+
+ initializeUserAccount(name = web3Address, registeredUserId = Uuid.parse(newAuthnzUserId))
}
private val authMethodFunctionAmendments: Map Unit>> =
From 485d1bfac0b5495fc9f8410cd1faf33edecdf090 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:07:10 +0100
Subject: [PATCH 47/91] Fix old JVM mismatch
---
waltid-services/waltid-wallet-api/build.gradle.kts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/build.gradle.kts b/waltid-services/waltid-wallet-api/build.gradle.kts
index cab5e2f66..36afe3a33 100644
--- a/waltid-services/waltid-wallet-api/build.gradle.kts
+++ b/waltid-services/waltid-wallet-api/build.gradle.kts
@@ -26,7 +26,7 @@ repositories {
tasks.withType {
compilerOptions {
- jvmTarget = JvmTarget.JVM_17
+ jvmTarget = JvmTarget.JVM_21
}
}
@@ -52,7 +52,7 @@ tasks.withType {
}*/
kotlin {
- jvmToolchain(17)
+ jvmToolchain(21)
}
dependencies {
From 5b0faacf796d741a3ef858b96fc8dbae6a419269 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:25:22 +0100
Subject: [PATCH 48/91] Allow setting generic name for user in frontend
(instead of just email)
---
.../src/layouts/default-reduced-nav.vue | 2 +-
.../waltid-demo-wallet/src/layouts/default.vue | 2 +-
.../src/layouts/desktop-without-sidebar.vue | 5 ++---
.../waltid-demo-wallet/src/layouts/desktop.vue | 2 +-
.../src/pages/wallet/[wallet]/profile.vue | 2 +-
.../src/layouts/default-reduced-nav.vue | 2 +-
.../apps/waltid-dev-wallet/src/layouts/default.vue | 2 +-
.../apps/waltid-dev-wallet/src/pages/login.vue | 14 +++++++-------
.../apps/waltid-dev-wallet/src/pages/profile.vue | 2 +-
.../libs/components/WalletPageHeader.vue | 2 +-
.../waltid-web-wallet/libs/stores/user.ts | 2 +-
11 files changed, 18 insertions(+), 19 deletions(-)
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/default-reduced-nav.vue b/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/default-reduced-nav.vue
index 4eb151936..f6460fed7 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/default-reduced-nav.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/default-reduced-nav.vue
@@ -234,7 +234,7 @@
{{ user.email }}{{ user.friendlyName }}
-->
{{ user.email }}{{ user.friendlyName }}
- {{ user.email
- }}
+ {{ user.friendlyName }}
@@ -88,4 +87,4 @@ const { user } = storeToRefs(userStore);
const currentWallet = useCurrentWallet()
const profileUrl = `/wallet/${currentWallet.value}/profile`
-
\ No newline at end of file
+
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/desktop.vue b/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/desktop.vue
index 477ba5b2d..26041ad6f 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/desktop.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-demo-wallet/src/layouts/desktop.vue
@@ -56,7 +56,7 @@
{{ user.email }}{{ user.friendlyName }}
- {{ user.email }}
+ {{ user.friendlyName }}
DID
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/layouts/default-reduced-nav.vue b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/layouts/default-reduced-nav.vue
index b11491e54..26c1879c0 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/layouts/default-reduced-nav.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/layouts/default-reduced-nav.vue
@@ -234,7 +234,7 @@
{{ user.email }}{{ user.friendlyName }}
-->
{{ user.email }}{{ user.friendlyName }}
{
+ .then(() =>{
user.value = {
id: "",
- email: userData.email
+ friendlyName: userData.email
};
})
.catch((err) => {
@@ -488,7 +488,7 @@ async function openWeb3() {
const result = await verificationResponse.json();
console.log("Verification result: ", result);
- await authnzLogin(result.token)
+ await authnzLogin(address, result.token)
}
definePageMeta({
@@ -521,7 +521,7 @@ if (route.redirectedFrom != undefined) {
const isOidcLogin = ref(route.query.oidc_login == "true");
-async function authnzLogin(token) {
+async function authnzLogin(address, token) {
console.log("authnz: logging in");
isLoggingIn.value = true;
@@ -535,10 +535,10 @@ async function authnzLogin(token) {
{ token: token /*email: emailInput, password: passwordInput, type: "email"*/ },
{ callbackUrl: signInRedirectUrl.value }
)
- .then((data) => {
+ .then(() => {
user.value = {
- id: ""
- // email: userData.email
+ id: "",
+ friendlyName: address
};
})
.catch((err) => {
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/profile.vue b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/profile.vue
index 496690dba..a68e28c48 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/profile.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/profile.vue
@@ -1,7 +1,7 @@
Profile
- Username: {{ user.email }}
+ Username: {{ user.friendlyName }}
diff --git a/waltid-applications/waltid-web-wallet/libs/components/WalletPageHeader.vue b/waltid-applications/waltid-web-wallet/libs/components/WalletPageHeader.vue
index 134cb92ae..79e98f034 100644
--- a/waltid-applications/waltid-web-wallet/libs/components/WalletPageHeader.vue
+++ b/waltid-applications/waltid-web-wallet/libs/components/WalletPageHeader.vue
@@ -17,7 +17,7 @@
afternoon
-
, {{ user.email }}
+
, {{ user.friendlyName }}
diff --git a/waltid-applications/waltid-web-wallet/libs/stores/user.ts b/waltid-applications/waltid-web-wallet/libs/stores/user.ts
index 07529990f..b19b7d49d 100644
--- a/waltid-applications/waltid-web-wallet/libs/stores/user.ts
+++ b/waltid-applications/waltid-web-wallet/libs/stores/user.ts
@@ -3,7 +3,7 @@ import { defineStore } from "pinia";
import { ref } from "vue";
export const useUserStore = defineStore("userStore", () => {
- const user = ref(useLocalStorage("id/walt/wallet/user", { id: "", email: "n/a" }));
+ const user = ref(useLocalStorage("id/walt/wallet/user", { id: "", friendlyName: "n/a" }));
return { user };
});
From fb2d06262f5c9618c3e3dfa81ff2fca37340d8ae Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 04:25:50 +0100
Subject: [PATCH 49/91] Implement simple authnz logout for vue frontend
---
.../auth/KtorAuthnzFrontendController.kt | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt
index dc72d8721..51266e631 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/web/controllers/auth/KtorAuthnzFrontendController.kt
@@ -14,6 +14,7 @@ import io.ktor.server.auth.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
+import io.ktor.util.date.*
import kotlinx.serialization.json.*
fun Application.ktorAuthnzFrontendRoutes() {
@@ -38,14 +39,13 @@ fun Application.ktorAuthnzFrontendRoutes() {
}
}
- post("login") { // also in authenticate {} block as it just relays authnz auth
- //call.sessions.set(LoginTokenSession(token))
-
+ post("login") {
val providedToken = call.receiveText()
println("providedToken: $providedToken")
val (account, token) = if (providedToken.isNotEmpty()) {
- val token = Json.decodeFromString
(providedToken)["token"]?.jsonPrimitive?.content ?: error("Missing token")
+ val token =
+ Json.decodeFromString(providedToken)["token"]?.jsonPrimitive?.content ?: error("Missing token")
val session = KtorAuthnzManager.tokenHandler.resolveTokenToSession(token)
val account = session.accountId
val sessionToken = session.token
@@ -64,6 +64,13 @@ fun Application.ktorAuthnzFrontendRoutes() {
}
)
}
+
+ post("logout") {
+ call.response.cookies.append("ktor-authnz-auth", "", CookieEncoding.URI_ENCODING, 0L, GMTDate())
+ call.response.cookies.append("auth.token", "", CookieEncoding.URI_ENCODING, 0L, GMTDate())
+
+ context.respond(HttpStatusCode.OK)
+ }
}
}
}
From 5812a26adbaf6e6c105232047c3256010c56baa9 Mon Sep 17 00:00:00 2001
From: waltkb <68587968+waltkb@users.noreply.github.com>
Date: Wed, 15 Jan 2025 11:32:21 +0100
Subject: [PATCH 50/91] Exclamation mark at login page
---
.../apps/waltid-dev-wallet/src/pages/login.vue | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
index afe0f5232..853009094 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
@@ -21,10 +21,8 @@
sign up for your SSI wallet
-
- !
+ >sign up for your SSI wallet!
+
@@ -407,7 +405,7 @@ async function login() {
{ email: emailInput, password: passwordInput, type: "email" },
{ callbackUrl: signInRedirectUrl.value }
)
- .then(() =>{
+ .then(() => {
user.value = {
id: "",
friendlyName: userData.email
@@ -488,7 +486,7 @@ async function openWeb3() {
const result = await verificationResponse.json();
console.log("Verification result: ", result);
- await authnzLogin(address, result.token)
+ await authnzLogin(address, result.token);
}
definePageMeta({
From cf6b97fe5f0cfc3bfa88bab58f1fbebf130ec25b Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Wed, 15 Jan 2025 17:56:18 +0100
Subject: [PATCH 51/91] fix : fix for hard coded dispatcher
---
.../service/account/authnz/AuthenticationService.kt | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
index 93acc1d32..a8a0be0e2 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
@@ -7,6 +7,7 @@ import id.walt.ktorauthnz.methods.data.AuthMethodStoredData
import id.walt.webwallet.db.models.authnz.AuthnzAccountIdentifiers
import id.walt.webwallet.db.models.authnz.AuthnzAccountIdentifiers.userId
import id.walt.webwallet.db.models.authnz.AuthnzStoredData
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jetbrains.exposed.sql.insert
@@ -16,13 +17,13 @@ import java.util.UUID
import kotlin.uuid.ExperimentalUuidApi
@OptIn(ExperimentalUuidApi::class)
-class AuthenticationService {
+class AuthenticationService(private val dispatcher: CoroutineDispatcher = Dispatchers.IO) {
val editableAccountStore = object : EditableAccountStore {
override suspend fun addAccountIdentifierToAccount(
accountId: String,
newAccountIdentifier: AccountIdentifier
- ): Unit = withContext(Dispatchers.IO) {
+ ): Unit = withContext(dispatcher) {
transaction {
AuthnzAccountIdentifiers.insert {
it[AuthnzAccountIdentifiers.userId] = UUID.fromString(accountId)
@@ -41,7 +42,7 @@ class AuthenticationService {
accountIdentifier: AccountIdentifier,
method: String,
data: AuthMethodStoredData
- ): Unit = withContext(Dispatchers.IO) {
+ ): Unit = withContext(dispatcher) {
val savableStoredData = data.transformSavable()
transaction {
val userId = AuthnzAccountIdentifiers
@@ -63,7 +64,7 @@ class AuthenticationService {
accountId: String,
method: String,
data: AuthMethodStoredData
- ): Unit = withContext(Dispatchers.IO) {
+ ): Unit = withContext(dispatcher) {
val savableStoredData = data.transformSavable()
transaction {
AuthnzStoredData.insert {
@@ -117,7 +118,7 @@ class AuthenticationService {
}
override suspend fun lookupAccountUuid(identifier: AccountIdentifier): String? =
- withContext(Dispatchers.IO) {
+ withContext(dispatcher) {
transaction {
AuthnzAccountIdentifiers
.selectAll().where { AuthnzAccountIdentifiers.identifier eq identifier.accountIdentifierName }
@@ -129,7 +130,7 @@ class AuthenticationService {
override suspend fun hasStoredDataFor(
identifier: AccountIdentifier,
method: AuthenticationMethod
- ): Boolean = withContext(Dispatchers.IO) {
+ ): Boolean = withContext(dispatcher) {
transaction {
AuthnzStoredData
.selectAll().where { AuthnzStoredData.method eq method.toString() }
From 12e647768b19cbaf1d6a5f79cb3894ab468b0ed1 Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Wed, 15 Jan 2025 17:57:27 +0100
Subject: [PATCH 52/91] fix : implement correct exception for not implemented
function
---
.../account/authnz/AuthenticationService.kt | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
index a8a0be0e2..1b6c2134b 100644
--- a/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
+++ b/waltid-services/waltid-wallet-api/src/main/kotlin/id/walt/webwallet/service/account/authnz/AuthenticationService.kt
@@ -13,7 +13,7 @@ import kotlinx.coroutines.withContext
import org.jetbrains.exposed.sql.insert
import org.jetbrains.exposed.sql.selectAll
import org.jetbrains.exposed.sql.transactions.transaction
-import java.util.UUID
+import java.util.*
import kotlin.uuid.ExperimentalUuidApi
@OptIn(ExperimentalUuidApi::class)
@@ -35,7 +35,7 @@ class AuthenticationService(private val dispatcher: CoroutineDispatcher = Dispat
}
override suspend fun removeAccountIdentifierFromAccount(accountIdentifier: AccountIdentifier) {
- TODO("Not yet implemented")
+ throw NotImplementedError("removeAccountIdentifierFromAccount")
}
override suspend fun addAccountIdentifierStoredData(
@@ -80,7 +80,7 @@ class AuthenticationService(private val dispatcher: CoroutineDispatcher = Dispat
method: String,
data: AuthMethodStoredData
) {
- TODO("Not yet implemented")
+ throw NotImplementedError("updateAccountIdentifierStoredData")
}
override suspend fun updateAccountStoredData(
@@ -88,25 +88,25 @@ class AuthenticationService(private val dispatcher: CoroutineDispatcher = Dispat
method: String,
data: AuthMethodStoredData
) {
- TODO("Not yet implemented")
+ throw NotImplementedError("updateAccountStoredData")
}
override suspend fun deleteAccountIdentifierStoredData(
accountIdentifier: AccountIdentifier,
method: String
) {
- TODO("Not yet implemented")
+ throw NotImplementedError("deleteAccountIdentifierStoredData")
}
override suspend fun deleteAccountStoredData(accountId: String, method: String) {
- TODO("Not yet implemented")
+ throw NotImplementedError("deleteAccountStoredData")
}
override suspend fun lookupStoredDataForAccount(
accountId: String,
method: AuthenticationMethod
): AuthMethodStoredData? {
- TODO()
+ throw NotImplementedError("lookupStoredDataForAccount")
}
@@ -114,7 +114,7 @@ class AuthenticationService(private val dispatcher: CoroutineDispatcher = Dispat
identifier: AccountIdentifier,
method: AuthenticationMethod
): AuthMethodStoredData? {
- TODO("Not yet implemented")
+ throw NotImplementedError("lookupStoredDataForAccountIdentifier")
}
override suspend fun lookupAccountUuid(identifier: AccountIdentifier): String? =
From 8ba39fc1fbc192086064403c404b2755970551f0 Mon Sep 17 00:00:00 2001
From: SuperBatata
Date: Wed, 15 Jan 2025 17:58:09 +0100
Subject: [PATCH 53/91] fix : remove testing condition used while debugging
---
.../waltid-dev-wallet/src/pages/login.vue | 32 +++++++++----------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
index 853009094..837865d3c 100644
--- a/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
+++ b/waltid-applications/waltid-web-wallet/apps/waltid-dev-wallet/src/pages/login.vue
@@ -349,21 +349,21 @@