Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
abbaspour committed Feb 27, 2020
0 parents commit 394a804
Show file tree
Hide file tree
Showing 25 changed files with 380 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
vendor
.idea
*.lock
.env
env.js
94 changes: 94 additions & 0 deletions callback.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration - Callback</title>
<script src="env.js"></script>
<script src="http:https://cdn.auth0.com/js/auth0/9.12.2/auth0.min.js"></script>
</head>
<body>
<h1>Few more questions</h1>

<label for="given_name">Given name:</label>
<input type="text" id="given_name" name="given_name"><br><br>
<label for="family_name">Family name:</label>
<input type="text" id="family_name" name="family_name"><br><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password"><br><br>

<input type="submit" value="Create Account" onclick="submit()">

<script>
const auth0js = new auth0.WebAuth({
domain: AUTH0_DOMAIN,
clientID: AUTH0_CLIENT_ID,
redirectUri: SUCCESS_REDIRECT_URI,
responseType: 'id_token'
});

// TODO: add state & nonce check if want to enforce same browser
let access_token = getAccessToken();

auth0js.client.userInfo(access_token, function(err, user) {
if(err) {
console.log('invalid access token');
window.location.href = '/error.html?msg=' + err;
}
});

function create_user(access_token, given_name, family_name, password) {
let url = '/create-user.php';

let data = {
access_token: access_token,
given_name: given_name,
family_name: family_name,
password: password
};

const params = {
headers: {'content-type': 'application/json'},
method: 'POST',
body: JSON.stringify(data)
};

fetch(url, params)
.then(data => data.json())
.then(value => {
auth0js.login(
{
'email' : value.email,
'password' : password,
'realm' : value.connection,
},
err => {
window.location.href = '/error.html?msg=' + err;
}
);
})
.catch(err => console.log('error in create-user call: ' + err));
}

function submit() {
let given_name = document.getElementById('given_name').value;
let family_name = document.getElementById('family_name').value;
let password = document.getElementById('password').value;
create_user(access_token, given_name, family_name, password);
}

function getParameterByName(name) {
var match = RegExp('[#&]' + name + '=([^&]*)').exec(window.location.hash);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}

function getAccessToken() {
return getParameterByName('access_token');
}

</script>
</body>
</html>



21 changes: 21 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "tab registration poc",
"description": "tabcorp registration poc",
"require": {
"vlucas/phpdotenv": "^3.6.0",
"auth0/auth0-PHP": "dev-master",
"google/recaptcha": "^1.2"
},
"repositories": [
{
"type": "git",
"url": "https://github.com/abbaspour/auth0-PHP.git"
}
],
"authors": [
{
"name": "Amin Abbaspour",
"email": "[email protected]"
}
]
}
80 changes: 80 additions & 0 deletions create-user.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php
$data = json_decode(file_get_contents('php:https://input'), true);

$given_name = $data["given_name"];
$family_name = $data["family_name"];
$password = $data["password"];
$access_token = $data["access_token"];

if(! (isset($given_name) && isset($family_name) && isset($password) && isset($access_token))) {
die('missing input');
}

header('Content-Type: application/json');

require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/dotenv-loader.php';

use \Auth0\SDK\API\Authentication;

$auth0_api = new Authentication(
getenv('AUTH0_DOMAIN'),
getenv('AUTH0_CLIENT_ID'),
getenv('AUTH0_CLIENT_SECRET')
);

$pwl_user_info = $auth0_api->userinfo($access_token);

$email = $pwl_user_info['email'];
if(! isset($email)) {
die('email missing');
}

$config = [
'client_secret' => getenv('AUTH0_CLIENT_SECRET'),
'client_id' => getenv('AUTH0_CLIENT_ID'),
'audience' => getenv('AUTH0_MANAGEMENT_AUDIENCE'),
];

try {
$result = $auth0_api->client_credentials($config);
} catch (Exception $e) {
die( $e->getMessage() );
}

$access_token = $result["access_token"];

use Auth0\SDK\API\Management;

$mgmt_api = new Management( $access_token, getenv('AUTH0_DOMAIN') );

$username = rand(); // get username from backend database

$DB_CONNECTION_NAME = getenv('DB_CONNECTION_NAME');

$user_data = array(
'connection' => $DB_CONNECTION_NAME,
'given_name' => $given_name,
'family_name' => $family_name,
'email' => $email,
'username' => "$username",
'password' => $password,
'email_verified'=> true,
'verify_email' => false);

try {
$create_result = $mgmt_api->users()->create($user_data);
} catch (Exception $e) {
die( $e->getMessage() );
}

try {
$delete_result = $mgmt_api->users()->delete($pwl_user_info['sub']);
} catch (Exception $e) {
die( $e->getMessage() );
}


$result = array('success' => true, 'user_id' => $create_result['user_id'], 'email' => $email, 'connection' => $DB_CONNECTION_NAME );

echo json_encode($result, JSON_PRETTY_PRINT);
8 changes: 8 additions & 0 deletions dotenv-loader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
// Read .env
try {
$dotenv = Dotenv\Dotenv::create(__DIR__);
$dotenv->load();
} catch(\Dotenv\Exception\InvalidPathException $ex) {
// Ignore if no dotenv
}
10 changes: 10 additions & 0 deletions env-sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
AUTH0_CLIENT_ID=XXX
AUTH0_DOMAIN=XXX.auth0.com
AUTH0_CLIENT_SECRET=XXXX
AUTH0_CALLBACK_URL=http:https://app1.com:3001/callback.html
AUTH0_MANAGEMENT_AUDIENCE=https://XXX.auth0.com/api/v2/
DB_CONNECTION_NAME='Registration-DB'

RECAPTCHA_SITE_KEY=XXXX
RECAPTCHA_SITE_NAME=app1.com
RECAPTCHA_SECRET=XXXX
4 changes: 4 additions & 0 deletions env.js-sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
const AUTH0_DOMAIN='XXX.auth0.com';
const AUTH0_CLIENT_ID='XXXX';
const SUCCESS_REDIRECT_URI='https://jwt.io';
const RECAPTCHA_SITE_KEY='XXXX';
11 changes: 11 additions & 0 deletions error.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration Error</title>
</head>
<body>
<h1>Oops. some error. Please <a href="/index.html">start again</a>.</h1>
</body>
</html>
Binary file added favicon.ico
Binary file not shown.
Binary file added img/1-check-mail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/1-start.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/2-email.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/3-create.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/4-success.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/5-profile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/app-conn-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/app-conn-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/app-create.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/app-grants.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/app-m2m-scopes.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/app-settings.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/captcha-register.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
37 changes: 37 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Registration</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<script src="env.js"></script>
<script src="https://www.google.com/recaptcha/api.js?render=6LfcVNwUAAAAAC3_KBKCG66eMqkFrUJLHG8j80sx"></script>
</head>
<body>
<h1>Welcome to Registration PoC</h1>
<label for="email">Email:</label>

<form id="registration_form" method="post" action="/start.php">
<input type="email" id="email" name="email"><br><br>
<input type="submit" value="Register">
</form>

<script>
$('#registration_form').submit(function(event) {
event.preventDefault();
let email = $('#email').val();

grecaptcha.ready(function() {
grecaptcha.execute(RECAPTCHA_SITE_KEY, {action: 'register_email'}).then(function(token) {
$('#registration_form').prepend('<input type="hidden" name="token" value="' + token + '">');
$('#registration_form').prepend('<input type="hidden" name="action" value="register_email">');
$('#registration_form').unbind('submit').submit();
});
});
});
</script>
</body>
</html>
57 changes: 57 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Sample App to register with email verification


## Setup
1. Register a RWA client in Auth0
![Register a RWA client in Auth0](img/app-create.png)
2. Configure callback and CORS URLs
![App Settings](img/app-settings.png)
3. Add implicit and M2M grants to your App
![App Grants](img/app-grants.png)
4. Add DB connection to App
![App DB Connection](img/app-conn-1.png)
5. Add Passwordless Email to App
![App Passwordless Connection](img/app-conn-2.png)
6. Add Management API with following scopes to your clients:
`users:create`, `users:delete`
![App M2M Scopes](img/app-m2m-scopes.png)
7. (Optional) [register](https://www.google.com/recaptcha/admin/create) a Google reCAPTCHA v3 account
![Captcha Register](img/captcha-register.png)

8. Copy `env-sample` to `.env` and update client information
9. Copy `env.js-sample` to `env.js` and update client information


## Running
Clone the project first.

```bash
$ cat /etc/hosts | grep app1.com
127.0.0.1 app1.com

$ compose install

$ php -S app1.com:3001 -e
```

### Sequence Diagram
![Registration Sequence Diagram](https://www.websequencediagrams.com/files/render?link=aVQ0WropybKb6WlkPtMGXuKcHSgTRntwqXukAiBdvPp9uZxstzy2acpcSJGYkTt6)

### Screenshots
1. User visit http:https://app1.com:3001
![Enter Email](img/1-start.png)
![See Prompt](img/1-check-mail.png)

2. Check Mailbox
![Mailbox](img/2-email.png)

3. Enter name, password and other details
![Create](img/3-create.png)

4. Success
![Success](img/4-success.png)

5. User Profile
![Profile](img/5-profile.png)


53 changes: 53 additions & 0 deletions start.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php
require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/dotenv-loader.php';

$email = $_POST["email"];
$gRecaptchaResponse = $_POST["token"];

if(! (isset($email)))
die("params invalid");

$recaptcha = new \ReCaptcha\ReCaptcha(getenv('RECAPTCHA_SECRET'));
$resp = $recaptcha->setExpectedHostname(getenv('RECAPTCHA_SITE_NAME'))
->verify($gRecaptchaResponse, $_SERVER['REMOTE_ADDR']);

if ($resp->isSuccess()) {
// Verified!
} else {
$errors = $resp->getErrorCodes();
die('recaptcha failed! ' + $errors);
}

use \Auth0\SDK\API\Authentication;
use Auth0\SDK\Store\SessionStore;
use Auth0\SDK\Store\CookieStore;
use Auth0\SDK\Helpers\TransientStoreHandler;
use Auth0\SDK\Auth0;

$auth0_api = new Authentication(
getenv('AUTH0_DOMAIN'),
getenv('AUTH0_CLIENT_ID'),
getenv('AUTH0_CLIENT_SECRET')
);

// Generate and store a state value.
$transient_store = new CookieStore();
$state_handler = new TransientStoreHandler($transient_store);
$state_value = $state_handler->issue(Auth0::TRANSIENT_STATE_KEY);

$authParams = array(
'redirect_uri' => getenv('AUTH0_CALLBACK_URL'),
'response_type' => 'token',
'scope' => 'openid email',
//'state' => $state_value
);



// TODO: check no matching user
$auth0_api->email_passwordless_start($email, 'link', $authParams);

echo "Please check your mailbox at <code>$email</code><br/>";
echo '<a href="/">Try again</a>';

0 comments on commit 394a804

Please sign in to comment.