Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:Sphereon-Opensource/OID4VC-demo …
Browse files Browse the repository at this point in the history
…into feat/VDX-308-env-subst

# Conflicts:
#	packages/agent/conf/demos/sphereon/oid4vci_metadata/sphereon.json
#	packages/agent/conf/demos/sphereon/oid4vci_options/sphereon.json
  • Loading branch information
Maikel Maas committed Nov 17, 2023
2 parents 81a005a + dfca752 commit f87b8f4
Show file tree
Hide file tree
Showing 61 changed files with 722 additions and 673 deletions.
12 changes: 8 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
**/*.env*
!**/.env.example
packages/agent/conf/dev

#docker files
/docker

# dependencies
/node_modules
onto-demo-client/node_modules
siopv2-openid4vp-demo-backend/node_modules
onto-demo-shared-types/node_modules
**/node_modules
/.pnp
.pnp.js

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ yarn.lock

.idea

#docker
/docker/compose/build
!/docker/compose/build/docker-compose.yml
!/docker/compose/build/install-configs.sh
63 changes: 49 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ And a scenario for using Verifiable Credential(s) For OID4VP flow:
![OID4VP flow](http://www.plantuml.com/plantuml/proxy?cache=no&src=https://raw.githubusercontent.com/Sphereon-Opensource/OID4VC-demo/develop/documents/oid4vp-flow.puml)

# Step by Step instructions

In the next chapters we're going to show you how to setup the `agent` module, oid4vci-demo-front-end and a brief
introduction on how credential branding actually works.

Expand All @@ -73,28 +74,62 @@ introduction on how credential branding actually works.

### Docker

From the root folder run:
We maintain Docker a setup for building and testing in directory `docker/compose/build`.
We have created a script to install and patch the agent configurations for you required to build and run the Docker
containers.
It's located here: `docker/compose/build/install-configs.sh <ecosystem> <agent host address>`.
**IMPORTANT:** The host address should be either a DNS host or a LAN IP that is reachable for your mobile devices running SSI wallet
software. For example:

```bash
docker-compose build
docker-compose up
install-configs.sh sphereon http://192.168.1.100:5000
```

The build phase might take a few minutes. If you run the docker-compose up command 3 services will be running. The
ssi-agent, oid4vci-demo-frontend and oid4vp-frontend.
The install-configs.sh script will set up the environment for your containers using the .env.examples files from
packages/**src/.env.example and put them in the directories under `docker/compose/build`:

You should now be able to go to http://host.docker.internal:5001 and http://host.docker.internal:5002 respectively to
test the issuer and verifier demo's.
```
oid4vci-demo-frontend/.env.local
oid4vp-demo-frontend/.env.local
agent/.env.local
```

Please note that you might have to configure your docker environment to expose the host.docker.internal like the image
below. If you cannot make that work you could adjust the config/docker and docker/*.env files to suit your needs
(The .env.local files are copied and patched from the packages/**/src/.env.example files)

Please ensure that you execute the script and docker compose commands with ./docker/compose/build as working directory
and have correctly set up your environment
variables as outlined in the documentation for [Setting up the agent](./documents/agent-setup.md)
and [Setting up the VCI frontend](./documents/vci-front-end.md).

The current example for ecosystem "sphereon" loads the folder `packages/agent/conf/demos/sphereon` as your base
configuration folder.
All ecosystems present in packages/agent/conf/demos can be installed using the install-configs.sh script.

To build and run the Docker containers, execute the following commands from within the respective directory:

```bash
docker compose build # This builds the Docker images
docker compose up -d # This starts the Docker containers, this will require the .env & config files to be installed
```

The building process may take a few minutes. Once you execute the docker compose up command, three services will start:
ssi-agent, oid4vci-demo-frontend, and oid4vp-frontend.

You should now be able to go to http://localhost:5001 and http://localhost:5002 respectively to test the issuer and
verifier demo's.

Please note that you might have to configure your docker environment to expose the host.docker.internal like the image
below. If you cannot make that work you could adjust the config/docker and docker/compose/build/**/.env* files to suit
your needs.
<img src="resources/docker_settings.png" width="500" />

#### Environment variables and configuration for docker.
To build the images without docker-compose you can also just use "docker build" in the project root directory with some
parameters:

```shell
docker build -f ./docker/Dockerfile -t oid4vc-demo-ssi-agent:latest --build-arg="PACKAGE_PATH=packages/agent" --build-arg="NODE_SCRIPT=start:dev" .
docker build -f ./docker/Dockerfile -t oid4vci-demo-frontend:latest --build-arg="PACKAGE_PATH=packages/oid4vci-demo-frontend" --build-arg="NODE_SCRIPT=start:prod" .
docker build -f ./docker/Dockerfile -t oid4vp-demo-frontend:latest --build-arg="PACKAGE_PATH=packages/oid4vp-demo-frontend" --build-arg="NODE_SCRIPT=start:prod" .
```

Please note that the environment variables for the 3 images come from the ./docker folder. You will have to copy the 3
example files and remove the .example suffix.

The configuration files are copied over to the agent image. So the above explained configuration options also apply when
running in docker.
34 changes: 0 additions & 34 deletions docker-compose.yml

This file was deleted.

3 changes: 0 additions & 3 deletions docker/.env.oid4vci-demo-frontend

This file was deleted.

5 changes: 0 additions & 5 deletions docker/.env.oid4vp-demo-frontend

This file was deleted.

13 changes: 0 additions & 13 deletions docker/.env.ssi-agent

This file was deleted.

23 changes: 23 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Builder stage
FROM node:lts-bookworm AS oid4vc-demo-builder
SHELL ["/bin/bash", "-c"]
RUN npm -g install pnpm && SHELL=bash pnpm setup && source /root/.bashrc && pnpm add -g pnpm
RUN pnpm add typescript tslib
WORKDIR /opt/oid4vc-demo

COPY /. .
RUN rm -rf /root/.local/share/pnpm/store
RUN pnpm install -r
RUN pnpm build

# Final stage
FROM node:lts-bookworm
ARG PACKAGE_PATH
ARG NODE_SCRIPT
ENV NODE_SCRIPT=${NODE_SCRIPT}
COPY --from=oid4vc-demo-builder /opt/oid4vc-demo/${PACKAGE_PATH} /opt/oid4vc-demo/${PACKAGE_PATH}
# package node_modules has symlinks to root node_modules
COPY --from=oid4vc-demo-builder /opt/oid4vc-demo/node_modules /opt/oid4vc-demo/node_modules

WORKDIR /opt/oid4vc-demo/${PACKAGE_PATH}
ENTRYPOINT npm run-script ${NODE_SCRIPT}
11 changes: 0 additions & 11 deletions docker/Dockerfile.oid4vci-demo-frontend

This file was deleted.

11 changes: 0 additions & 11 deletions docker/Dockerfile.oid4vp-demo-frontend

This file was deleted.

12 changes: 0 additions & 12 deletions docker/Dockerfile.ssi-agent

This file was deleted.

56 changes: 56 additions & 0 deletions docker/compose/build/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
version: '3.8'

services:
oid4vc-demo-ssi-agent:
container_name: oid4vc-demo-ssi-agent
image: oid4vc-demo-ssi-agent:latest
build:
context: ../../..
dockerfile: ./docker/Dockerfile
args:
PACKAGE_PATH: packages/agent
NODE_SCRIPT: "start:dev"
volumes:
- "./agent/conf:/opt/oid4vc-demo/packages/agent/conf:ro"
- "./agent/.env.local:/opt/oid4vc-demo/packages/agent/.env.local:ro"
ports:
- "5000:5000"

oid4vci-demo-frontend:
container_name: oid4vci-demo-frontend
image: oid4vci-demo-frontend:latest
depends_on:
- oid4vc-demo-ssi-agent
tty: true
build:
context: ../../..
dockerfile: ./docker/Dockerfile
args:
PACKAGE_PATH: packages/oid4vci-demo-frontend
NODE_SCRIPT: "start:prod"
volumes:
- "./oid4vci-demo-frontend/conf:/opt/oid4vc-demo/packages/oid4vci-demo-frontend/src/configs:ro"
- "./oid4vci-demo-frontend/.env.local:/opt/oid4vc-demo/packages/oid4vci-demo-frontend/.env.local:ro"
ports:
- "5001:5001"
restart: unless-stopped

oid4vp-demo-frontend:
container_name: oid4vp-demo-frontend
image: oid4vp-demo-frontend:latest
extra_hosts:
- "host.docker.internal:host-gateway"
depends_on:
- oid4vc-demo-ssi-agent
tty: true
build:
context: ../../..
dockerfile: ./docker/Dockerfile
args:
PACKAGE_PATH: packages/oid4vp-demo-frontend
NODE_SCRIPT: "start:prod"
volumes:
- "./oid4vp-demo-frontend/.env.local:/opt/oid4vc-demo/packages/oid4vp-demo-frontend/.env.local:ro"
ports:
- "5002:5002"
restart: unless-stopped
95 changes: 95 additions & 0 deletions docker/compose/build/install-configs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/bin/bash

ecosystem_name=$1
agent_host_address=$2
if [ -z "$ecosystem_name" ] || [ -z "$agent_host_address" ]; then
echo "Usage: ./install-configs.sh <ecosystem> <agent host address>"
exit 1
fi

# Check if agent_host_address contains 'http://' or 'https://'
if [[ ! $agent_host_address =~ ^http ]]; then
echo "agent host address should be an http/https URL"
exit 1
fi

if [ ! -e "../../../packages/agent/conf/demos/${ecosystem_name}" ]; then
echo "There is no ecosystem named ${ecosystem_name} in /packages/agent/conf/demos"
exit 1
fi

if [ ! -e "../../../packages/oid4vci-demo-frontend/src/configs/${ecosystem_name}.json" ]; then
echo "There is no ecosystem file named ${ecosystem_name} json in packages/oid4vci-demo-frontend/src/configs"
exit 1
fi


# copy & patch .env files from templates
mkdir -p ./agent
cp ../../../packages/agent/.env.example ./agent/.env.local
sed -i "s|^CONF_PATH=.*|CONF_PATH=\"/opt/oid4vc-demo/packages/agent/conf/${ecosystem_name}\"|" ./agent/.env.local
sed -i "s|^OID4VP_WEBAPP_BASE_URI=.*|OID4VP_WEBAPP_BASE_URI=${agent_host_address}|" ./agent/.env.local
sed -i "s|^OID4VP_AGENT_BASE_URI=.*|OID4VP_AGENT_BASE_URI=${agent_host_address}|" ./agent/.env.local

mkdir -p ./oid4vci-demo-frontend/conf
cp ../../../packages/oid4vci-demo-frontend/.env.example ./oid4vci-demo-frontend/.env.local
sed -i "s|^REACT_APP_DEFAULT_ECOSYSTEM=.*|REACT_APP_DEFAULT_ECOSYSTEM=$ecosystem_name|" ./oid4vci-demo-frontend/.env.local

mkdir -p ./oid4vp-demo-frontend
cp ../../../packages/oid4vp-demo-frontend/.env.example ./oid4vp-demo-frontend/.env.local
sed -i "s|^REACT_APP_BACKEND_BASE_URI=.*|REACT_APP_BACKEND_BASE_URI=${agent_host_address}|" ./oid4vp-demo-frontend/.env.local

# change the urls in vci frontend configs
cp "../../../packages/oid4vci-demo-frontend/src/configs/${ecosystem_name}.json" ./oid4vci-demo-frontend/conf
config_file="./oid4vci-demo-frontend/conf/${ecosystem_name}.json"
if [ -f "$config_file" ]; then
new_oid4vp_agent_base_url="${agent_host_address}"
new_oid4vci_agent_base_url="${agent_host_address}"

jq --arg oid4vp "$new_oid4vp_agent_base_url" --arg oid4vci "$new_oid4vci_agent_base_url" \
'.general.oid4vpAgentBaseUrl = $oid4vp | .general.oid4vciAgentBaseUrl = $oid4vci' \
"$config_file" > temp.json && mv temp.json "$config_file"
else
echo "Config file not found: ${config_file}"
fi

src_dir="../../../packages/agent/conf/demos/${ecosystem_name}"
dest_dir="./agent/conf"
mkdir -p $dest_dir/${ecosystem_name}

# Check if the source directory exists (because we might have different names for our config here)
if [ ! -d "$src_dir" ]; then
# If the exact match doesn't exist, find the first directory containing the environment name
src_dir=$(find ../../../../packages/agent/conf/demos -type d -name "*${ecosystem_name}*" | head -n 1)
fi
# Copy the found dir to destination
cp -r "$src_dir" "$dest_dir"

# modify the values in the destination folder
find "$dest_dir" -type f -name '*.json' | while read json_file; do
jq --arg newUrl "$new_oid4vci_agent_base_url" \
'(
if .metadata then .metadata.credential_issuer = $newUrl else . end
) |
(
if .metadata then .metadata.credential_endpoint = ($newUrl + "/credentials") else . end
)' \
"$json_file" > temp.json && mv temp.json "$json_file"
done

oid4vci_metadata_folder="${dest_dir}/oid4vci_metadata"
if [ -d "$oid4vci_metadata_folder" ]; then
find "$oid4vci_metadata_folder" -type f -name '*.json' | while read json_file; do
jq --arg newUrl "$new_oid4vci_agent_base_url" \
'if .metadata then .metadata |= (.credential_issuer = $newUrl, .credential_endpoint = ($newUrl + "/credentials")) else . end' \
"$json_file" > temp.json && mv temp.json "$json_file"
done
fi

simplified_dest_dir=$dest_dir

# Loop to remove each occurrence of '../' from the beginning of simplified_dest_dir
while [[ $simplified_dest_dir == ../* ]]; do
simplified_dest_dir=${simplified_dest_dir#../}
done
echo "Configuration installation complete for environment ${ecosystem_name} in docker/compose/build"
4 changes: 2 additions & 2 deletions documents/vci-front-end.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ In this module we're using a few configuration from .env which are listed below:
- `PORT`: The port number that you want this frontend to be accessed from.
- `REACT_APP_DEFAULT_ECOSYSTEM`: (optional) The default ecosystem name of this demo. This should be your own configuration file name. You can also switch you ecosystem in the runtime with using `ecosystemId` query param in your url. For example you can head to `http://localhost:5001/?ecosystemId=sphereon#/credentials/issue/success` to see Sphereon's configured version of SSICredentialIssuedSuccessPage page.
- `REACT_APP_DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN`: (optional) If set to true, the frontend will try to find ecosystem value from subdomain
- `DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN_BEFORE`: This optional environment variable enhances the functionality of multi-tenancy or environment-specific configurations in a web application. When `REACT_APP_DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN` is set to `true`, this variable instructs the application to dynamically extract and set the ecosystem value from a specified segment of the application's URL.
- `REACT_APP_DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN_SUFFIX`: This optional environment variable enhances the functionality of multi-tenancy or environment-specific configurations in a web application. When `REACT_APP_DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN` is set to `true`, this variable instructs the application to dynamically extract and set the ecosystem value from a specified segment of the application's URL.
The purpose of this variable is to parse the URL and use a portion of the subdomain as the ecosystem identifier, which can then be used to configure or customize the application's behavior based on that ecosystem. This is particularly useful for applications that serve multiple ecosystems or tenants from a single codebase but require tenant-specific configurations.
Here's how it works:
- If the application's URL is `http://simple.demo.sphereon.com/`, and
- The `DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN_BEFORE` is set to `demo.sphereon.com`,
- The `REACT_APP_DEFAULT_ECOSYSTEM_FROM_SUBDOMAIN_SUFFIX` is set to `demo.sphereon.com`,
Then the application will extract the subdomain segment that precedes the `demo.sphereon.com` part of the URL, which in this case is `simple`. This extracted value is then designated as the ecosystem identifier.
The ecosystem identifier (`simple` in the example) can be used to load specific configurations, assets, or even to dictate the application's behavior for that particular ecosystem. This enables a flexible and scalable approach to managing configurations in a multi-ecosystem platform.

Expand Down
Loading

0 comments on commit f87b8f4

Please sign in to comment.