Is there any way using AWS Cognito to send the user their verification code, have them enter the code, verify it is a valid code, THEN have them set their username and password?
For some reason, the workflow in my mind seems strange for the user to enter their code and new password in the same step. I want to check their code, and if it is valid, then take them to the screen to reset their password.
So far I've used the API function call:
forgotPassword
To send the code, which works fine, and from all my reading of the docs and searching here and online, I see that the next step is to call:
confirmForgotPassword
But in this step, it requires the new password (from what I can tell from the documentation):
$result = $client->confirmForgotPassword([
'AnalyticsMetadata' => [
'AnalyticsEndpointId' => '<string>',
],
'ClientId' => '<string>', // REQUIRED
'ClientMetadata' => ['<string>', ...],
'ConfirmationCode' => '<string>', // REQUIRED
'Password' => '<string>', // REQUIRED
'SecretHash' => '<string>',
'UserContextData' => [
'EncodedData' => '<string>',
],
'Username' => '<string>', // REQUIRED
]);
Am I missing something?
For context, I'm using the PHP API, but I'm really just looking for the correct API calls in the correct order to accomplish what I'd like if it is even possible.
Thanks in advance.
I changed my workflow so that I used a lambda function in AWS to send a link with the code, this way I validate the code on the link click and then the user can enter their password in.
Doesn't seem possible to do this in two steps.
Related
I have been trying to show up the company name instead of a phone number when an outbound call is initiated automatically at certain times using aws connect contact flow. So far, everything is working as it should be except for showing up the name of the company. I have been trying to find a solution or a documentation on how to show the company name instead of a number but so far could not find anything useful. the only hint I got from aws documentation was , I should set the caller id and name by myself, and no further instruction or hints on how to do it. I Tried to change the phone number using outboundcall api's contact attributes but nothing was showing up.
$result = $client->startOutboundVoiceContact([
'Attributes' => array(
'sourcePhoneNumber' => $d->company_name,
'd`enter code here`ate'=> $d->date,
'time' => $d->time,
'clinic' => $d->company_branch_name,
'address' => $d->company_branch_address,
),
'ContactFlowId' => $this->contactFlowId, // REQUIRED
'DestinationPhoneNumber' => $d->phone_number, // REQUIRED
'InstanceId' => $this->instanceId, // REQUIRED
'SourcePhoneNumber' => $this->sourcePhoneNumber,
]);
'''
where $d is my database and i am getting all the information from there
any recommendation or solution would be very much helpful. thank you.
If I recall correctly this feature is only possible in the US.
I have an AWS Cognito User Pool where users are created through Cognito's API using the AdminCreateUser action, which works fine. This sends out a verification e-mail to the user, containing a temporary password. So far so good.
Now a user did not receive this verification e-mail, so I need to send it again, using the ResendConfirmationCode action. I am attempting to do that with the below PHP code.
$userPoolId = '[POOL_ID_HERE]';
$backendAppId = '[APP_ID_HERE]';
$clientSecret = '[SECRET_HERE]';
$username = '[UUID_HERE]';
$secretHash = base64_encode(hash_hmac('sha256', $username . $backendAppId, $clientSecret, true));
$cognitoIdp->resendConfirmationCode([
'ClientId' => $backendAppId,
'SecretHash' => $secretHash,
'Username' => $username,
]);
That gives me the following error:
Aws/CognitoIdentityProvider/Exception/CognitoIdentityProviderException
with message 'Error executing "ResendConfirmationCode" on
"https://cognito-idp.eu-central-1.amazonaws.com"; AWS HTTP error:
Client error: POST https://cognito-idp.eu-central-1.amazonaws.com
resulted in a 400 Bad Request response:
{"__type":"NotAuthorizedException","message":"Can't resend
confirmation code for this user"} NotAuthorizedException (client):
Can't resend confirmation code for this user -
{"__type":"NotAuthorizedException","message":"Can't resend
confirmation code for this user"}'
I am using the credentials of a user which has the following IAM permissions for the user pool:
cognito-idp:AdminDeleteUser
cognito-idp:AdminCreateUser
cognito-idp:AdminAddUserToGroup
cognito-idp:ResendConfirmationCode
If I test the permissions using the IAM Policy Simulator, it gives me the green light, saying that everything is OK. To my knowledge, the cognito-idp:ResendConfirmationCode action should be sufficient, as sending out the verification e-mail works fine when creating the user.
What am I doing wrong here? An alternative approach would be to invoke the AdminCreateUser action again, setting the MessageAction parameter to RESEND. This would force the verification e-mail to be resent for existing users, but I prefer using the ResendConfirmationCode action if I can get it to work.
Any ideas? Thanks!
I understand that you would like your web application end users to receive a confirmation code again if they do not get the confirmation code due to some reason after they sign-up, and I also understand that you are getting the "NotAuthorizedException" when you are trying to run the ResendConfirmationCode API call from your code that uses the PHP SDK.
The ResendConfirmationCode API call[1] can be used after the sign-up API call[2], and it is not a part of the AdminCreateUser Authentication flow, which is why the error is thrown. The AdminCreateUser API call changes the status of the new user to the "Force Change Password State", and neither the ResendConfirmationCode call or the ForgotPassword call can work after AdminCreateUser is used for creating a new user.
If you would like your end-users to get the confirmation code again, you could use the AdminCreateUser API call itself and set the "RESEND" flag in MessageAction in the PHP code. There would be no other way to send the verification message again in this particular use-case, as per my understanding of Amazon Cognito.
An example of the API call in PHP according to the official documentation is as follows[3]:
$result = $client->adminCreateUser([
'DesiredDeliveryMediums' => ['<string>', ...],
'ForceAliasCreation' => true || false,
'MessageAction' => 'RESEND|SUPPRESS',
'TemporaryPassword' => '<string>',
'UserAttributes' => [
[
'Name' => '<string>', // REQUIRED
'Value' => '<string>',
],
// ...
],
'UserPoolId' => '<string>', // REQUIRED
'Username' => '<string>', // REQUIRED
'ValidationData' => [
[
'Name' => '<string>', // REQUIRED
'Value' => '<string>',
],
// ...
],
]);
After using setting 'MessageAction' as 'RESEND', the end-users should be able to receive the verification message again on their end.
References
[1]. https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/resend-confirmation-code.html
[2]. https://docs.aws.amazon.com/cli/latest/reference/cognito-idp/sign-up.html
[3]. https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-cognito-idp-2016-04-18.html#admincreateuser
I am trying to use the built-in driver for Mailgun to send email. Here's what I have done so far.
Installed Guzzle driver.
Added the following to my config\services.php
'mailgun' => [
'domain' => env('sandbox54d5c9ed96434d689f971fd3.mailgun.org'),
'secret' => env('key-e800aa77cbda23ee8471dd5e'),
],
In my config\mail.php I have added
'driver' => env('MAIL_DRIVER', 'mailgun'),
However, now if I try to do forget password. It says we have sent an email but I don't get anything.
The domain is my sandbox domain name and secret is the API Key.
Am I missing something here or doing something wrong? How can I debug if there are some issues?
Sorry for this late answer, just found your question while googling for something different and hope not too late. If you want to save the credentials in .env, do this in your config\services.php:
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
Then in your .env file
MAILGUN_DOMAIN=sandbox54d5c9ed96434d689f971fd3.mailgun.org
MAILGUN_SECRET=key-e800aa77cbda23ee8471dd5e
In the config\services.php you just tell the key on .env file with:
'setting' => env('KEY_IN_ENV')
Laravel will then check if the key found and get the value from .env file:
KEY_IN_ENV = setting_value
Or simply like this in your config\services.php only:
'mailgun' => [
'domain' => 'sandbox54d5c9ed96434d689f971fd3.mailgun.org',
'secret' => 'key-e800aa77cbda23ee8471dd5e',
],
Good for you.
I've been trying a few combinations but can't seem to come up with something that works. More information about the API I'm asking about can be found here https://developers.google.com/admin-sdk/directory/v1/reference/users/insert . I have a feeling I'm just not setting up the request correctly. The following bit of code is known to work. I use it to set up the client that is able to query all the users.
client = Google::APIClient.new(:application_name => "myapp", :version => "v0.0.0")
client.authorization = Signet::OAuth2::Client.new(
:token_credential_uri => 'https://accounts.google.com/o/oauth2/token',
:audience => 'https://accounts.google.com/o/oauth2/token',
:scope => "https://www.googleapis.com/auth/admin.directory.user",
:issuer => issuer,
:signing_key => key,
:person => user + "#" + domain)
client.authorization.fetch_access_token!
api = client.discovered_api("admin", "directory_v1")
When I try to use the following code
parameters = Hash.new
parameters["password"] = "ThisIsAPassword"
parameters["primaryEmail"] = "tstacct2#" + domain
parameters["name"] = {"givenName" => "Test", "familyName" => "Account2"}
parameters[:api_method] = api.users.insert
response = client.execute(parameters)
I always get back the same error "code": 400, "message": "Invalid Given/Family Name: FamilyName"
I've observed a few things while looking into this particular API. If I print out the parameters for both the list and the insert functions e.g
puts "--- Users List ---"
puts api.users.list.parameters
puts "--- Users Insert ---"
puts api.users.insert.parameters
Only the List actually displays the parameters
--- Users List ---
customer
domain
maxResults
orderBy
pageToken
query
showDeleted
sortOrder
--- Users Insert ---
This leaves me wondering if the ruby client is unable to retrieve the api and therefore unable to submit the request correctly or if I'm just doing something completely wrong.
I'd appreciate any idea's or direction that might help set me on the right path.
Thank you,
James
You need to supply an Users resource in the request body, which is also the reason why you don't see it in the params.
So the request should look like:
# code dealing with client and auth
api = client.discovered_api("admin", "directory_v1")
new_user = api.users.insert.request_schema.new({
'password' => 'aPassword',
'primaryEmail' => 'testAccount#myDomain.mygbiz.com',
'name' => {
'familyName' => 'John',
'givenName' => 'Doe'
}
})
result = client.execute(
:api_method => api.users.insert,
:body_object => new_user
)
What I'd like
I want to be able to reset a users password without emailing them. I also need to do this via REST (it's for a kiosk system).
So I need to:
Get user with a specific username
Reset the password of that user
Try as I might, I can't get the user with a username.
The problem
After I've logged in using the admin user via REST I do:
GET on http://mydomain.com/rest/user?name=user.
According to REST documentation, this should get the user with name user.
I get a 200 response, but nothing is returned in the body.
What I've Tried
Get node from ID
Once I've logged in as admin, I can do:
GET on http://mydomain.com/rest/user/1
This works, returning the details of user 1 in the response. But I need to search for a user by username.
Different GETs
GET on http://mydomain.com/rest/user/admin
GET on http://mydomain.com/rest/user/account/name/admin
GET on http://mydomain.com/rest/user?account[name]=admin
GET on http://mydomain.com/rest/user?uid=1
GET on http://mydomain.com/rest/user/retrieve?uid=1
GET on http://mydomain.com/rest/user?account[uid]=1
All these fail.
Nodes instead of users
GET on http://mydomain.com/rest/node/1 works, but http://mydomain.com/rest/node?nid=1 gives me a 200 response with nothing in the body.
List of all users
GET on http://mydomain.com/rest/user/ doesn't show a list of all users either. I get a 200 with empty body again.
Further Details
I'm working with a Drupal 6.22 install.
I've installed the services module (3.0 RC1) and REST Server (2.0 beta 1).
I've got the session authentication module installed.
I've tried the above with the session authentication switched on and with it off.
I've enabled all node resources and user resources for the REST endpoint I've set up.
I've tried the above with and without clean URLs and nothing seems to make a difference.
Question
How do I get a user with a specific username? What am I doing wrong?
Update
I've uninstalled then reinstalled Services module, I've done the same with the REST server. I've also rolled back my version of CTools to the latest recommended one. I've added a brand new service in case it was corrupted. Nothing I do works. Frustrating!
Update 2
I've found the problem, but would like a more permanent solution. It turns out it was an error because of table naming. See my current accepted answer.
Im sorry this is so frustrating for you. Im the maintainer for services module and were really working on the documentation but I thought I would answer here to just get you moving along.
The reason you are not getting any of the data you want is because the parameters you are passing are wrong.
If you look at user_resource.inc index is defined as follows
'index' => array(
'file' => array('type' => 'inc', 'module' => 'services', 'name' => 'resources/user_resource'),
'callback' => '_user_resource_index',
'args' => array(
array(
'name' => 'page',
'optional' => TRUE,
'type' => 'int',
'description' => 'The zero-based index of the page to get, defaults to 0.',
'default value' => 0,
'source' => array('param' => 'page'),
),
array(
'name' => 'fields',
'optional' => TRUE,
'type' => 'string',
'description' => 'The fields to get.',
'default value' => '*',
'source' => array('param' => 'fields'),
),
array(
'name' => 'parameters',
'optional' => TRUE,
'type' => 'array',
'description' => 'Parameters',
'default value' => array(),
'source' => array('param' => 'parameters'),
),
),
'access arguments' => array('access user profiles'),
'access arguments append' => FALSE,
),
Notice the third argument, parameters.
You can do all sorts of fun stuff with the index query as long as it is turned on, but what you havnt tried is ?parameters[name]=user Example below
When I make a request to http://test/api/user?parameters[name]=gdsfgsdfgsdfg&fields=name,uid
I get returned
[
{
"name":"gdsfgsdfgsdfg",
"uid":"36",
"uri":"http:\/\/test\/api\/user\/36"
}
]
Notice i also added some fields, uid and name. Obviously these are optional but it shows you the power of the index query. The same applies to nodes.
I hope this helps.
Try something like:
GET on http://mydomain.com/rest/user?parameters[name]=admin
This worked for me in Drupal7. Not sure if it'll be the same for 6. But I also had no issues with getting the index of all users using GET on http://mydomain.com/rest/user/
I found the issue. It's an error/bug with the Services module in the setup I have.
From the services.module file
449 // Now implode that array into an actual WHERE clause.
450 $where = !empty($where) ? ' WHERE '. implode(' AND ', $where) : '';
451 // Run through db_rewrite_sql to make sure proper access checks are applied.
// **** Error logged for this next line ****
452 $sql = "SELECT $fields FROM {$table} $where ORDER BY $order"; // <-- Error was logged for this line
453 $sql = db_rewrite_sql($sql);
454 $result = db_query_range($sql, $parameters, $page * 20, 20);
455 return $result;
The error
Table '<REDACTED>_drup1.users' doesn't exist query: SELECT * FROM users ORDER BY created DESC LIMIT 0, 20 in /<REDACTED>/sites/all/modules/services/services.module on line 455.
The users table in my installation is called drup_users. When I change line 452 to
452 $sql = "SELECT $fields FROM drup_{$table} $where ORDER BY $order";
It works. I'd be interested in knowing how I can have a more permanent solution. I ran update.php several times and it didn't fix this.