AWS Cognito Respond to New_Password_Required challenge returns "Cannot modify an already provided email" - amazon-cognito

An app that has been working successfully for a couple years has started throwing the following error whenever trying to respond to the NEW_PASSWORD_REQUIRED challenge with AWS Cognito:
{"__type":"NotAuthorizedException","message":"Cannot modify an already provided email"}
I'm sending the below, which all seems to match the docs.
{
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ClientId": <client_id>,
"ChallengeResponses": {
"userAttributes.email": "test#example.com",
"NEW_PASSWORD": "testP#55w0rd",
"USERNAME": "testfake"
},
"Session": <session_id>
}
Nothing has changed on the front end; is there a configuration change we might have done on the Cognito/AWS side that might cause this error?

I started getting the same error recently. I'm following Use case 23 Authenticate a user and set new password for a user. After some investigation, I found that it is the email attribute in userAttributes that's causing completeNewPasswordChallenge to throw the error. The userAttributes I get from authenticateUser used to be an empty object {}, but it now looks like this:
{ email_verified: 'true', email: 'test#example.com' }
I had to delete the email attribute (as well as the email_verified attribute as shown in the example code in Use case 23) before using the userAttribute for a completeNewPasswordChallenge. So my code is now like this:
cognitoUser.authenticateUser(authenticationDetails, {
...
newPasswordRequired: function(userAttributes, requiredAttributes) {
// the api doesn't accept this field back
delete userAttributes.email_verified;
delete userAttributes.email; // <--- add this line
// store userAttributes on global variable
sessionUserAttributes = userAttributes;
}
});
// ... handle new password flow on your app
handleNewPassword(newPassword) {
cognitoUser.completeNewPasswordChallenge(newPassword, sessionUserAttributes);
}
I guess aws changed their api recently, but I haven't found any doc about this change. Even though the value of the email attribute is the same as the actual email of the user, it throws the Cannot modify an already provided email error if you include it in the request. Deleting it solves the issue.

Related

FCM - "messaging/registration-token-not-registered" - but the client is still using the token?

When sending a multicast message to FCM...
const message = {
notification: {
title: messageTitle,
body: messageBody,
},
tokens: tokenArray,
}
getMessaging().sendMulticast(message)
I'm receiving this error.
messaging/registration-token-not-registered - Requested entity was not
found
According to this post, I should then remove the token.
Here's what I'm confused about though. When I run getToken() on my client device, it's still showing this same token.
getToken(messaging, { vapidKey: "MY_VAPID_KEY"}).then(token => console.log(token))
Is there like a registration step that I'm missing? I don't understand why the client is using this as the current token but FCM thinks it's unregistered.
So my solution was I reset the browser cache and notification permissions. My browser then generated a new token which is working.
Kind of strange though is on the first call of getToken() after clearing and refreshing, it sent a request to delete the token after failing a check with isTokenValid(), and then the delete itself failed so my token remained registered and is now working. No idea what's going on there.

Facebook js api - "unsupported get request" error

I'm trying to get some (I think allowed) information in my app. I have an access token that has the following info:
App ID: <my app id> : iHOUSEListingPoster - Test 001
Type: User
App-Scoped User ID: <user id> : Joe Webb
Valid: True
Scopes: email, pages_show_list, pages_read_engagement, pages_manage_posts, public_profile
I'm trying this:
FB.api( "/me",
"GET",
{fields: 'name'},
function(get_fb_info_response) {
console.log("Here: ", get_fb_info_response
});
And getting this error:
"Unsupported get request. Object with ID 'me' does not exist, cannot be loaded due to missing permissions, or does not support this operation"
I have tried with both "/me" and "/me/". And while I want name, picture and email, I tried limiting it to just name, and still. What am I missing here?
Try this:
FB.api('/me?fields=name', function(response) {
console.log('me', response);
});
I'm not sure if api function from FB does have this signature you're using.
Edit
After searching at Facebook docs, found that the signature you were using is valid as well. Then, I went to do some tests here. And I was able to reproduce the same error you have mentioned when calling the function like this:
FB.api("/<123>/", "GET", { fields: 'name' }, function(response) {
console.log('response', response);
});
To fix it, you need to remove < and >, for example:
FB.api("/123/", "GET", { fields: 'name' }, function(response) {
console.log('response', response);
});
Calling /me and /me/ endpoint returned no error in my test.
In this screenshot you can see the tests I have run directly at my browser's console.
Ok, I finally figured out what the problem is/was here (sheepish face). We have a couple of Facebook accounts here at the company. One is the container for my app and it's test app, the other is a more general company account. I was logged into the general company account. When I tried my app, it grabbed some random app from that account, which wasn't the app that matched the access token (which I think is possible wrong on Facebook's part), therefore this error was thrown.
Once I logged into the correct Facebook account, all works as expected.

Strapi doesn't authorize JWT

Good morning,
I've encountered a weird issue with my strapi-project.
I have a standard user model which I query for info on the user's profile page via the /users/me endpoint. This was all working fine last week but as I tried logging in this morning, the authorization appeared to not work anymore. I log my user in via this code:
....
async submitForm() {
axios.post('http://localhost:1337/auth/local', {
'identifier': this.email,
'password': this.password
})
.then((response) => {
const { jwt, user } = response.data;
window.localStorage.setItem('jwt', jwt);
window.localStorage.setItem('userData', JSON.stringify(user));
router.push('/dashboard');
})
.catch((e) => {
this.$store.commit('LOGIN_ERROR', e)
});
},
...
Which then redirects to my dashboard which queries the /users/me endpoint like so:
let token = localStorage.jwt;
axios.get(`http://localhost:1337/users/me`, {
headers: {
Authorization: `Bearer ${token}`
}
})
.then((response) => {
console.log(response.data);
})
A few days ago this was working fine, also the token variable used in the post contais the token returned from the backend after logging in. Now strapi gives me an error in the console:
[2021-10-16T07:16:52.568Z] debug GET /users/me (5 ms) 500
[2021-10-16T07:17:03.231Z] debug POST /auth/local (76 ms) 200
[2021-10-16T07:17:24.915Z] error TypeError: Cannot read property 'type' of null
at module.exports (/home/user/WebstormProjects/strapi-project/node_modules/strapi-plugin-users-permissions/config/policies/permissions.js:35:14)
at async /home/user/WebstormProjects/strapi-project/node_modules/strapi-utils/lib/policy.js:68:5
at async serve (/home/user/WebstormProjects/strapi-project/node_modules/koa-static/index.js:59:5)
at async /home/user/WebstormProjects/strapi-project/node_modules/strapi/lib/middlewares/parser/index.js:48:23
at async /home/user/WebstormProjects/strapi-project/node_modules/strapi/lib/middlewares/xss/index.js:26:9
My first guess was that maybe something with axios was wrong e.g. that the token wasn't sent correctly in the request so I tried the same thing with webstorm's http client:
POST http://localhost:1337/auth/local
Content-Type: application/json
{
"identifier": "test#test.com",
"password": "..."
}
Which returns the user and token:
"jwt": "<TOKEN>",
If I try using this token to authenticate the user, however a get a 401
GET http://localhost:1337/users/me
Authorization: "Bearer <token>"
Accept: application/json
returns
{
"statusCode": 401,
"error": "Unauthorized",
"message": "Invalid token."
}
So I tried figuring out what was going on there and after an hour I noticed that when looking at the user in the backend the user didn't have the authenticated role assigned. When I changed this manually in the backend, the request authorization works again.
So can anyone maybe tell me what is going on here? Because from my understanding, when POSTing valid credentials to /auth/local the user's role should change to Authenticated, which was working some days back.
Is there something I'm missing?
Any help would be greatly appreciated,
greetings, derelektrischemoench
Okay, so let me reply to your first part:
"Because from my understanding, when POSTing valid credentials to /auth/local the user's role should change to Authenticated"
Answer is, not really. When you send valid credentials to the auth/local, Strapi just checks the database for matching username/email and password. If a user is found, then it fetches the role assigned that user and puts all the data in ctx.state.user.role. So you could have many other roles, like Viewer, Commenter etc with each having different set of access limits.
The different roles can be created here:
http://localhost:1337/admin/settings/users-permissions/roles
So depending on the roles assigned, Strapi will just fetch and store the values in ctx.state.user.role on each request via the strapi-plugin-users-permissions plugin for your convenience, so that you can easily check which user it is and which role it has in any controller or service file using the ctx from the request to provide any additional functionality.
You can check how it does it in the following file:
node_modules/strapi-plugin-users-permissions/config/policies/permissions.js
Now coming to what could have caused it:
Well it could have been you yourself. Possibly while saving the user or viewing user details you could have removed the role from the user and saved the record.
The other possibility could be a database switch.
It can also be a Strapi version upgrade that caused, but it's highly unlikely.
You could have a update query in the your code that updates the user model, where you might have missed the role parameter. So check your code once.
Nevertheless, it can simply be solved by re-assigning the user roles via the users module.

Firebase rule auth.token.email is not working: "Simulated write denied"

https://firebase.google.com/docs/reference/security/database/#authtokenF
{
"rules": {
"c":{
".write":"newData.child('email').val()=== auth.token.email"
},
}
}
Always it showing "Simulated write denied"
How to solve this problem ? Is there any mistake with my firebase rule
It looks like you're not providing an email address in the authentication data.
When you select a provider, the simulator shows the exact auth.token payload that it will use. For the Google provider my Auth token payload looks like this:
The simulator takes the literal JSON that is shown in here, and uses it as auth.token.
{
"provider": "google",
"uid": "27e08474-4e33-460d-ba92-ba437c6aa962"
}
Since there is no email provided, your rules (correctly) fail.
For testing this scenario, you'll want to switch to a custom provider, so that you can specify your own auth token with an email property:

auth0 - email verification - user account does not exist or verification code is invalid

Here is my problem : In auth0 dashboard, I select a user within my users list and click on send a verification email... The user receive the mail, click on the link and get an error "User account doesn't exist or verification code is invalid" But the user exists and I do not use passwordless or sms authentication , my users have to enter their password and are also stored in mongodb. Any ideas to solve this?
-- edited precision added --
#Arcseldon
I'am actually using a customDB and here is my getUser script, but I don't know what to change, could you help me?
Thank you!
function getByEmail (email, callback) {
mongo('mongodb://user:pass#dsXXXX.mlab.com:XXXX/base', function (db) {
var users = db.collection('user');
users.findOne({ email: email }, function (err, user) {
if (err) return callback(new Error("my error message"));
if (!user) return callback(null);
var profile = {
user_id: user._id,
nickname: user.username,
email: user.email,
};
callback(null, profile);
});
});
}
Ok, just re-read your question - where you state "my users have to enter their password and are also stored in mongodb." - are you referring to your own Mongo DB? Are you using an Auth0 Custom DB Connection? Confusingly, Auth0 also uses MongoDB for its own DB storage, hence the clarification. If you are using a Custom DB connection to your own DB, then this may be a misconfiguration of one of your Custom DB Scripts. If using Custom DB Script, please double-check the implementation of your GetUser.js script.
In the event, you are using an Auth0 DB (not a custom DB) then definitely check with Auth0 support team (as per comment and your reply above).