workflow for self registration
-
There is no way to transfer an application from one tenant to another. You must create new application in the second tenant.
You may help yourself with applications API to get json representation of your app, tweak it as needed, and post in another application creation request.
Going back to the original question and external resources synchronization. You may also populate your external database only once the user verifies his email.
user.email.verified
webhook event can be utilized for such solution. -
@mgetka said in workflow for self registration:
You may also populate your external database only once the user verifies his email. user.email.verified webhook event can be utilized for such solution.
Good point. However I save the record number in the id field (of my table) of FA. That allows me to directly get to the record to delete the record, if need be. And I don't have the record number (to pop into the FA table) until I do an INSERT into my table.
The problem I am having is that I register the administrator, but registration-verification email is not being sent. Here is what I am doing:
I register an admin with $result = $_SESSION['client']->register("", $requestJ);
I do have Self Service Registration enabled.
For the Verification Template I have set it to Registration Verification.
So I expected FA to send that verification email out by itsef, but that is not what is happening. I has assumed that this was because I have the tenent for this workflow set to Default. But I really don't need the tenant at all.
Any idea why the verification email is not being sent? -
I believe you are again confusing user creation with registrations. Please refer to the docs for better understanding of the differences.
To sum it up, user entity, created on an user creation event represents an user. This entity contains the user email and its verification status. The user email verification email may be sent only on user creation.
The registration, is an entity that associates already existing user to a specific application. The registration is not related to user email nor its verification status. However, it can contain alternative username to be used by the user in this application only. On an event of registration creation, FA can send confirmation email, but it doesn't confirm user email, it only confirms whether the registration of an user in the application should persist.
You are quoting a code snippet with a
register
API request, so I suppose you are actually attempting on registration creation, having user creation in mind. The quoted request itself is invalid - the first argument should contain UUID of the user (since registrations are created for users that already exists) so it cannot be successful. This may be the cause of not receiving any emails. If not, you may check your SMTP settings in the tenant configuration. SMTP related errors can also be tracked via System > Event Log. -
@mgetka OK. The nomenclature is getting clearer. You are saying that the word "registration" only goes with an application and the word "create" only goes with a user.
In my case I have "registered" the application through the UI. My code is just fiddling with "creation" of users. It does no registering of applications.
Now when I run my code, it does create a user (I know because i can see them in the UI). But I will fix this. So clearly I don't want to use "register" a to add a user (to an already existing application). There must be some other php call to add a new user to an existing application? which?
Looking at the Docs under Core Concepts/Users I see this:
User scope
A User is scoped to a Tenant. A User existing within a Tenant can be registered to, and use the same credentials to authenticate to multiple applications within that Tenant.In fact I just searched for the word "create" on that page and it doesn't exist other than in "user action API". I then did a search on all the docs and can find the word "create" but not associated with a "user". Is the term "user action" synonymous with "create user"?
I then found this is the Docs:
Registrations
A User can be registered to one or more FusionAuth Applications. A User Registration can define one to many Application Roles.As you can see from the above statement, a User gets "registered" to a FA application. This is actually what i am trying to do since the application already exists (I created it in the UI).
I am trying to find a function in the php-client that will create a "user entity". My SMTP is fine. One more thing. Am I correct to assume that a verification email will be sent automatically upon a user action to create a user (once I get that going)?
-
Well, somehow I got it working. Thx for your help. The verification email is being sent and the user can verify.
I want to set the time allowed for a user to verify to about 5 minutes. At that point I'd like to delete the user from FA and fire off a webhook that will tell my application to delete the user from my apps user table.
Where can I set a timer for the verification to be complete? Or does my app need to watch the time and then send a user delete to FA?
-
I'm glad you got it working! Finishing the topic I will leave few more links:
There is also combined API call, that creates a user and a registration at once - I have missed that saying your register request is invalid - sorry. User creation and registration in one call. This is probably the request you were trying to perform.
You can configure unverified users deletion time in Edit Tenant > Email - as mentioned in my first response. But 5 minute offset is not reachable since the time is given in days.
-
Thanks again. As I think i said i have two different passwordless logins (type A and type B). Type A is for a user to take a survey. Type B is for an administrator to register themselves. For type A I am using Tenant default. In this under Template settings I have my Passwordless login template.
Now for type B I want to have a completely different Passwordless login template (it will say different stuff). But I see under Tenant Default there is only a place for one passwordless login template.
Now I have two different applications,type A (which uses tenant default) and type B (which also uses tenant default)? Why? Because the tenant field in Applications is read only.
You mentioned a day or two ago creating an application under the 2nd tenant. How do I do this in the UI? Under Tenant, is there a place for me to specify what Application to use?
I am thinking that the easiest way to do this would be to just create another application, so there will be 3 in total. But how to create it under it's own tenant (in the UI)?
-
But how to create it under it's own tenant (in the UI)?
Once you have more than one tenant, you should see a dropdown when you are adding an application in the UI which lets you determine which tenant the application is associated with.
Note that tenants have different user email spaces. That is to say that if I have an account with tenant A and an account with tenant B, they might have different passwords and they will certainly have different user attributes (last login, for example). That may be ok, but just wanted to make you aware. You may want to read the tenants core concepts docs if you haven't already.
-
If you have mor than one tenant defined (as you have) then tenant selection dropdown appears in the application creation view. Create chosen application in the second tenant and discard it in the first one.
-
@mgetka jinx!
-
After carefully comparing the passwordless login that worked with the passwordless that didn't work, I can see that the TenantId on the one that didn't work is incorrect. For some reason FA is trying to use the same tenant ID in both cases. They should be two different tenant IDs. BTW, I am using a different tenant for the registration than for the login. Perhaps this is why when the user tries to login, the wrong tenantID is chosen?
So I guess I will need to :Making an API request using a Tenant Id. I am using Codeigniter so I tried using this $this->output->set_header('X-FusionAuth-TenantId: 8ea1c784-866b-4755-b97b-b4fda2ad19e4'); right before my call to start PasswordlessLogin()
The result I am getting is :
FusionAuth\ClientResponse Object
(
[errorResponse] =>
[exception] =>
[method] => POST
[request] => {"applicationId":"2cf00c29-ac46-49bf-8cd4-32538ddb00d8","loginId":"richardbernstein217@gmail.com","state":{"redirect_uri":"http://substantiator-survey.ngrok.io/index.php/Configure/report_generator_amazing","client_id":"2cf00c29-ac46-49bf-8cd4-32538ddb00d8","response_type":"code","scope":"openid","state":"richardbernstein217@gmail.com"}}
[successResponse] =>
[status] => 404
)Obviously not optimum. But I see I can set an API key:
Using an API key.You may optionally create an API key that is scoped to a particular tenant. To create an API key navigate to Settings API Keys.
Similar to the example screenshot above where we created a new API key, in this example we have selected the Pied Piper tenant for this API key. Only Users, Groups and Applications belonging to the Pied Piper tenant will be visible to this API.
Create a Tenant API Key
HTTP Authorization Header example
The following example demonstrates an API request to an API endpoint requiring tenantId, using the tenant-scoped API key.curl -X POST
-H 'Authorization: oa06-d9uxCHTorBOkVdh_QzsX_iEEYARGv8udnMMLJ8'
-H 'Content-Type: application/json'
-d '{"group": {"name": "Admin"}}'
"http://localhost:9011/api/group"Setting this up requires me to choose an endpoint with Get, put, patch, post, delete. I have no idea how to get my tenant id, 8ea1c784-866b-4755-b97b-b4fda2ad19e4, to work with my call to startPasswordlessLogin. Is there an example anywhere?
-
Some posts ago you have mentioned that both of your apps reside in the same tenant. Moving one of them into another tenant was mentioned but I suppose you have abandoned the idea in the meantime. So, if they are both in same tenant, why would you expect FA to use different tenant ID for each app?
BTW,
$this->output->set_header
sets the header for a response sent to the web browser - data defined this way will never reach FA. -
No you are correct, they are in different tenants. That is why I need to set the "header info" as per the docs.
The docs say that if you have more than one tenant, which I do, that you will need to specify the tenant via the "header". There is even an example: HTTP Authorization Header example
curl -X POST
-H 'Authorization: oa06-d9uxCHTorBOkVdh_QzsX_iEEYARGv8udnMMLJ8'
-H 'Content-Type: application/json'
-d '{"group": {"name": "Admin"}}'
"http://localhost:9011/api/group"But that example makes no sense to someone using the php client.
Please tell me how to tell FA the tenant to use in the context of a php program?
-
Referring to the PHP client source code, the tenant id can be set for the client using
withTenantId
method. Something like this should work:$client->withTenantId(...)->passwordlessLogin(...);
Be aware that
withTenantId
stores the id in the client internal state, and the stored id will be used for all subsequent requests. It may be something that suits you or not - refer to the source code and check how this effect will affect your application. -
@mgetka Thanks. I found this:
public function withTenantId($tenantId) {
$this->tenantId = $tenantId;
return $this;
}/**
- Takes an action on a user. The user being actioned is called the "actionee" and the user taking the action is called the
- "actioner". Both user ids are required in the request object.
- @param array $request The action request that includes all of the information about the action being taken including
-
the id of the action, any options and the duration (if applicable).
What two users are they talking about? There is only one user involved. Does this make sense?
$requestJ = json_encode($request); //convert the array into json $result = $_SESSION['client']->setTenantId('8ea1c784-866b-4755-b97b-b4fda2ad19e4')->startPasswordlesslogin($requestJ);
-
The quoted code comment refers to
actionUser
API method, not thewitheTenantId
client method. -
This post is deleted! -
@mgetka Is there any example of how to specify a tenantID in a php call? I searched for ->withTenantId() as you show in your example call above and can't find it anywhere on the FA site.
-
The code snippet I put in the post where I first mention the
withTenantId
method is actually such an example. When I recommended referencing the source code, I meant the code itself, not the docstrings - the logic behind thewithTenantId
method is quite simple, and the code describes mentioned effects (alteration of internal client state) in the most unambigious way.If you need more verbose examples see the code below
<?php require __DIR__ . '/vendor/autoload.php'; $apiKey = "5a826da2-1e3a-49df-85ba-cd88575e4e9d"; $client = new FusionAuth\FusionAuthClient($apiKey, "http://localhost:9011"); $request = array( "applicationId" => "c9a6f176-93df-4eaa-b67c-b651d18df60c", "loginId" => "user" ); $result = $client->withTenantId("adca656e-4895-4a9e-ac2e-8b9ebebb5149")->startPasswordlesslogin($request); var_dump($result); ?>
For such a call, the client invokes following HTTP API request
POST /api/passwordless/start HTTP/1.1 Host: [...]:9011 Accept: */* X-FusionAuth-TenantId: adca656e-4895-4a9e-ac2e-8b9ebebb5149 Authorization: 5a826da2-1e3a-49df-85ba-cd88575e4e9d Content-Length: 73 Content-Type: application/json {"applicationId":"c9a6f176-93df-4eaa-b67c-b651d18df60c","loginId":"user"}
-
Thanks. I modified as requested. I am still getting a 404 error. Note that the errorResponse is blank.
Here is the call:
$result = $_SESSION['client']->withTenantId('8ea1c784-866b-4755-b97b-b4fda2ad19e4')->startPasswordlesslogin($requestJ);Here is the $result I am seeing:
FusionAuth\ClientResponse Object
(
[errorResponse] =>
[exception] =>
[method] => POST
[request] => {"applicationId":"2cf00c29-ac46-49bf-8cd4-32538ddb00d8","loginId":"richardbernstein217@gmail.com","state":{"redirect_uri":"http://substantiator-survey.ngrok.io/index.php/Configure/report_generator_amazing","client_id":"2cf00c29-ac46-49bf-8cd4-32538ddb00d8","response_type":"code","scope":"openid","state":"richardbernstein217@gmail.com"}}
[successResponse] =>
[status] => 404
)