Skip to content
Draft
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
7dcd644
feat: wwwallet setup docs
PascalDR Sep 11, 2025
039daf5
chore: updated .gitignore
PascalDR Sep 15, 2025
ec89509
feat: initial configuration for wwwallet
PascalDR Sep 15, 2025
7d1ab9c
chore: updated submodules
PascalDR Sep 16, 2025
7ee449c
chore: added submodules
PascalDR Sep 16, 2025
6716b4e
feat: added configuration
PascalDR Sep 16, 2025
750c8d7
feat: updated script
PascalDR Sep 16, 2025
c940d6d
fix: script
PascalDR Sep 16, 2025
5e362a8
feat: added conf file
PascalDR Sep 16, 2025
542d710
chore: updated submodule
PascalDR Sep 16, 2025
78f6fe9
feat: updated script
PascalDR Sep 16, 2025
ee280fe
chore: update .gitignore
PascalDR Sep 16, 2025
d1f7b4f
Merge branch 'dev' of https://github.com/italia/iam-proxy-italia into…
PascalDR Sep 16, 2025
572e01c
fix: config
PascalDR Sep 16, 2025
7d2ced7
fix: updated compose script
PascalDR Sep 17, 2025
c289e71
Update Docker-compose/docker-compose.yml
PascalDR Sep 18, 2025
eec60b9
fix: updated script
PascalDR Sep 18, 2025
babf6f9
Merge branch 'docs/wwwallet_documentation' of https://github.com/ital…
PascalDR Sep 18, 2025
5fe39ea
feat: added mariadb
PascalDR Sep 18, 2025
716abc7
fix: merged nginx
PascalDR Sep 18, 2025
4f3a229
chore: removed file
PascalDR Sep 18, 2025
4a7a0a8
fix: removed unecessary sections
PascalDR Sep 18, 2025
eeb6989
fix: docs
PascalDR Sep 18, 2025
9b4060b
fix: support multiple profiles
PascalDR Sep 18, 2025
d842f51
fix: use env variables
PascalDR Sep 18, 2025
79a32ab
feat: dynamic config
PascalDR Sep 18, 2025
0d48f11
fix: clean nginx data
PascalDR Sep 18, 2025
4bb8334
feat: updated docs
PascalDR Sep 29, 2025
48f520e
Merge branch 'dev' into docs/wwwallet_documentation
PascalDR Sep 29, 2025
f77a40d
Update Docker-compose/docker-compose.yml
PascalDR Sep 29, 2025
c01c602
fix: typo
PascalDR Sep 29, 2025
990dfdd
Merge branch 'docs/wwwallet_documentation' of https://github.com/ital…
PascalDR Sep 29, 2025
25024c2
fix: typo
PascalDR Sep 29, 2025
a260a13
fix: protocol
PascalDR Sep 29, 2025
36dc974
Merge remote-tracking branch 'origin/dev' into docs/wwwallet_document…
saralongobardiacn Oct 1, 2025
bff1674
gitignore: ignore wwwallet files in Docker-compose folder
saralongobardiacn Oct 2, 2025
cc9126e
fix: wwwallet, fix startup pipeline and manage run-docker-compose.sh …
saralongobardiacn Oct 2, 2025
f7329aa
fix: wwwallet, remove file ignored for fix startup
saralongobardiacn Oct 2, 2025
af3f30f
Merge branch 'dev' into docs/wwwallet_documentation
peppelinux Oct 2, 2025
046bca3
Fix merge commit
saralongobardiacn Oct 2, 2025
cd50aab
Merge remote-tracking branch 'origin/dev' into docs/wwwallet_document…
saralongobardiacn Oct 10, 2025
b1b38b5
fix: *-docker-compose.sh, handle multiple instruction in run and remo…
saralongobardiacn Oct 10, 2025
7cc5205
fix: wwwallet, runtime error for invoke /status endpoint
saralongobardiacn Oct 10, 2025
dbc9f63
fix: wwwallet, create custom config for openid4vci_frontend.yml
saralongobardiacn Oct 13, 2025
9ec05d3
fix: openid4vci, handle default_target_authentication_backend
saralongobardiacn Oct 13, 2025
b76c72d
rev: openid4vci wwwallet, use SATOSA_BASE_OPENID4VCI env instead same…
saralongobardiacn Oct 15, 2025
5b1fb93
rev: wwwallet, set nginx proxy for use localhost instead satosa-nginx…
saralongobardiacn Oct 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ iam-proxy-italia-project/logs/*.log
iam-proxy-italia-project/metadata/*.md
iam-proxy-italia-project/data/*
iam-proxy-italia-project/private/*
iam-proxy-italia-project/wwwallet/mysql/data/
iam-proxy-italia-project/wwwallet/mysql/init/
*.pyc
*pyFF_example/info.log
*pyFF_example/error.log
Expand All @@ -27,6 +29,7 @@ Docker-compose/djangosaml2_sp/*
Docker-compose/mongo/db/*
Docker-compose/nginx/html/static/*
Docker-compose/.env
Docker-compose/wwwallet/*
Docker-compose/eudi-wallet-it-python
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
Expand Down
9 changes: 9 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[submodule "iam-proxy-italia-project/wwwallet/wallet-frontend"]
path = iam-proxy-italia-project/wwwallet/wallet-frontend
url = https://github.com/wwWallet/wallet-frontend.git
[submodule "iam-proxy-italia-project/wwwallet/wallet-backend-server"]
path = iam-proxy-italia-project/wwwallet/wallet-backend-server
url = https://github.com/wwWallet/wallet-backend-server
[submodule "iam-proxy-italia-project/wwwallet/wallet-common"]
path = iam-proxy-italia-project/wwwallet/wallet-common
url = https://github.com/wwWallet/wallet-common
64 changes: 62 additions & 2 deletions Docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,60 @@
services:

wwwallet-mariadb:
profiles:
- wwwallet
container_name: wwwallet-mariadb
environment:
MARIADB_DATABASE: ${MARIADB_DBNAME:-wwwalletdb}
MARIADB_ROOT_PASSWORD: ${MARIADB_DBPASSWORD:-changeme}
MARIADB_USER: ${MARIADB_DBUSER:-dbuser}
MARIADB_PASSWORD: ${MARIADB_DBPASSWORD:-dbpassword}
command:
- --table_definition_cache=100
- --performance_schema=0
- --innodb_use_native_aio=0
volumes:
- ./wwwallet/mariadb/data/:/var/lib/mysql
image: mariadb:10.6
ports:
- "3306:3306"
networks:
- iam-proxy-italia

wwwallet-server:
profiles:
- wwwallet
build:
context: ./wwwallet/wallet-backend-server
dockerfile: Dockerfile
container_name: wwwallet-server
depends_on:
- wwwallet-mariadb
ports:
- "5000:5000"
networks:
- iam-proxy-italia

wwwallet-frontend:
profiles:
- wwwallet
build:
context: ./wwwallet/wallet-frontend
dockerfile: Dockerfile
container_name: wwwallet-frontend
depends_on:
- wwwallet-server
ports:
- "3000:3000"
networks:
- iam-proxy-italia

satosa-mongo:
profiles:
- demo
- mongo
- mongoexpress
- wwwallet
image: mongo
container_name: satosa-mongo
environment:
Expand All @@ -25,6 +75,7 @@ services:
profiles:
- demo
- mongoexpress
- wwwallet
image: mongo-express
container_name: satosa-mongo-express
ports:
Expand All @@ -45,6 +96,7 @@ services:
profiles:
- demo
- dev
- wwwallet
build:
context: ../
args:
Expand Down Expand Up @@ -128,6 +180,7 @@ services:
- ./iam-proxy-italia-project:/satosa_proxy:rwx
#- ./eudi-wallet-it-python/pyeudiw:/.venv/lib/python3.12/site-packages/pyeudiw:rwx
# - iam-proxy-italia-data:/satosa_proxy # to be used for external volumes
# - ./eudi-wallet-it-python/pyeudiw:/.venv/lib/python3.12/site-packages/pyeudiw:rw
Comment thread
PascalDR marked this conversation as resolved.
Outdated
working_dir: /satosa_proxy
entrypoint: "sh entrypoint.sh"
networks:
Expand All @@ -140,6 +193,12 @@ services:
timeout: 30s

satosa-nginx:
profiles:
- demo
- mongo
- mongoexpress
- dev
- wwwallet
image: nginx:alpine
container_name: satosa-nginx
depends_on:
Expand All @@ -150,7 +209,7 @@ services:
ports:
- "443:443"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/html:/usr/share/nginx/html:ro
- ./certbot/archive:/etc/archive:ro
- ./certbot/live/${SATOSA_HOSTNAME:-localhost}:/etc/nginx/certs:ro
Expand All @@ -165,7 +224,8 @@ services:
profiles:
- demo
- dev
image: italia/spid-saml-check
- wwwallet
image: italia/spid-saml-check:1.10.6
Comment thread
peppelinux marked this conversation as resolved.
container_name: spid-samlcheck
ports:
- "8443:8443"
Expand Down
2 changes: 2 additions & 0 deletions Docker-compose/nginx/conf.d/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ server {
uwsgi_param SERVER_ADDR $server_addr;
}

include ./conf.d/sites-enabled/*.conf;

error_page 404 /404.html;
location = /404.html {
root /usr/share/nginx/html/errors;
Expand Down
30 changes: 30 additions & 0 deletions Docker-compose/nginx/conf.d/sites-enabled/wwwallet.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
location /wwwallet-frontend/ {
rewrite ^/wwwallet-frontend/(.*)$ /$1 break;
alias /wwwallet-frontend/;

proxy_pass http://wwwallet-frontend:80/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Forwarded-Port $server_port;
}


location /wwwallet-server/ {
rewrite ^/wwwallet-server/(.*)$ /$1 break;
alias /wwwallet-server/;

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

proxy_pass http://wwwallet-server:8002/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Forwarded-Port $server_port;
}
15 changes: 14 additions & 1 deletion Docker-compose/run-docker-compose.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/bash
export COMPOSE_PROFILES=demo
export COMPOSE_PROFILES=wwwallet
Comment thread
PascalDR marked this conversation as resolved.
Outdated
export SKIP_UPDATE=
export RUN_SPID_TEST=

Expand All @@ -8,6 +8,8 @@ function clean_data {
rm -Rf ./iam-proxy-italia-project/*
rm -Rf ./djangosaml2_sp/*
rm -Rf ./nginx/html/static
rm -Rf ./nginx/conf.d/sites-enabled/*
rm -Rf ./wwwallet/*
}

function initialize_satosa {
Expand All @@ -19,10 +21,21 @@ function initialize_satosa {
mkdir -p ./djangosaml2_sp
mkdir -p ./mongo/db
mkdir -p ./nginx/html/static
mkdir -p ./wwwallet

if [ ! -f ./iam-proxy-italia-project/proxy_conf.yaml ]; then cp -R ../iam-proxy-italia-project/* ./iam-proxy-italia-project/ && rm -R ./satosa/static/ ; else echo 'iam-proxy-italia-project directory is already initialized' ; fi
if [ ! -f ./djangosaml2_sp/run.sh ]; then cp -R ../iam-proxy-italia-project_sp/djangosaml2_sp/* ./djangosaml2_sp ; else echo 'djangosaml2_sp directory is already initialided' ; fi
if [ ! -f ./nginx/html/static/disco.html ]; then cp -R ../iam-proxy-italia-project/static/* ./nginx/html/static ; else echo 'nginx directory is already initialized' ; fi
if [ "$COMPOSE_PROFILES" == *"wwwallet"* ]; then
if [ ! -f ./nginx/conf.d/sites-enabled/wwwallet.conf ]; then cp -R ../iam-proxy-italia-project/wwwallet/configs/wwwallet.conf ./nginx/conf.d/sites-enabled/ ; else echo 'nginx wwwallet configuration is already initialized' ; fi
if [ ! -f ./wwwallet/wallet-frontend/package.json ]; then cp -R ../iam-proxy-italia-project/wwwallet/wallet-frontend ./wwwallet/wallet-frontend ; else echo 'wwwallet-frontend directory is already initialized' ; fi
if [ ! -f ./wwwallet/wallet-backend-server/package.json ]; then cp -R ../iam-proxy-italia-project/wwwallet/wallet-backend-server ./wwwallet/wallet-backend-server ; else echo 'wwwallet-backend-server directory is already initialized' ; fi
if [ ! -f ./wwwallet/wallet-frontend/.env.prod ]; then cp -R ../iam-proxy-italia-project/wwwallet/configs/.env.prod ./wwwallet/wallet-frontend/.env.prod ; else echo 'wwwallet-frontend .env.prod file is already initialized' ; fi
if [ ! -f ./wwwallet/wallet-frontend/lib/wallet-common/package.json ]; then mkdir -p ./wwwallet/wallet-frontend/lib/wallet-common && cp -R ../iam-proxy-italia-project/wwwallet/wallet-common ./wwwallet/wallet-frontend/lib/wallet-common ; else echo 'wwwallet-frontend wallet-common directory is already initialized' ; fi
cp -R ../iam-proxy-italia-project/wwwallet/configs/config.template.ts ./wwwallet/wallet-backend-server/config/config.template.ts
cp -R ../iam-proxy-italia-project/wwwallet/configs/vite.config.ts ./wwwallet/wallet-frontend/vite.config.ts
cp -R ../iam-proxy-italia-project/wwwallet/configs/proxy.router.ts ./wwwallet/wallet-backend-server/src/routers/proxy.router.ts
fi

chmod -R 777 ./iam-proxy-italia-project
echo "WARNING: iam-proxy-italia-project permission folder set recursively to 777"
Expand Down
2 changes: 2 additions & 0 deletions Docker-compose/wwwallet/mysql/config/my.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[mysqld]
default-authentication-plugin=mysql_native_password
46 changes: 46 additions & 0 deletions docs/readme.wwwallet_setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

# Setup Instructions

## Prerequisites
Before you begin, ensure you have the following installed:
- Docker
- Docker Compose
- Git

### WWWAllet Backend Setup
Every aspect of backend configuration is managed through `iam-proxy-italia-project/wwwallet/configs/config.template.ts` file and if you need to customize it, like changing the database connection details or enabling/disabling certain features, you can do so by editing this file.
Note that you will need to set:
- the host and port where the backend will be running.
- the database connection details to connect to your Mysql instance.
- and the notification system need to be disabled if no firebase subscription is available.

### WWWAllet Frontend Setup
The frontend configuration is managed through the `iam-proxy-italia-project/wwwallet/configs/.env.prod` file.
You can customize it by editing this file.
Note that you will need to set:
- the backend url to connect to the backend instance.
- the firebase configuration if you want to enable the notification system.

### Nginx Custom Configuration
The Nginx configuration for wwwallet is managed through the `iam-proxy-italia-project/wwwallet/configs/wwwallet.conf` file.
If you change the backend or frontend host and port, you will need to update this file accordingly.

## Installation Steps

### Automated Setup with Docker-Compose
The installation process is completely automated by the script `run-docker-compose.sh` located in the `Docker-compose` folder.
You can set the variable `COMPOSE_PROFILES` to the value `wwwallet` into the script and run it with the command:
```bash
./run-docker-compose.sh
```

### Trusted Issuer Configuration
After the backend initialization, you must add the instance of the OpenID4VCI frontend, distributed in iam-proxy-italia using [pyeudiw](https://github.com/italia/eudi-wallet-it-python), as trusted issuer.
We therefore need to configure the enabled credential issuer by adding an entry in the table `credential_issuer` of the Mysql database used by wwwallet backend.
You can do this with any MariaDB client or using the MariaDB command line.
Note that the url must point to the OpenID4VCI Frontend to work properly.
An example of the SQL command to be executed is the following:
```sql
INSERT INTO wwwalletdb.credential_issuer (credentialIssuerIdentifier,clientId,visible)
VALUES ('Satosa OpenID4VCI','https://localhost/OpenID4VCI',1);
```
28 changes: 28 additions & 0 deletions iam-proxy-italia-project/wwwallet/configs/.env.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
HOST='0.0.0.0'
PORT=3000
VITE_WS_URL=ws://${SATOSA_HOSTNAME}/wwwallet-server/
Comment thread
PascalDR marked this conversation as resolved.
Outdated
VITE_WALLET_BACKEND_URL=https://${SATOSA_HOSTNAME}/wwwallet-server/
VITE_LOGIN_WITH_PASSWORD=true
VITE_FIREBASE_ENABLED=false
VITE_FIREBASE_VAPIDKEY=<Your_Vapid_Key>
VITE_FIREBASE_API_KEY=<Your_Firebase_API_Key>
VITE_FIREBASE_AUTH_DOMAIN=<Your_Firebase_Auth_Domain>
VITE_FIREBASE_PROJECT_ID=<Your_Firebase_Project_ID>
VITE_FIREBASE_STORAGE_BUCKET=<Your_Firebase_Storage_Bucket>
VITE_FIREBASE_MESSAGING_SENDER_ID=<Your_Firebase_Messaging_Sender_ID>
VITE_FIREBASE_APP_ID=<Your_Firebase_App_ID>
VITE_FIREBASE_MEASUREMENT_ID=<Your_Firebase_Measurement_ID>
VITE_DID_KEY_VERSION=jwk_jcs-pub
VITE_APP_VERSION=$npm_package_version
VITE_GENERATE_SOURCEMAP=false
VITE_DISPLAY_CONSOLE=true
VITE_WEBAUTHN_RPID=${SATOSA_HOSTNAME}
VITE_OPENID4VCI_REDIRECT_URI=http://${SATOSA_HOSTNAME}/wallet-frontend
Comment thread
PascalDR marked this conversation as resolved.
Outdated
VITE_OPENID4VCI_PROOF_TYPE_PRECEDENCE="attestation,jwt"
VITE_OPENID4VP_SAN_DNS_CHECK=false
VITE_OPENID4VP_SAN_DNS_CHECK_SSL_CERTS=false
VITE_VALIDATE_CREDENTIALS_WITH_TRUST_ANCHORS=true
VITE_MULTI_LANGUAGE_DISPLAY=true
VITE_STATIC_PUBLIC_URL=https://demo.wwwallet.org
VITE_STATIC_NAME=wwWallet
VITE_DISPLAY_ISSUANCE_WARNINGS=false
27 changes: 27 additions & 0 deletions iam-proxy-italia-project/wwwallet/configs/config.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const config = {
url: "localhost",
port: "8002",
appSecret: "SERVICE_SECRET",
ssl: false,
db: {
host: "wwwallet-mariadb",
port: "3306",
username: "root",
password: "changeme",
Comment thread
peppelinux marked this conversation as resolved.
Comment thread
peppelinux marked this conversation as resolved.
dbname: "wwwalletdb",
},
walletClientUrl: "WALLET_CLIENT_URL",
webauthn: {
attestation: "direct",
origin: "WEBAUTHN_ORIGIN",
rp: {
id: "WEBAUTHN_RP_ID",
name: "wwWallet demo",
},
},
alg: "EdDSA",
notifications: {
enabled: false,
serviceAccount: "firebaseConfig.json"
}
}
59 changes: 59 additions & 0 deletions iam-proxy-italia-project/wwwallet/configs/proxy.router.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import axios from 'axios';
import express, { Request, Response, Router } from 'express';
import { Agent } from 'node:https';
const proxyRouter: Router = express.Router();

const agent = new Agent({
rejectUnauthorized: false,
});

proxyRouter.post('/', async (req, res) => {
const { headers, method, url, data } = req.body;
try {
const isBinaryRequest = /\.(png|jpe?g|gif|webp|bmp|tiff?|ico)(\?.*)?(#.*)?$/i.test(url);
console.log("URL = ", url)
const response = await axios({
url: url,
headers: headers,
method: method,
data: data,
...(isBinaryRequest && { responseType: 'arraybuffer' }),
maxRedirects: 0,
httpsAgent: agent,
});

if (isBinaryRequest) {
// forward all response headers
for (const key in response.headers) {
if (Object.prototype.hasOwnProperty.call(response.headers, key)) {
const value = response.headers[key];
if (value !== undefined) {
res.setHeader(key, value as string);
}
}
}
return res.status(response.status).send(response.data);
}

// JSON or other text content
return res.status(response.status).send({
status: response.status,
headers: response.headers,
data: response.data,
});
}
catch (err) {
console.error("Error in proxy request: ", err);
if (err.response && err.response.data) {
console.error("Error data = ", err.response.data)
}
if (err.response && err.response.status == 302) {
return res.status(200).send({ status: err.response.status, headers: err.response.headers, data: {} })
}
return res.status(err.response?.status ?? 104).send({ status: err.response?.status ?? 104, data: err.response?.data, headers: err.response?.headers });
}
})

export {
proxyRouter
}
Loading
Loading