diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 9506b63c..e20606c6 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -22,7 +22,7 @@ jobs: with: python-version: ${{ matrix.python-version }} - - run: pip install -U setuptools + - run: pip install -U setuptools wheel - run: pip install -r requirements.txt @@ -48,7 +48,7 @@ jobs: - run: pushd examples/aml && pip install -r requirements.txt && popd - - run: pushd examples/yoti_example_django && pip install --upgrade pip && pip install -r requirements.txt && popd + - run: pushd examples/yoti_example_django && pip install --upgrade pip && pip install --no-cache-dir -r requirements.txt && popd - run: pushd examples/yoti_example_flask && pip install -r requirements.txt && popd diff --git a/.gitignore b/.gitignore index 022b5cb0..6c611549 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,7 @@ examples/yoti_example_flask/static/YotiSelfie.jpg #.pem files for examples examples/yoti_example_django/*.pem examples/yoti_example_flask/*.pem +examples/digitalidentity/*.pem .scannerwork .venv/ diff --git a/examples/digitalidentity/.env.example b/examples/digitalidentity/.env.example new file mode 100644 index 00000000..950e65a9 --- /dev/null +++ b/examples/digitalidentity/.env.example @@ -0,0 +1,3 @@ +# Required Keys +YOTI_CLIENT_SDK_ID=yourClientSdkId +YOTI_KEY_FILE_PATH=yourKeyFilePath diff --git a/examples/digitalidentity/.gitignore b/examples/digitalidentity/.gitignore new file mode 100644 index 00000000..612424a3 --- /dev/null +++ b/examples/digitalidentity/.gitignore @@ -0,0 +1 @@ +*.pem \ No newline at end of file diff --git a/examples/digitalidentity/README.md b/examples/digitalidentity/README.md new file mode 100644 index 00000000..2bfa2f8d --- /dev/null +++ b/examples/digitalidentity/README.md @@ -0,0 +1,11 @@ +# Yoti Share v2 Python Example + +## Running the example project + +1. Rename the [.env.example](.env.example) file to `.env` and fill in the required configuration values +2. Add your SDK ID to the [templates/index.html](templates/index.html) file +3. Create a virtual environment with `python3 -m venv .venv` +4. Active the environment `. .venv/bin/activate` +5. Install the dependencies with `pip install -r requirements.txt` +6. Start the server `flask run --port 8000` +7. Visit `http://127.0.0.1:8000` diff --git a/examples/digitalidentity/__init__.py b/examples/digitalidentity/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/digitalidentity/app.py b/examples/digitalidentity/app.py new file mode 100644 index 00000000..515c5ddd --- /dev/null +++ b/examples/digitalidentity/app.py @@ -0,0 +1,134 @@ +import json, requests +from flask import Flask, Response, request, render_template + + +from cryptography.fernet import base64 + +from settings import YOTI_API_URL, YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH + +from yoti_python_sdk.digital_identity import ( + DigitalIdentityClient +) + +app = Flask(__name__) + +@app.route("/") +def index(): + return render_template("index.html") + +@app.route("/sessions") +def sessions(): + session_config = { + "policy": { + "wanted": [ + { + "name": "date_of_birth", + "derivation": "age_over:18", + "optional": "false" + } + , + { + "name": "full_name" + }, + { + "name": "email_address" + }, + { + "name": "phone_number" + }, + { + "name": "selfie" + }, + { + "name": "date_of_birth", + "derivation": "age_over:18" + }, + { + "name": "nationality" + }, + { + "name": "gender" + }, + { + "name": "document_details" + }, + { + "name": "document_images" + }], + "wanted_auth_types": [], + "wanted_remember_me": "false", + }, + "extensions": [], + "subject": { + "subject_id": "some_subject_id_string" + }, # Optional reference to a user ID + "notification": { + "url": "https://webhook.site/818dc66b-e18b-4767-92c5-47c7af21629c", + "method": "POST", + "headers": {}, + "verifyTls": "true" + }, + "redirectUri": "/profile" # Mandatory redirect URI but not required for Non-browser flows + } + + digital_identity_client = DigitalIdentityClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH, YOTI_API_URL) + + share_session_result = digital_identity_client.create_share_session(session_config) + + session_id = share_session_result.id + + # create_qr_code_result = create_share_qr_code(share_session_result.id) + # get_share_session_result = get_share_session(share_session_result.id) + # get_qr_code_result = get_share_qr_code(create_qr_code_result.id) + + # Return Session ID JSON + return json.dumps({"session_id": session_id}) + +@app.route("/create-qr-code") +def create_qr_code(): + # Get query params - sessionId + session_id = request.args.get('sessionId') + digital_identity_client = DigitalIdentityClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH, YOTI_API_URL) + +# Create QR Code + create_qr_code_result = digital_identity_client.create_share_qr_code(session_id) + + # Return QR Code ID and URI JSON + return json.dumps({"qr_code_id": create_qr_code_result.id, "qr_code_uri": create_qr_code_result.uri}) + +@app.route("/render-qr-code") +def render_qr_code(): + # Get query params - qrCodeUri + qr_code_uri = request.args.get('qrCodeUri') + # Make a POST request to the API to create a QR Code image + url = "https://api.yoti.com/api/v1/qrcodes/image" + payload = { "url": str(qr_code_uri) } + headers = { + "Accept": "image/png", + "Content-Type": "application/json" + } + + response = requests.request("POST", url, json=payload, headers=headers) + + # Return QR Code Image as PNG + return Response(response.content, mimetype='image/png') + +@app.route("/profile") +def profile(): + # Get query params - receiptId + receipt_id = request.args.get('receiptId') + digital_identity_client = DigitalIdentityClient(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH, YOTI_API_URL) + + share_receipt = digital_identity_client.get_share_receipt(receipt_id) + age_over_verification = share_receipt.userContent.profile.find_age_over_verification(18) + selfie = share_receipt.userContent.profile.selfie.value + attribute_list = share_receipt.userContent.profile.attributes + full_name = share_receipt.userContent.profile.full_name.value + data = base64.b64encode(selfie).decode("utf-8") + selfie_image = "data:{0};base64,{1}".format("image/jpeg", data) + age_verified = age_over_verification.result + + return render_template("profile.html", age_verified=age_verified, selfie=selfie, full_name=full_name, selfie_image=selfie_image, attribute_list = attribute_list) + +if __name__ == "__main__": + app.run(host="0.0.0.0", ssl_context="adhoc") diff --git a/examples/digitalidentity/keys/.gitignore b/examples/digitalidentity/keys/.gitignore new file mode 100644 index 00000000..612424a3 --- /dev/null +++ b/examples/digitalidentity/keys/.gitignore @@ -0,0 +1 @@ +*.pem \ No newline at end of file diff --git a/examples/digitalidentity/requirements.in b/examples/digitalidentity/requirements.in new file mode 100644 index 00000000..b0d3fbd8 --- /dev/null +++ b/examples/digitalidentity/requirements.in @@ -0,0 +1,3 @@ +flask>=3.0.1 +python-dotenv>=1.0.1 +yoti>=2.15 diff --git a/examples/digitalidentity/requirements.txt b/examples/digitalidentity/requirements.txt new file mode 100644 index 00000000..5a69a26b --- /dev/null +++ b/examples/digitalidentity/requirements.txt @@ -0,0 +1,60 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --output-file=requirements.txt requirements.in +# +asn1==2.2.0 + # via yoti +blinker==1.7.0 + # via flask +certifi==2023.11.17 + # via requests +cffi==1.16.0 + # via cryptography +charset-normalizer==3.3.2 + # via requests +click==8.1.7 + # via flask +cryptography==42.0.1 + # via + # pyopenssl + # yoti +deprecated==1.2.10 + # via yoti +flask==3.0.1 + # via -r requirements.in +future==0.18.3 + # via yoti +idna==3.6 + # via requests +iso8601==0.1.13 + # via yoti +itsdangerous==2.1.2 + # via flask +jinja2==3.1.3 + # via flask +markupsafe==2.1.4 + # via + # jinja2 + # werkzeug +protobuf==3.20.1 + # via yoti +pycparser==2.21 + # via cffi +pyopenssl==24.0.0 + # via yoti +python-dotenv==1.0.1 + # via -r requirements.in +pytz==2022.1 + # via yoti +requests==2.31.0 + # via yoti +urllib3==2.1.0 + # via requests +werkzeug==3.0.1 + # via flask +wrapt==1.16.0 + # via deprecated +yoti==2.15 + # via -r requirements.in diff --git a/examples/digitalidentity/settings.py b/examples/digitalidentity/settings.py new file mode 100644 index 00000000..cc48730b --- /dev/null +++ b/examples/digitalidentity/settings.py @@ -0,0 +1,16 @@ +from os import environ +from os.path import dirname, join + +from dotenv import load_dotenv + +dotenv_path = join(dirname(__file__), ".env") +load_dotenv(dotenv_path) + +YOTI_CLIENT_SDK_ID = environ.get("YOTI_CLIENT_SDK_ID", None) +YOTI_KEY_FILE_PATH = environ.get("YOTI_KEY_FILE_PATH", None) +YOTI_API_URL = environ.get("YOTI_API_URL", "https://api.yoti.com/share") + +if YOTI_CLIENT_SDK_ID is None or YOTI_KEY_FILE_PATH is None: + raise ValueError("YOTI_CLIENT_SDK_ID or YOTI_KEY_FILE_PATH is None") + +YOTI_APP_BASE_URL = environ.get("YOTI_APP_BASE_URL", "https://127.0.0.1:8000") diff --git a/examples/digitalidentity/static/assets/app-store-badge.png b/examples/digitalidentity/static/assets/app-store-badge.png new file mode 100644 index 00000000..3ec996cc Binary files /dev/null and b/examples/digitalidentity/static/assets/app-store-badge.png differ diff --git a/examples/digitalidentity/static/assets/app-store-badge@2x.png b/examples/digitalidentity/static/assets/app-store-badge@2x.png new file mode 100644 index 00000000..84b34068 Binary files /dev/null and b/examples/digitalidentity/static/assets/app-store-badge@2x.png differ diff --git a/examples/digitalidentity/static/assets/company-logo.jpg b/examples/digitalidentity/static/assets/company-logo.jpg new file mode 100644 index 00000000..551474bf Binary files /dev/null and b/examples/digitalidentity/static/assets/company-logo.jpg differ diff --git a/examples/digitalidentity/static/assets/google-play-badge.png b/examples/digitalidentity/static/assets/google-play-badge.png new file mode 100644 index 00000000..761f237b Binary files /dev/null and b/examples/digitalidentity/static/assets/google-play-badge.png differ diff --git a/examples/digitalidentity/static/assets/google-play-badge@2x.png b/examples/digitalidentity/static/assets/google-play-badge@2x.png new file mode 100644 index 00000000..46707cea Binary files /dev/null and b/examples/digitalidentity/static/assets/google-play-badge@2x.png differ diff --git a/examples/digitalidentity/static/assets/icons/address.svg b/examples/digitalidentity/static/assets/icons/address.svg new file mode 100644 index 00000000..f7d9b2a7 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/address.svg @@ -0,0 +1,3 @@ + diff --git a/examples/digitalidentity/static/assets/icons/calendar.svg b/examples/digitalidentity/static/assets/icons/calendar.svg new file mode 100644 index 00000000..4f6b9bb7 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/calendar.svg @@ -0,0 +1,5 @@ + diff --git a/examples/digitalidentity/static/assets/icons/chevron-down-grey.svg b/examples/digitalidentity/static/assets/icons/chevron-down-grey.svg new file mode 100644 index 00000000..6753becb --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/chevron-down-grey.svg @@ -0,0 +1,7 @@ + + diff --git a/examples/digitalidentity/static/assets/icons/document.svg b/examples/digitalidentity/static/assets/icons/document.svg new file mode 100644 index 00000000..4c41271e --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/document.svg @@ -0,0 +1,3 @@ + diff --git a/examples/digitalidentity/static/assets/icons/email.svg b/examples/digitalidentity/static/assets/icons/email.svg new file mode 100644 index 00000000..c4582d6e --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/email.svg @@ -0,0 +1,14 @@ + diff --git a/examples/digitalidentity/static/assets/icons/gender.svg b/examples/digitalidentity/static/assets/icons/gender.svg new file mode 100644 index 00000000..af5c5772 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/gender.svg @@ -0,0 +1,5 @@ + diff --git a/examples/digitalidentity/static/assets/icons/nationality.svg b/examples/digitalidentity/static/assets/icons/nationality.svg new file mode 100644 index 00000000..e57d7522 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/nationality.svg @@ -0,0 +1,3 @@ + diff --git a/examples/digitalidentity/static/assets/icons/phone.svg b/examples/digitalidentity/static/assets/icons/phone.svg new file mode 100644 index 00000000..b19cce04 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/phone.svg @@ -0,0 +1,3 @@ + diff --git a/examples/digitalidentity/static/assets/icons/profile.svg b/examples/digitalidentity/static/assets/icons/profile.svg new file mode 100644 index 00000000..5c514fc1 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/profile.svg @@ -0,0 +1,3 @@ + diff --git a/examples/digitalidentity/static/assets/icons/verified.svg b/examples/digitalidentity/static/assets/icons/verified.svg new file mode 100644 index 00000000..7ca4dbb3 --- /dev/null +++ b/examples/digitalidentity/static/assets/icons/verified.svg @@ -0,0 +1,6 @@ + diff --git a/examples/digitalidentity/static/assets/logo.png b/examples/digitalidentity/static/assets/logo.png new file mode 100644 index 00000000..c60227fa Binary files /dev/null and b/examples/digitalidentity/static/assets/logo.png differ diff --git a/examples/digitalidentity/static/assets/logo@2x.png b/examples/digitalidentity/static/assets/logo@2x.png new file mode 100644 index 00000000..9f29784d Binary files /dev/null and b/examples/digitalidentity/static/assets/logo@2x.png differ diff --git a/examples/digitalidentity/static/index.css b/examples/digitalidentity/static/index.css new file mode 100644 index 00000000..e3184163 --- /dev/null +++ b/examples/digitalidentity/static/index.css @@ -0,0 +1,152 @@ +.yoti-body { + margin: 0; +} + +.yoti-top-section { + display: flex; + flex-direction: column; + padding: 38px 0; + background-color: #f7f8f9; + align-items: center; +} + +.yoti-logo-section { + margin-bottom: 25px; +} + +.yoti-logo-image { + display: block; +} + +.yoti-top-header { + font-family: Roboto, sans-serif; + font-size: 40px; + font-weight: 700; + line-height: 1.2; + margin-top: 0; + margin-bottom: 80px; + text-align: center; + color: #000; +} + +@media (min-width: 600px) { + .yoti-top-header { + line-height: 1.4; + } +} + +.yoti-sdk-integration-section { + margin: 30px 0; +} + +#yoti-share-button { + width: 250px; + height: 45px; +} + +.yoti-login-or-separator { + text-transform: uppercase; + font-family: Roboto; + font-size: 16px; + font-weight: bold; + line-height: 1.5; + text-align: center; + margin-top: 30px; +} + +.yoti-login-dialog { + display: grid; + box-sizing: border-box; + width: 100%; + padding: 35px 38px; + border-radius: 5px; + background: #fff; + grid-gap: 25px; +} + +@media (min-width: 600px) { + .yoti-login-dialog { + width: 560px; + padding: 35px 88px; + } +} + +.yoti-login-dialog-header { + font-family: Roboto, sans-serif; + font-size: 24px; + font-weight: 700; + line-height: 1.1; + margin: 0; + color: #000; +} + +.yoti-input { + font-family: Roboto, sans-serif; + font-size: 16px; + line-height: 1.5; + box-sizing: border-box; + padding: 12px 15px; + color: #000; + border: solid 2px #000; + border-radius: 4px; + background-color: #fff; +} + +.yoti-login-actions { + display: flex; + justify-content: space-between; + align-items: center; +} + +.yoti-login-forgot-button { + font-family: Roboto, sans-serif; + font-size: 16px; + text-transform: capitalize; +} + +.yoti-login-button { + font-family: Roboto, sans-serif; + font-size: 16px; + box-sizing: border-box; + width: 145px; + height: 50px; + text-transform: uppercase; + color: #fff; + border: 0; + background-color: #000; +} + +.yoti-sponsor-app-section { + display: flex; + flex-direction: column; + padding: 70px 0; + align-items: center; +} + +.yoti-sponsor-app-header { + font-family: Roboto, sans-serif; + font-size: 20px; + font-weight: 700; + line-height: 1.2; + margin: 0; + text-align: center; + color: #000; +} + +.yoti-store-buttons-section { + margin-top: 40px; + display: grid; + grid-gap: 10px; + grid-template-columns: 1fr; +} + +@media (min-width: 600px) { + .yoti-store-buttons-section { + grid-template-columns: 1fr 1fr; + grid-gap: 25px; + } +} + +.yoti-app-button-link { + text-decoration: none; +} diff --git a/examples/digitalidentity/static/profile.css b/examples/digitalidentity/static/profile.css new file mode 100644 index 00000000..80871acd --- /dev/null +++ b/examples/digitalidentity/static/profile.css @@ -0,0 +1,420 @@ +.yoti-html { + height: 100%; +} + +.yoti-body { + margin: 0; + height: 100%; +} + +.yoti-icon-profile, +.yoti-icon-phone, +.yoti-icon-email, +.yoti-icon-calendar, +.yoti-icon-verified, +.yoti-icon-address, +.yoti-icon-gender, +.yoti-icon-nationality { + display: inline-block; + height: 28px; + width: 28px; + flex-shrink: 0; +} + +.yoti-icon-profile { + background: no-repeat url('/static/assets/icons/profile.svg'); +} + +.yoti-icon-phone { + background: no-repeat url('/static/assets/icons/phone.svg'); +} + +.yoti-icon-email { + background: no-repeat url('/static/assets/icons/email.svg'); +} + +.yoti-icon-calendar { + background: no-repeat url('/static/assets/icons/calendar.svg'); +} + +.yoti-icon-verified { + background: no-repeat url('/static/assets/icons/verified.svg'); +} + +.yoti-icon-address { + background: no-repeat url('/static/assets/icons/address.svg'); +} + +.yoti-icon-gender { + background: no-repeat url('/static/assets/icons/gender.svg'); +} + +.yoti-icon-nationality { + background: no-repeat url('/static/assets/icons/nationality.svg'); +} + +.yoti-profile-layout { + display: grid; + grid-template-columns: 1fr; +} + +@media (min-width: 1100px) { + .yoti-profile-layout { + grid-template-columns: 360px 1fr; + height: 100%; + } +} + +.yoti-profile-user-section { + display: flex; + align-items: center; + justify-content: space-between; + flex-direction: column; + padding: 40px 0; + background-color: #f7f8f9; +} + +@media (min-width: 1100px) { + .yoti-profile-user-section { + display: grid; + grid-template-rows: repeat(3, min-content); + align-items: center; + justify-content: center; + position: relative; + } +} + +.yoti-profile-picture-image { + width: 220px; + height: 220px; + border-radius: 50%; + margin-left: auto; + margin-right: auto; + display: block; +} + +.yoti-profile-picture-powered, +.yoti-profile-picture-account-creation { + font-family: Roboto; + font-size: 14px; + color: #b6bfcb; +} + +.yoti-profile-picture-powered-section { + display: flex; + flex-direction: column; + text-align: center; + align-items: center; +} + +@media (min-width: 1100px) { + .yoti-profile-picture-powered-section { + align-self: start; + } +} + +.yoti-profile-picture-powered { + margin-bottom: 20px; +} + +.yoti-profile-picture-section { + display: flex; + flex-direction: column; + align-items: center; +} + +@media (min-width: 1100px) { + .yoti-profile-picture-section { + position: absolute; + top: 50%; + transform: translateY(-50%); + width: 100%; + } +} + +.yoti-logo-image { + margin-bottom: 25px; +} + +.yoti-profile-picture-area { + position: relative; + display: inline-block; +} + +.yoti-profile-picture-verified-icon { + display: block; + background: no-repeat url("/static/assets/icons/verified.svg"); + background-size: cover; + height: 40px; + width: 40px; + position: absolute; + top: 10px; + right: 10px; +} + +.yoti-profile-name { + margin-top: 20px; + font-family: Roboto, sans-serif; + font-size: 24px; + text-align: center; + color: #333b40; +} + +.yoti-attributes-section { + display: flex; + flex-direction: column; + justify-content: start; + align-items: center; + width: 100%; + padding: 40px 0; +} + + .yoti-attributes-section.-condensed { + padding: 0; + } + +@media (min-width: 1100px) { + .yoti-attributes-section { + padding: 60px 0; + align-items: start; + overflow-y: scroll; + } + + .yoti-attributes-section.-condensed { + padding: 0; + } +} + +.yoti-company-logo { + margin-bottom: 40px; +} + +@media (min-width: 1100px) { + .yoti-company-logo { + margin-left: 130px; + } +} + +/* extended layout list */ +.yoti-attribute-list-header, +.yoti-attribute-list-subheader { + display: none; +} + +@media (min-width: 1100px) { + .yoti-attribute-list-header, + .yoti-attribute-list-subheader { + width: 100%; + display: grid; + grid-template-columns: 200px 1fr 1fr; + grid-template-rows: 40px; + align-items: center; + text-align: center; + font-family: Roboto; + font-size: 14px; + color: #b6bfcb; + } +} + +.yoti-attribute-list-header-attribute, +.yoti-attribute-list-header-value { + justify-self: start; + padding: 0 20px; +} + +.yoti-attribute-list-subheader { + grid-template-rows: 30px; +} + +.yoti-attribute-list-subhead-layout { + grid-column: 3; + display: grid; + grid-template-columns: 1fr 1fr 1fr; +} + +.yoti-attribute-list { + display: grid; + width: 100%; +} + +.yoti-attribute-list-item:first-child { + border-top: 2px solid #f7f8f9; +} + +.yoti-attribute-list-item { + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: minmax(60px, auto); + border-bottom: 2px solid #f7f8f9; + border-right: none; + border-left: none; +} + + .yoti-attribute-list-item.-condensed { + grid-template-columns: 50% 50%; + padding: 5px 35px; + } + +@media (min-width: 1100px) { + .yoti-attribute-list-item { + display: grid; + grid-template-columns: 200px 1fr 1fr; + grid-template-rows: minmax(80px, auto); + } + + .yoti-attribute-list-item.-condensed { + grid-template-columns: 200px 1fr; + padding: 0 75px; + } +} + +.yoti-attribute-cell { + display: flex; + align-items: center; +} + +.yoti-attribute-name { + grid-column: 1 / 2; + display: flex; + align-items: center; + justify-content: center; + border-right: 2px solid #f7f8f9; + padding: 20px; +} + +@media (min-width: 1100px) { + .yoti-attribute-name { + justify-content: start; + } +} + +.yoti-attribute-name.-condensed { + justify-content: start; +} + +.yoti-attribute-name-cell { + display: flex; + align-items: center; +} + +.yoti-attribute-name-cell-text { + font-family: Roboto, sans-serif; + font-size: 16px; + color: #b6bfcb; + margin-left: 12px; +} + +.yoti-attribute-value { + grid-column: 2 / 3; + display: flex; + align-items: center; + justify-content: center; + padding: 20px; +} + +@media (min-width: 1100px) { + .yoti-attribute-value { + justify-content: start; + } +} + +.yoti-attribute-value.-condensed { + justify-content: start; +} + +.yoti-attribute-value-text { + font-family: Roboto, sans-serif; + font-size: 18px; + color: #333b40; + word-break: break-word; +} + + .yoti-attribute-value-text table { + font-size: 14px; + border-spacing: 0; + } + + .yoti-attribute-value-text table td:first-child { + font-weight: bold; + } + + .yoti-attribute-value-text table td { + border-bottom: 1px solid #f7f8f9; + padding: 5px; + } + + .yoti-attribute-value-text img { + width: 100%; + } + +.yoti-attribute-anchors-layout { + grid-column: 1 / 3; + grid-row: 2 / 2; + display: grid; + grid-template-columns: 1fr 1fr 1fr; + grid-auto-rows: minmax(40px, auto); + font-family: Roboto, sans-serif; + font-size: 14px; + background-color: #f7f8f9; + border: 5px solid white; +} + +@media (min-width: 1100px) { + .yoti-attribute-anchors-layout { + grid-column: 3 / 4; + grid-row: 1 / 2; + } +} + +.yoti-attribute-anchors-head { + border-bottom: 1px solid #dde2e5; + display: flex; + align-items: center; + justify-content: center; +} + +@media (min-width: 1100px) { + .yoti-attribute-anchors-head { + display: none; + } +} + +.yoti-attribute-anchors { + display: flex; + align-items: center; + justify-content: center; +} + +.yoti-attribute-anchors-head.-s-v { + grid-column-start: span 1 s-v; +} + +.yoti-attribute-anchors-head.-value { + grid-column-start: span 1 value; +} + +.yoti-attribute-anchors-head.-subtype { + grid-column-start: span 1 subtype; +} + +.yoti-attribute-anchors.-s-v { + grid-column-start: span 1 s-v; +} + +.yoti-attribute-anchors.-value { + grid-column-start: span 1 value; +} + +.yoti-attribute-anchors.-subtype { + grid-column-start: span 1 subtype; +} + +.yoti-edit-section { + padding: 50px 20px; +} + +@media (min-width: 1100px) { + .yoti-edit-section { + padding: 75px 110px; + } +} diff --git a/examples/digitalidentity/templates/index.html b/examples/digitalidentity/templates/index.html new file mode 100644 index 00000000..4485799f --- /dev/null +++ b/examples/digitalidentity/templates/index.html @@ -0,0 +1,98 @@ + + + +
+ + +bb{{ key }} + {{ value | tojson(indent=2) }}+ |
+
Type | {{ attribute_list[attribute].value.document_type }} |
Issuing Country | {{ attribute_list[attribute].value.issuing_country }} |
Issuing Authority | {{ attribute_list[attribute].value.issuing_authority }} |
Document Number | {{ attribute_list[attribute].value.document_number }} |
Expiration Date | {{ attribute_list[attribute].value.expiration_date }} |