diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index fa28630..0000000 --- a/AGENTS.md +++ /dev/null @@ -1,48 +0,0 @@ -# AGENTS.md - -## Project identity -- **Name**: idv-demo — Jumio identity verification (KYC/KYB) demo app -- **Stack**: vanilla PHP (no framework, no Composer), nginx + PHP-FPM -- **Owner**: customer-engineering / Sechpoint - -## Repo setup -- **Git remote**: `https://git.sechpoint.app/customer-engineering/idv-demo.git` -- **Credentials**: source `~/bin/.gitenv` for `GIT_USER_NAME`, `GIT_USER_EMAIL`, `GIT_TOKEN` -- **Default branch**: `main` -- **Commit prefix convention**: `chore:` - -## Architecture (non-obvious) - -``` -html/ → web root (deploys as /var/www/html/public — see nginx config) - index.php → single entry point (front controller) - class/ → core: config.php, site.php (session init), functions.php - app/ - controler/ → routing: start.php (GET pages), request.php (POST actions) - model/ → Jumio API calls: M01.php, M04.php, docv.php, retrival_1.php, retrival_2.php, success.php - view/ → .phtml templates (header, footer, pages 00–04, loader, results) - cdn/ → static assets (JS includes iovation/IGLOO blackbox) - lng/ → language strings: en/ (default), de/ -nginx/ → nginx site config (serves from /var/www/html/public, PHP-FPM via socket) -``` - -- **No build tools, no tests, no CI/CD, no package manager** — it's raw PHP. -- Routing: URL segments drive pages (`$PARAMS[1]` in start.php); POST/GET `do` parameter drives actions (request.php). -- Jumio workflow: M01 (ID verification) → docv (document verification) → retrival → results. - -## Dev mode -- Hostname starting with `dev` sets `DEBUG = TRUE` (`html/class/config.php` line 28). -- When DEBUG is true, `debug_log()` writes to `html/log/YYYYMM.log`. The `log/` directory must exist and be writable. - -## Secrets warning -- `html/class/config.php` contains hardcoded Jumio API credentials. **Do not commit to public repos.** - -## Nginx -- Active config: `nginx/default.conf` -- PHP-FPM socket: `unix:/run/php-fpm.sock` -- Clean URLs via `try_files $uri $uri/ /index.php?$args` -- Stale backup files in `nginx/`: `default_old.conf`, `default.conf.bak`, `default.bak.3.conf` - -## Gotchas -- Filename `retrival` is intentionally misspelled (not "retrieval") — used consistently in `retrival_1.php`, `retrival_2.php`, and session keys. -- `html/` contains `.DS_Store` (macOS artifact) — should be gitignored. diff --git a/html/app/controler/dev.php b/html/app/controler/dev.php index 0c3c283..9be73ce 100644 --- a/html/app/controler/dev.php +++ b/html/app/controler/dev.php @@ -21,17 +21,12 @@ ##################################################################################### if (!empty($PARAMS['2'])) { - if (DEBUG) { + if (DEBUG) { switch ($PARAMS['2']) { -//==========>> - case 'workbanch': - include(__ROOT__.'/app/model/workbanch.php'); - break; - //==========>> case 'test': - include(__ROOT__.'/app/view/test.html'); + include(__ROOT__.'/app/view/dev_test.html'); break; - //==========>> + case 'clear': session_unset(); session_destroy(); diff --git a/html/app/controler/request.php b/html/app/controler/request.php index aeb1156..41693c3 100644 --- a/html/app/controler/request.php +++ b/html/app/controler/request.php @@ -64,6 +64,21 @@ if(!empty($HTML_REQUEST['do'])){ exit; break; + case 'login': + include(__ROOT__.'/app/model/login.php'); + exit; + break; + + case 'reset': + include(__ROOT__.'/app/model/reset.php'); + exit; + break; + + case 'pwless': + include(__ROOT__.'/app/model/pwless.php'); + exit; + break; + case 'callback': echo "callback"; #include(__ROOT__.'/app/model/callback.php'); diff --git a/html/app/controler/start.php b/html/app/controler/start.php index df4d641..4f7737a 100644 --- a/html/app/controler/start.php +++ b/html/app/controler/start.php @@ -4,7 +4,7 @@ if (!empty($PARAMS['1'])) { //==========>> MENUE OPTIONS case 'home': include(__ROOT__.'/app/view/_header.phtml'); - include(__ROOT__.'/app/view/page_00.phtml'); + include(__ROOT__.'/app/view/page_home.phtml'); include(__ROOT__.'/app/view/_footer.phtml'); break; case 'one': @@ -57,11 +57,7 @@ if (!empty($PARAMS['1'])) { break; //==========>> FUNCTIONAL OPTIONS case 'dev': - include(__ROOT__.'/app/controler/development.php'); - break; - - case 'q5b35W4M3cWt': - include(__ROOT__.'/app/view/dev_demo.html'); + include(__ROOT__.'/app/controler/dev.php'); break; case 'clear': diff --git a/html/app/model/login.php b/html/app/model/login.php new file mode 100644 index 0000000..bf47990 --- /dev/null +++ b/html/app/model/login.php @@ -0,0 +1,17 @@ + "https://retrieval.".$_SESSION['SITE']['datacenter']."/api/v1/accounts/".$_SESSION['TRANSACTION']["RETURN"]['accountId']."/workflow-executions/".$_SESSION['TRANSACTION']["RETURN"]['workflowExecutionId']."/status", - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => "", - CURLOPT_MAXREDIRS => 10, - CURLOPT_TIMEOUT => 30, - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => "GET", - CURLOPT_HTTPHEADER => [ - "Authorization: Bearer ". $access_token , - "Content-Type: application/json", - "User-Agent: Jumio SE Testing" - ], - ]); - // Look to check Jumio Result. - do { - $response = curl_exec($curl); - $err = curl_error($curl); - if ($err) { - $_SESSION['SITE']['ERROR']="cURL Error #:" . $err; - $_SESSION['SITE']['ERROR']['API']=array(); - $_SESSION['SITE']['ERROR']['API']=$response_json; - debug_log("API ERROR",json_encode($_SESSION, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT )); - $error_msg=ERROR_501; - include(__ROOT__.'/app/view/_header.phtml'); - include(__ROOT__.'/app/view/page_error.phtml'); - include(__ROOT__.'/app/view/_footer.phtml'); - break; - } else { - $retrival_status=array(); - $retrival_status=json_decode($response,TRUE); - } - print_r($retrival_status); - if ($retrival_status["workflowExecution"]["status"] === "PROCESSED") { break; } - sleep(10); - $retry_count++; - } while ($retry_count < $max_retries); - break; -} -//==================================================== -echo '
'.json_encode($_SESSION, JSON_PRETTY_PRINT).'
';exit; diff --git a/html/app/view/dev_demo.html b/html/app/view/dev_demo.html deleted file mode 100644 index 53bf955..0000000 --- a/html/app/view/dev_demo.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - Start Jumio Demo - - - - - -
-

Please click to initiate your Demo!

-
- - diff --git a/html/app/view/page_00.phtml b/html/app/view/page_00.phtml deleted file mode 100644 index 105c397..0000000 --- a/html/app/view/page_00.phtml +++ /dev/null @@ -1,10 +0,0 @@ - -
-
-
-
-
-
-
-
diff --git a/html/app/view/page_02.phtml b/html/app/view/page_02.phtml index 012bba7..f19bb02 100644 --- a/html/app/view/page_02.phtml +++ b/html/app/view/page_02.phtml @@ -4,7 +4,14 @@
-
-
-
+
+
+ +
+ + +
+
+ +
diff --git a/html/app/view/page_03.phtml b/html/app/view/page_03.phtml index cecf0c9..59ed94b 100644 --- a/html/app/view/page_03.phtml +++ b/html/app/view/page_03.phtml @@ -4,7 +4,9 @@
-
-
-
+
+
+ + +
diff --git a/html/app/view/page_home.phtml b/html/app/view/page_home.phtml new file mode 100644 index 0000000..c735f99 --- /dev/null +++ b/html/app/view/page_home.phtml @@ -0,0 +1,23 @@ + +
+
+
+
+
+
+
+
+ +
+
Welcome to the Demo
+
Please enter your email to access the demonstration.
+
+ +
+ + +
+ +
+
+ diff --git a/html/class/config.php b/html/class/config.php index 4f9b7d7..1e3a489 100644 --- a/html/class/config.php +++ b/html/class/config.php @@ -31,8 +31,5 @@ // API Credentials for IDV - $api_key = '2b2i83jup3eu2tr3tn581kl2dc'; - $api_secret = '1vat6laeka5gv8riltk1j0hqlguo80bue3q6gvrnk9u3f2adl39i'; - $api_token = base64_encode($api_key . ":" . $api_secret); - define( 'API_URL' , 'emea-1.jumio.ai'); - define( 'API_TOKEN' , $api_token); + define( 'API_DATACENTER' , 'emea-1.jumio.ai'); + define( 'API_TOKEN' , base64_encode('2b2i83jup3eu2tr3tn581kl2dc' . ':' . '1vat6laeka5gv8riltk1j0hqlguo80bue3q6gvrnk9u3f2adl39i')); diff --git a/html/class/site.php b/html/class/site.php index 56c3e5c..dab0000 100644 --- a/html/class/site.php +++ b/html/class/site.php @@ -28,21 +28,13 @@ if(empty($_SESSION)){ $_SESSION['SITE']['arrived']=gmdate(DATE_ATOM); $_SESSION['SITE']['client_ip']=''; $_SESSION['SITE']['site_url'] = 'https://'.$_SERVER["HTTP_HOST"].'/'; - $_SESSION['SITE']['apiToken']=''; - $_SESSION['SITE']['datacenter']=''; + $_SESSION['SITE']['apiToken']=API_TOKEN; + $_SESSION['SITE']['datacenter']=API_DATACENTER; $_SESSION['SITE']['language']=''; $_SESSION['SITE']['access']='false'; -// check if language is suppoted +// check if language is supported $activeLanguage=substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2); - switch ($activeLanguage) { - case 'de': - $_SESSION['SITE']['language']='de'; - break; - - default: - $_SESSION['SITE']['language']='en'; - break; - } + $_SESSION['SITE']['language']='en'; // -------- GET CLIENT IP ----------------------------------------------------------------- if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { //to check ip is pass from proxy $_SESSION['SITE']['client_ip']=$_SERVER['HTTP_X_FORWARDED_FOR']; diff --git a/html/index.php b/html/index.php index b0ab521..edad551 100644 --- a/html/index.php +++ b/html/index.php @@ -27,14 +27,12 @@ require_once('./lng/'.$_SESSION['SITE']['language'].'/default.php'); require_once('./class/functions.php'); //// CAPTURE HTML_REQUESTS ///////////////////////////////////////////////////// -if (!empty($_POST)) { $HTML_REQUEST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);} -if (!empty($_GET)) { $HTML_REQUEST = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);} +if (!empty($_POST)) { $HTML_REQUEST = filter_input_array(INPUT_POST, FILTER_SANITIZE_FULL_SPECIAL_CHARS);} +if (!empty($_GET)) { $HTML_REQUEST = filter_input_array(INPUT_GET, FILTER_SANITIZE_FULL_SPECIAL_CHARS);} if (!empty($HTML_REQUEST)) { require_once(__ROOT__.'/app/controler/request.php'); } else { //// ROUTING /////////////////////////////////////////////////////////////////// - $REQUEST = ''; - $PARAMS = ''; - $REQUEST = str_replace("/", "/", $_SERVER['REQUEST_URI']); + $REQUEST = $_SERVER['REQUEST_URI']; $PARAMS = explode("/", $REQUEST); require_once(__ROOT__.'/app/controler/start.php'); } diff --git a/html/lng/de/default.php b/html/lng/de/default.php deleted file mode 100644 index a07a253..0000000 --- a/html/lng/de/default.php +++ /dev/null @@ -1,63 +0,0 @@ -> -// == PAGES -// == HOME -define('HOME_TITLE', 'HOME_TITLE'); -define('HOME_CONTENT', 'HOME_CONTENT'); -// == PAGE_LINK -define('PAGE_LINK_TITLE', 'PAGE_LINK_TITLE'); -define('PAGE_LINK_CONTENT', 'PAGE_LINK_CONTENT'); -//==========>> - -define('WALLET_TOP_UP_TITLE','Your e-wallet by iovation'); -define('WALLET_TOP_UP_CONTENT_1','Provide your login credential and the amount you wish to top-up.'); -define('WALLET_TOP_UP_CONTENT_2', ' -

You need to provide mock-up login credentials. You can use your email or invent an email but please ensue that you can remember the email and use the same email during testing. The email provide is converted in to a GDPR compliant fingerprint and stored on iovations servers. We use the email only as an account identifier. -You can invent a password and don`t need to remember this, we are not useing password verification for this mock-up demonstration.

-

-

You can controle the result of the fraud screening.

-Any amount below 100.00 will result in ALLOWED.
-Any amount between 100.01 and 199.99 will result in REVIEW
-Any amount over 200.00 will result in DENIED
-

-'); -//==========>> - -define('WALLET_CHECKOUT_A_TITLE','Card Payment'); -define('WALLET_CHECKOUT_A_CONTENT_1','This was a low risk transaction, therefore no liability shift through 3D secure is required.'); -define('WALLET_CHECKOUT_A_CONTENT_2',' -

Please provide a credit card number for testing. This can be any random number of 16 digits.For the card expiry date, -take any date from 2019 to 2029 and 4 random digits for the CVV number.

' -); -define('WALLET_CHECKOUT_AMT_FINAL', 'You will top up '); -define('WALLET_CHECKOUT_SUBMIT', 'execute top up'); - -//==========>> - -define('WALLET_CHECKOUT_D_TITLE', 'SEPA Instant Bank Payment'); -define('WALLET_CHECKOUT_D_CONTENT_1','This was a high risk transaction, therefore only SEPA instant bank payment is offerd.'); -define('WALLET_CHECKOUT_D_CONTENT_2',' -

Please provide a IBAN number for testing. This can be any random number of 16 digits.

' -); -//==========>> - -define('WALLET_CHECKOUT_R_TITLE', 'Card Payment'); -define('WALLET_CHECKOUT_R_CONTENT_1','This was a medium risk transaction, therefore a liability shift through 3D secure is initiated.'); -define('WALLET_CHECKOUT_R_CONTENT_2',' -

Please provide a credit card number for testing. This can be any random number of 16 digits.For the card expiry date, -take any date from 2019 to 2029 and 4 random digits for the CVV number.

' -); -//==========>> diff --git a/html/lng/en/default.php b/html/lng/en/default.php index 23d78a8..70b847c 100644 --- a/html/lng/en/default.php +++ b/html/lng/en/default.php @@ -1,59 +1,64 @@ -> First Level Pages -// =========>> PAGE_PAGE_HOME - define('PAGE_HOME_TITLE','Jumio KYX Platform Use-Case Demo'); - define('PAGE_HOME_CONTENT_1',''); - define('PAGE_HOME_CONTENT_2',''); - define('PAGE_HOME_CONTENT_3',''); - define('PAGE_HOME_CONTENT_4',''); - define('PAGE_HOME_CONTENT_5',''); - -// =========>> PAGE_ONE - define('PAGE_ONE_TITLE','ACME Holiday Homes'); - define('PAGE_ONE_CONTENT_1','Please fill out the form to register on our platform'); - define('PAGE_ONE_CONTENT_2',''); - define('PAGE_ONE_CONTENT_3',''); - define('PAGE_ONE_CONTENT_4',''); - define('PAGE_ONE_CONTENT_5',''); - - define('PAGE_TWO_TITLE','ACME Rent a Bike'); - define('PAGE_TWO_CONTENT_1',''); - define('PAGE_TWO_CONTENT_2',''); - define('PAGE_TWO_CONTENT_3',''); - define('PAGE_TWO_CONTENT_4',''); - define('PAGE_TWO_CONTENT_5',''); - - define('PAGE_THREE_TITLE','ACME Games'); - define('PAGE_THREE_CONTENT_1',''); - define('PAGE_THREE_CONTENT_2',''); - define('PAGE_THREE_CONTENT_3',''); - define('PAGE_THREE_CONTENT_4',''); - define('PAGE_THREE_CONTENT_5',''); - - define('PAGE_FOUR_TITLE','ACME Bank'); - define('PAGE_FOUR_CONTENT_1','Apply for your new ACME Account today'); - define('PAGE_FOUR_CONTENT_2','
'); - define('PAGE_FOUR_CONTENT_3',''); - define('PAGE_FOUR_CONTENT_4',''); - define('PAGE_FOUR_CONTENT_5',''); -// =========>> Second Level Pages <<======= - - -// == PAGE_ERRORS -define('ERROR_404', '

404 Not Found

The requested resource could not be found but may be available in the future.

'); -define('ERROR_501', '

500 Internal Server Error

A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.

'); +> First Level Pages +// =========>> PAGE_PAGE_HOME + define('PAGE_HOME_TITLE','1Kosmos Identity Platform Demo'); + define('PAGE_HOME_CONTENT_1',''); + define('PAGE_HOME_CONTENT_2',''); + define('PAGE_HOME_CONTENT_3',''); + define('PAGE_HOME_CONTENT_4',''); + define('PAGE_HOME_CONTENT_5',''); + +// =========>> PAGE_ONE — Account Onboarding (KYC) + define('PAGE_ONE_TITLE','Account Onboarding'); + define('PAGE_ONE_CONTENT_1','Identity verification and KYC for new account creation.'); + define('PAGE_ONE_CONTENT_2',''); + define('PAGE_ONE_CONTENT_3',''); + define('PAGE_ONE_CONTENT_4',''); + define('PAGE_ONE_CONTENT_5',''); + +// =========>> PAGE_TWO — Account Recovery + define('PAGE_TWO_TITLE','Account Recovery'); + define('PAGE_TWO_CONTENT_1','Enter your email to reset your password.'); + define('PAGE_TWO_CONTENT_2','You will receive a reset link at the address provided.'); + define('PAGE_TWO_CONTENT_2',''); + define('PAGE_TWO_CONTENT_3',''); + define('PAGE_TWO_CONTENT_4',''); + define('PAGE_TWO_CONTENT_5',''); + +// =========>> PAGE_THREE — Passwordless Sign‑in + define('PAGE_THREE_TITLE','Passwordless Sign‑in'); + define('PAGE_THREE_CONTENT_1','Click the button to sign in without a password.'); + define('PAGE_THREE_CONTENT_2','Your biometric or device credential will be used.'); + define('PAGE_THREE_CONTENT_2',''); + define('PAGE_THREE_CONTENT_3',''); + define('PAGE_THREE_CONTENT_4',''); + define('PAGE_THREE_CONTENT_5',''); + +// =========>> PAGE_FOUR + define('PAGE_FOUR_TITLE','Banking'); + define('PAGE_FOUR_CONTENT_1',''); + define('PAGE_FOUR_CONTENT_2',''); + define('PAGE_FOUR_CONTENT_3',''); + define('PAGE_FOUR_CONTENT_4',''); + define('PAGE_FOUR_CONTENT_5',''); +// =========>> Second Level Pages <<======= + + +// == PAGE_ERRORS +define('ERROR_404', '

404 Not Found

The requested resource could not be found but may be available in the future.

'); +define('ERROR_501', '

500 Internal Server Error

A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.

'); diff --git a/nginx/default.bak.3.conf b/nginx/default.bak.3.conf deleted file mode 100644 index 9eac48b..0000000 --- a/nginx/default.bak.3.conf +++ /dev/null @@ -1,35 +0,0 @@ -server { - listen [::]:80 default_server; - - root /var/www/html/public; - index index.php index.html; - charset utf-8; - server_name _; - -#Logging - access_log /var/log/nginx/access.log; - error_log /var/log/nginx/error.log notice; - -#handling Static files -# location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ { -# access_log off; -# expires max; -# } - -# Support Clean (aka Search Engine Friendly) URLs -# location / { -# try_files $uri $uri/ /index.php?$args ; -# } - -# Handling .php files - location ~ [^/]\.php(/|$) { - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - if (!-f $document_root$fastcgi_script_name) { - return 404; - } - include fastcgi_params; - fastcgi_pass unix:/run/php-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - } -} diff --git a/nginx/default.conf b/nginx/default.conf index c6702dd..d44ec82 100644 --- a/nginx/default.conf +++ b/nginx/default.conf @@ -1,6 +1,6 @@ server { listen 80 default_server; - root /var/www/html/public; + root /var/www/html; index index.php index.html; charset utf-8; server_name _; @@ -20,15 +20,11 @@ server { try_files $uri $uri/ /index.php?$args ; } -# Handling .php files - location ~ [^/]\.php(/|$) { - fastcgi_split_path_info ^(.+?\.php)(/.*)$; - if (!-f $document_root$fastcgi_script_name) { - return 404; - } - include fastcgi_params; - fastcgi_pass unix:/run/php-fpm.sock; - fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; - fastcgi_param PATH_INFO $fastcgi_path_info; - } +# Only index.php can execute PHP — all others blocked +location = /index.php { + include fastcgi_params; + fastcgi_pass unix:/run/php/php8.5-fpm.sock; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +} +location ~ \.php$ { return 404; } }