AppSync ReactNative Cognito Promise Rejection - amazon-web-services

I have a exception thrown by react native when the app is started and also logged in.
my config is
"authenticationType": "AMAZON_COGNITO_USER_POOLS",
"apiKey": null
cognito is working with appsync, but i donĀ“t know how to fix the alert message.
Any suggestions are welcomed thanks.

I have not worked with AWS appsync, so I don't know what might be the problem. I can just suggest you one thing,add promise resolver function. That way you can see what it's returning, and it will prevent showing any alert. Something like-
jwtToken: async () => (await Auth.currentSession()
.then(data => {
console.log("data",data);
return data
})
.catch(err => {
console.log("error",error);
return err
})).getIdToken().getJwtToken()

Related

AWS Amplify post request fails with "status code 403 at node_modules/axios"

I configured and initialized AWS Amplify for my ReactNative/Expo app and added a REST Api. Im new to AWS in general, but im assuming that once I add the API, my project is populated with amplify/backend folders and files and is ready for consumption.
So i tried to create a simple post request to create an item in my DynamoDB table with
import { Amplify, API } from "aws-amplify";
import awsconfig from "./src/aws-exports";
Amplify.configure(awsconfig);
const enterData = async () => {
API.post("API", "/", {
body: {
dateID: "testing",
},
headers: {
Authorization: `Bearer ${(await Auth.currentSession())
.getIdToken()
.getJwtToken()}`
}
})
.then((result) => {
// console.log(JSON.parse(result));
})
.catch((err) => {
console.log(err);
});
};
const signIn = async () => {
Auth.signIn('test#test.com', 'testpassword')
.then((data) => {
console.log(data)
enterData() //enterData is attempted after signin is confirmed.
})
.catch((err) => {
console.log(err)
})
}
signIn()
I did not touch anything else in my project folder besides including the above in my App.tsx because im unsure if i need to and where. I got a 403 error code and it "points" to the axios package but im not sure if issue is related to aws integration.
I configured the REST Api with restricted access where Authenticated users are allowed to CRUD, and guests are allowed to Read. How could I even check if I am considered an "Authorized User" .
Yes, AWS Amplify API category uses Axios under the hood so axios is related to your problem.
Probably you get 403 because you didn't authorized, for Rest API's you need to set authorization headers,
I don't know how is your config but you can take help from this page. Please review the "Define Authorization Rules" section under the API(REST) section.
https://docs.amplify.aws/lib/restapi/authz/q/platform/js/#customizing-http-request-headers
To check authorization methods, you can use "Auth" class like that also you can see auth class usage in the above link.
import { Amplify, API, Auth } from "aws-amplify";
https://aws-amplify.github.io/amplify-js/api/classes/authclass.html

Amplify PubSub not sending/receiving - no errors

I have been struggling with this implementation and figured I'd ask for some community perspective at this point.
I've implemented PubSub with a Lambda successfully and when tested in the cloud I am seeing messages in the IoT test environment. I believe, therefore, that my endpoint is functional.
When trying to implement the Amplify service via the docs (https://docs.amplify.aws/lib/pubsub/getting-started/q/platform/js/) I have been running into all sorts of issues. Worked through the "socket:undefined" issue by reinstalling lock file and node-modules. Now am not getting any errors but it simply is not connecting.
My code is below. Currently when I try to publish I'm getting a response of []. If I try to specify the provider I get this error - "Error: Could not find provider named AWSIoTProvider".
Note: I have been following various SOs - this one most recently:
Amplify PubSub javascript subscribe and publish using cognito authorization: how to?
import Amplify from 'aws-amplify';
import { AWSIoTProvider } from '#aws-amplify/pubsub/lib/Providers';
import PubSub from '#aws-amplify/pubsub';
Amplify.addPluggable(new AWSIoTProvider({
aws_pubsub_region: 'as-southeast-2',
aws_pubsub_endpoint: 'wss://{MY_IOT_ID}-ats.iot.ap-southeast-2.amazonaws.com/mqtt',
}));
Amplify.configure(config);
PubSub.configure();
PubSub.subscribe('myTopic1').subscribe({
next: data => console.log('Message received', data),
error: error => console.error(error),
complete: () => console.log('Done'),
});
Then I have a function that I'm calling for publish that returns the [] if I don't specify the provider and the error above if I specify it (shown below)
Unspecified:
await PubSub.publish('1234-abcd-9876/workitem', { msg: 'Hello to all subscribers!' })
.then(response => console.log('Publish response:', response))
.catch(err => console.log('Publish Pub Err:', err));
Specified:
await PubSub.publish('1234-abcd-9876/workitem', { msg: 'Hello to all subscribers!' }, { provider: 'AWSIoTProvider' })
.then(response => console.log('Publish response:', response))
.catch(err => console.log('Publish Pub Err:', err));
Does anyone have any thoughts as to what I might be doing wrong here or might try next?
Thanks!
Since you are saying the specific error you got is - "Error: Could not find provider named AWSIoTProvider".
so, change the import path for AWSIoTProvider to #aws-amplify/pubsub instead of using #aws-amplify/pubsub/lib/Providers.
import { AWSIoTProvider } from '#aws-amplify/pubsub;

Unable to by pass amazon cognito authentication using cypress

I am trying to get login, but login functionality takes place in 'AWS Cognito Authetication', which is making my life little mess.
What happens, when user enters base url on browser, app navigates to 'AWS Cognito' message, where I enter my credentials, after adding credentials, app is showing me an alert message i.e.
An error was encountered with the requested page.
Screenshot is attached. I have checked network logs, but it is showing me that:
{"error":{"name":"UnauthorizedError","message":"No authorization token was found"}}
I need to know , where to start the procedure, I have gone through AWS Cognito Credentials section, but nothing happened yet.
Can someone help me there, how to start and how to work with it?
Cypress documentation has advice on how to authenticate with Cognito.
It could be more complete though, this blog post by Nick Van Hoof offers a more complete solution.
First install aws-amplify and cypress-localstorage-commands libs.
Add a Cypress command like:
import { Amplify, Auth } from 'aws-amplify';
import 'cypress-localstorage-commands';
Amplify.configure({
Auth: {
region: 'your aws region',
userPoolId 'your cognito userPoolId',
userPoolWebClientId: 'your cognito userPoolWebClientId',
},
});
Cypress.Commands.add("signIn", () => {
cy.then(() => Auth.signIn(username, password)).then((cognitoUser) => {
const idToken = cognitoUser.signInUserSession.idToken.jwtToken;
const accessToken = cognitoUser.signInUserSession.accessToken.jwtToken;
const makeKey = (name) => `CognitoIdentityServiceProvider.${cognitoUser.pool.clientId}.${cognitoUser.username}.${name}`;
cy.setLocalStorage(makeKey("accessToken"), accessToken);
cy.setLocalStorage(makeKey("idToken"), idToken);
cy.setLocalStorage(
`CognitoIdentityServiceProvider.${cognitoUser.pool.clientId}.LastAuthUser`,
cognitoUser.username
);
});
cy.saveLocalStorage();
});
Then your test:
describe("Example test", () => {
before(() => {
cy.signIn();
});
after(() => {
cy.clearLocalStorageSnapshot();
cy.clearLocalStorage();
});
beforeEach(() => {
cy.restoreLocalStorage();
});
afterEach(() => {
cy.saveLocalStorage();
});
it("should be logged in", () => {
cy.visit("/");
// ...
});
});

How can I fix sign out bug on AWS Cognito with flutter?

I'm doing an app using flutter that uses AWS Cognito for authentication, but every time the user sign of the app this black screen appears, I've searched but could not find out what is wrong, can anyone help me?
Here is my authentication code:
signIn(username, password, context) async {
try {
SignInResult res =
await Amplify.Auth.signIn(username: username, password: password);
if (res.isSignedIn) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => HomePage()));
}
print(username);
} on AuthException catch (e) {
print(e.message);
}
}
signOut() async {
try {
await Amplify.Auth.signOut();
} on AuthException catch (e) {
print(e.message);
}
}
And this is how I'm calling the function:
leading: IconButton(
onPressed: () {
AuthService().signOut();
Navigator.of(context).pushReplacementNamed('/');
},
icon: Icon(Icons.arrow_back)),
the black screen that appears
When logging out your user with Cognito, you need to pass a redirect URI in your request, so Cognito knows what to do after the sign out has happened. This URI also has to be registered as a possible URL in your app client configuration, in order to determine whether or not this is intended or malicious behaviour.
As you've stated in the comments on your question, you have not configured any sign out URI. So Cognito redirects to a blank page since it has no information on how to proceed otherwise.
(edit)
This issue appears to only affect android at the moment.
To overcome this issue, you can do a global sign out so that the browser redirect is skipped. Note that globalSignOut on iOS seems to trigger AWS auth exceptions which is why I used Platform.isAndroid.
import 'dart:io' show Platform;
final SignOutResult res = await Amplify.Auth.signOut(
options: const SignOutOptions(globalSignOut: Platform.isAndroid),
);

AWS X-Ray (with SailsJS) not logging things in the correct trace?

I am trying to use AWS X-Ray in my SailsJS application. I noticed missing subsegments - I added custom traces via AWSXRay.captureAsyncFunc but noticed they are missing. After some closer inspection, I think they actually ended up in a different trace. Lets say I call login API then another API later. I notice my login API trace is weird
Notice theres calls quite abit after the request should have ended.
Those requests should actually be in another segment:
I'd think they should appear after find device subsegment. Why are segments scrambled like that?
My setup: in http.js,
const AWSXRay = require('aws-xray-sdk');
const xrayEnabled = process.env.AWS_XRAY === 'yes'
module.exports.http = {
middleware: {
order: [
'startRequestTimer',
'cookieParser',
'session',
'myRequestLogger',
'bodyParser',
'handleBodyParserError',
'compress',
'methodOverride',
'poweredBy',
'awsXrayStart',
'router',
'awsXrayEnd',
'www',
'favicon',
'404',
'500',
],
awsXrayStart: xrayEnabled ? AWSXRay.express.openSegment(`cast-${process.env.NODE_ENV || 'noenv'}`) : (req, res, next) => next(),
awsXrayEnd: xrayEnabled ? AWSXRay.express.closeSegment() : (req, res, next) => next(),
Then I wrapped my promises like:
instrumentPromise(promise, name, metadata = {}) {
if (this.isXrayEnabled()) {
return new Promise((resolve, reject) => {
AWSXRay.captureAsyncFunc(name, (subsegment) => {
if (!subsegment) console.warn(`[XRAY] Failed to instrument ${name}`)
Object.keys(metadata).forEach(k => {
if (subsegment) subsegment.addMetadata(k, metadata[k])
})
console.time(`[XRAY TIME] ${name}`)
promise
.then((data) => {
if (subsegment) subsegment.close()
console.timeEnd(`[XRAY TIME] ${name}`)
resolve(data)
})
.catch(err => {
if (subsegment) subsegment.close()
console.timeEnd(`[XRAY TIME] ${name}`)
reject(err)
})
})
})
}
return promise
}
Is there any information I am missing here? What am I doing wrong?
I tried manual mode and its alot more reliable but I have to manually pass segment around. Whats wrong with automatic mode? I am kind of guessing it does not work well with async nature nodejs? Like the SDK is not able to differenciate between the various async requests? And may close or track segments in the wrong places? That said ... its supposed to work with express, why isit not working as expected ...
Another thing is how will a shared mysql connection pool be tracked correctly by X-Ray? Different segments will be using the same mysql pool. I assume this will not work work well at all?
The issue you encounter seems to be related to how CLS handle context binding with Promise. There is a opt-in promise patch introduced in this PR https://github.com/aws/aws-xray-sdk-node/pull/11. It has full discussion around the repros and fixes. That should resolve the issue with subsegments being attached to the wrong trace.
The SDK does support capturing pool.query. You can see examples here https://www.npmjs.com/package/aws-xray-sdk-mysql.