Is SMS MFA Status in Cognito user pools set by calling setPreferredMFA or is that something else? - amazon-cognito

when using setPreferredMFA the SMS MFA Status in Cognito user pools is disabled even if setPreferredMFA is set.
What does SMS MFA Status represent and what does it do when I enable it or disable it?
Thank you

This is nothing more but an inconsistency in AWS console/API responses. Example:
Let's enable SMS MFA for a user:
aws cognito-idp set-user-mfa-preference --sms-mfa-settings Enabled=true,PreferredMfa=true --access-token <value>
Yes, in console it still looks as if SMS MFA was not enabled. But this is not true. Let's get our user's data:
aws cognito-idp get-user --access-token <value>
{
"Username": "your-email#example.com",
"UserAttributes": [
{
"Name": "sub",
"Value": "491a3eba-381f-4c87-a7d6-befa21e49e82"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "phone_number_verified",
"Value": "true"
},
{
"Name": "phone_number",
"Value": "+1234567890"
},
{
"Name": "email",
"Value": "your-email#example.com"
}
],
"PreferredMfaSetting": "SMS_MFA",
"UserMFASettingList": [
"SMS_MFA"
]
}
What you want to look at is the PreferredMfaSetting attribute. It tells you what your user choose for himself/herself.
And if you now try to authenticate like this:
aws cognito-idp initiate-auth --auth-flow USER_PASSWORD_AUTH --client-id <value> --auth-parameters USERNAME=<value>,PASSWORD=<value>
You will receive a response like this:
{
"ChallengeName": "SMS_MFA",
"Session": "<session-value>",
"ChallengeParameters": {
"CODE_DELIVERY_DELIVERY_MEDIUM": "SMS",
"CODE_DELIVERY_DESTINATION": "+*********7890",
"USER_ID_FOR_SRP": "your-email#example.com"
}
}
Ok, so what is this thing in console doing? It is actually deprecated. Take a look at the documentation of the MFAOptions here: https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetUser.html
So let's just enable SMS MFA through the console and then check the output of GetUser:
{
"Username": "your-email#example.com",
"UserAttributes": [
{
"Name": "sub",
"Value": "491a3eba-381f-4c87-a7d6-befa21e49e82"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "phone_number_verified",
"Value": "true"
},
{
"Name": "phone_number",
"Value": "+1234567890"
},
{
"Name": "email",
"Value": "your-email#example.com"
}
],
"MFAOptions": [
{
"DeliveryMedium": "SMS",
"AttributeName": "phone_number"
}
],
"PreferredMfaSetting": "SMS_MFA",
"UserMFASettingList": [
"SMS_MFA"
]
}
That's pretty much it.

Related

Chef Automate API

Starting to use the Chef Automate API.
I'm new to using APIs and I am confused as to what they mean by "Authorization Action" as listed on the documentation site:
I am using Postman as my utility/tool, and I have a Chef Automate admin API key. When I do a query:
GET {{ChefAutomateURL}}/apis/iam/v2/users?id=userid3
I would assume the reply would be only for that single user, but instead i'm getting everyone returned:
{
"users": [
{
"name": "user1",
"id": "userid1",
"membership_id": "a745cc00-8521-42a6-97ca-a60ccef931"
},
{
"name": "user2",
"id": "userid2",
"membership_id": "22e8e761-443b-45a3-9bdf-6ab4ccf79a"
},
{
"name": "user3",
"id": "userid3",
"membership_id": "67d2e924-2424-44d0-854d-c303f6c5ec"
}
]
}
... and I'm really confused as to why this isn't working.
This extends into my real desire, which is creating a local admin user, but again, when I try to do that, the response is just a JSON body with everyone:
POST {{ChefAutomateURL}}/apis/iam/v2/users
with this raw body:
{
"id": "userid4",
"name": "user4",
"password": "str0ng_password!"
}
I get a 200(OK) response like:
{
"users": [
{
"name": "user1",
"id": "userid1",
"membership_id": "a745cc00-8521-42a6-97ca-a60ccef931"
},
{
"name": "user2",
"id": "userid2",
"membership_id": "22e8e761-443b-45a3-9bdf-6ab4ccf79a"
},
{
"name": "user3",
"id": "userid3",
"membership_id": "67d2e924-2424-44d0-854d-c303f6c5ec"
}
]
}
I assume it has something to do with the "Authorization Action" as that's the only thing I'm not explicitly sending, but I don't understand what that is, or where/how it fits into the query.
I appreciate the help, thank you!

How to receive the media id from the Whatsapp Business Cloud API?

I have deployed my webhook and connected my WABA. Once I send an image to this business account. It did not return the media id from the response. Actually, the JSON returned to me like this:
{
"entry": [
{
"changes": [
{
"field": "messages",
"value": {
"contacts": [
{
"profile": {
"name": "XXXXXXX"
}
}
],
"messages": [
{
"from": "XXXXXXXXXX",
"id": "wamid.aisjdoiajsodiajsodasd\u003d",
"timestamp": "1657527108",
"type": "image"
}
],
"metadata": {}
}
}
],
"id": "124071984791824"
}
],
"object": "whatsapp_business_account"
}
Or should I try the Whatsapp On-premises API? https://developers.facebook.com/docs/whatsapp/on-premises/reference/media/media-id
You have to chooose the image_id from the request you receive.
like , let media_id=req.body.entry[0].changes[0].value.messages[0].image.id;
you can store this id in DB and use the endpioint where you can get the url for media_id.
Then you can download the image from the URL received and uploaded it anywhere you want.

Zoho Recruit API Register / Login Candidate

Could someone guide me an idea of how to create the registration and login for candidates with the Recruit api? I'm making a flutter app and I need my candidates to register and log in trow the app and see the job opening, post jobs.
At the moment I created the user with [POST] https://recruit.zoho.com/recruit/v2/Candidates
{
"data": [
{
"Email": "mail#gmail.com",
"First_Name": "TheName",
"Last_Name": "TheLastName",
"Mobile": "000000000",
"Expected_Salary": "8000000",
"Country": "PY",
"Departamento": "Central",
"C_I": "37114594",
"Ciudad_de_residencia": "City",
"$Password":"myPassWord199**"
}
],
"trigger": [
"approval",
"workflow",
"blueprint"
]
}
Works Well, got success
{
"data": [
{
"code": "SUCCESS",
"details": {
"Modified_Time": "2022-06-15T20:47:23-04:00",
"Modified_By": {
"name": "Admin",
"id": "00000000000000"
},
"Created_Time": "2022-06-15T20:47:23-04:00",
"id": "00000000000000",
"Created_By": {
"name": "Admin",
"id": "00000000000000"
}
},
"message": "record added",
"status": "success"
}
]
}
But If I try to log in in the web version (for testing the new candidate) don't work, but if it see the dashboard, the user exist. Need to add something else?
Basically I need a register api and a login one for the created record of the candidate.
Any help will be awesome, Thanks

Authenticating via Okta that uses 2FA

I built a simple asp.net core application and need to authenticate an account that uses MFA in addition to username & password.
The service I'm trying to log into exposes an authentication endpoint described here:
https://developer.okta.com/docs/reference/api/authn/#request-example-for-primary-authentication-with-public-application
When I provide the username and password it returns the expected JSON:
{
"stateToken": "00zQZJ1ZY3Em2401r4T69Dhx35TdF1VTFP5KRTa8ib",
"expiresAt": "2020-05-30T21:11:14.000Z",
"status": "MFA_REQUIRED",
"_embedded": {
"user": {
"id": "00u10vk1torIgBBxxxxx",
"profile": {
"login": "john.doe#email.com",
"firstName": "John",
"lastName": "Doe",
"locale": "en",
"timeZone": "America/Los_Angeles"
}
},
"factors": [{
"id": "ost1g59468dXOddAE0h8",
"factorType": "token:software:totp",
"provider": "OKTA",
"vendorName": "OKTA",
"profile": {
"credentialId": "john.doe#email.com"
},
"_links": {
"verify": {
"href": "https://company.okta.com/api/v1/authn/factors/ost1g59468dXOddxxxxx/verify",
"hints": {
"allow": ["POST"]
}
}
}
}, {
Does anyone know who I can also add 2FA into the request to get it to work?

AWS SES S3 process inbound email

I'm working on a publish by email system based on AWS SES. For all incoming emails I've set routing to save messages in an S3 bucket so I can asynchronously process them. The problem I have is that the messages are saved in the S3 bucket in a raw format: headers, email body, etc + the encrypted attachment (a huge string) - all in a single file.
Is there a way to break the email message apart form the attachment and save both in separate files at AWS SES level? I'm trying to get the data in the format I need straight from AWS and avoid adding another processing step to the process.
If AWS SES doesn't provide such a feature, what would be the proper way to process these messages to obtain the result described above?
It doesn't look possible to have SES automatically split up the email for you. As per the documentation here:
Amazon SES provides you the raw, unmodified email, which is typically
in Multipurpose Internet Mail Extensions (MIME) format.
I would use S3 or SNS to trigger a Lambda function whenever SES puts a new email file to S3. The Lambda function could split the file however you wish, then write those new files to another S3 bucket.
For anyone coming back later on to this question, this is the link to the JSON structure that you get when you invoke a Lambda function from SES.
http://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-notifications-examples.html
It took some searching to arrive at that page ;-)
From the link, a Lambda notification would look like this,
{
"notificationType": "Received",
"receipt": {
"timestamp": "2015-09-11T20:32:33.936Z",
"processingTimeMillis": 406,
"recipients": [
"recipient#example.com"
],
"spamVerdict": {
"status": "PASS"
},
"virusVerdict": {
"status": "PASS"
},
"spfVerdict": {
"status": "PASS"
},
"dkimVerdict": {
"status": "PASS"
},
"action": {
"type": "S3",
"topicArn": "arn:aws:sns:us-east-1:012345678912:example-topic",
"bucketName": "my-S3-bucket",
"objectKey": "\email"
}
},
"mail": {
"timestamp": "2015-09-11T20:32:33.936Z",
"source": "0000014fbe1c09cf-7cb9f704-7531-4e53-89a1-5fa9744f5eb6-000000#amazonses.com",
"messageId": "d6iitobk75ur44p8kdnnp7g2n800",
"destination": [
"recipient#example.com"
],
"headersTruncated": false,
"headers": [
{
"name": "Return-Path",
"value": "<0000014fbe1c09cf-7cb9f704-7531-4e53-89a1-5fa9744f5eb6-000000#amazonses.com>"
},
{
"name": "Received",
"value": "from a9-183.smtp-out.amazonses.com (a9-183.smtp-out.amazonses.com [54.240.9.183]) by inbound-smtp.us-east-1.amazonaws.com with SMTP id d6iitobk75ur44p8kdnnp7g2n800 for recipient#example.com; Fri, 11 Sep 2015 20:32:33 +0000 (UTC)"
},
{
"name": "DKIM-Signature",
"value": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=ug7nbtf4gccmlpwj322ax3p6ow6yfsug; d=amazonses.com; t=1442003552; h=From:To:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Date:Message-ID:Feedback-ID; bh=DWr3IOmYWoXCA9ARqGC/UaODfghffiwFNRIb2Mckyt4=; b=p4ukUDSFqhqiub+zPR0DW1kp7oJZakrzupr6LBe6sUuvqpBkig56UzUwc29rFbJF hlX3Ov7DeYVNoN38stqwsF8ivcajXpQsXRC1cW9z8x875J041rClAjV7EGbLmudVpPX 4hHst1XPyX5wmgdHIhmUuh8oZKpVqGi6bHGzzf7g="
},
{
"name": "From",
"value": "sender#example.com"
},
{
"name": "To",
"value": "recipient#example.com"
},
{
"name": "Subject",
"value": "Example subject"
},
{
"name": "MIME-Version",
"value": "1.0"
},
{
"name": "Content-Type",
"value": "text/plain; charset=UTF-8"
},
{
"name": "Content-Transfer-Encoding",
"value": "7bit"
},
{
"name": "Date",
"value": "Fri, 11 Sep 2015 20:32:32 +0000"
},
{
"name": "Message-ID",
"value": "<61967230-7A45-4A9D-BEC9-87CBCF2211C9#example.com>"
},
{
"name": "X-SES-Outgoing",
"value": "2015.09.11-54.240.9.183"
},
{
"name": "Feedback-ID",
"value": "1.us-east-1.Krv2FKpFdWV+KUYw3Qd6wcpPJ4Sv/pOPpEPSHn2u2o4=:AmazonSES"
}
],
"commonHeaders": {
"returnPath": "0000014fbe1c09cf-7cb9f704-7531-4e53-89a1-5fa9744f5eb6-000000#amazonses.com",
"from": [
"sender#example.com"
],
"date": "Fri, 11 Sep 2015 20:32:32 +0000",
"to": [
"recipient#example.com"
],
"messageId": "<61967230-7A45-4A9D-BEC9-87CBCF2211C9#example.com>",
"subject": "Example subject"
}
}
}
Regarding the question on how to write a Lambda. Here is a portion of our Lambda. The main thing to take out of it is the parseEvent function. and data.event.Records[0] which will give you details
exports.handler = function(event, context, callback) {
var AWS = require('aws-sdk');
// Validate characteristics of a SES event record.
if (!event ||
!event.hasOwnProperty('Records') ||
event.Records.length !== 1 ||
event.Records[0].hasOwnProperty('eventSource') ||
event.Records[0].eventSource !== 'aws:ses' ||
event.Records[0].eventVersion !== '1.0') {
callback(null, {'disposition':'STOP_RULE_SET'});
}
email = data.event.Records[0].ses.mail;
subjectLine = event.Records[0].ses.mail.commonHeaders.subject;
}
The key is the event.Record[0].ses.mail. Unfortunately, I can't find the structure of it via a Google search, I am sure I had seen it before.