FusionAuth oAuth not working with TestCafe - testing

I am failing to correctly login through the UI with the testing framework TestCafe. Our company uses FusionAuth for authentication which lives on a separate Domain from the application I am looking to test. At the moment im just trying to develop a Proof of Concept with logging in through the UI.
Currently, the cookie that I often see get set when logging in normal through my browser does not get set when going through testcafe. Thus when you return to the application it does not to know that you are authenticated.
It seems that the passing of cookies / local storage from the IDP login page back to the Application in test does not happen.
Ive tried useing Role's with preserveUrl set to true.
const testUser = Role('{domainURL}/login', async t => {
const username = 'username'; //Not real values
const password = 'passwword';
await t
.typeText('#loginId', username)
.typeText('#password', password)
.click('.submit');
}, { preserveUrl: true });
test
.disablePageCaching('Login to Test Users Account', async t => {
await t.useRole(testUser);
});
Ive also tried just using selectors and putting in the Credientials manually in the UI. Neither have worked so far for me.
I was curious if:
I am approaching this wrong?
What is the best approach for Black box End-2-End Testing with testcafe when dealing with login?
I know this is probably not the best place, but i wasn't sure how else to contact testcafe support.

In general, TestCafe Roles is the recommended approach for dealing with logging. There can be some FusionAuth specifics that do not work correctly with TestCafe. If you want our TestCafe team to research this issue, you can create an issue in our github repository using the following link: https://github.com/DevExpress/testcafe/issues/new?assignees=&labels=&template=bug-report.md
Please note that we will need an example that demonstrates the issue. If you cannot share your project/login/password publicly, you can send it to support#devexpress.com.

This was turned into a github Issue ticket that can be found here. Going to close this Question for now.

Related

What is the RIGHT way to access Google websites from within an electron app? [duplicate]

A user of my app reported an issue today about authorizing the user with Google (using OAuth 2.0). So far the application was opening a new BrowserWindow (node integration disabled, session is separated from the main application). You can see the implementation here since the library is OSS. I am using this to authorize the user to access application data on Google Drive.
Today after logging in I see the following message:
This browser or app may not be secure.
Try using a different browser. If you’re already using a supported browser, you can refresh your screen and try again to sign in.
The learn more link has a section for developers. This section has 2 links. One is how to upgrade the application to PWA. Because the application is an API testing tool it won't be possible to run it in a web browser.
The second link points to a document describing how to migrate to authorization for native application. However described flow requires authorization_code grant. This means I need to include OAuth secret into my application. Electron application, however, is still web application and there's no notion of compiling sources. I would expose client secret to the public which is not secured. Potentially I could build a server application to support it but the app is OSS project. It does not have funding to run a server for authorization.
My question is now how should I implement OAuth 2 for Electron application then. I can't use PWA's and server authorization flow (code grant) is far from ideal in this case.
As Paweł explained, changing the user agent will do the trick. However, you can easily set the user agent by passing an object when loading the URL
win = new BrowserWindow({width: 800, height: 600});
win.loadURL(authUrl, {userAgent: 'Chrome'})
I have tested it and it worked like a charm
Warning: This answer relies on changing the browser's user-agent. As of Jan. 2021, Google disapproves of this and warns not to do this (see EDIT4). Use at your own risk!
The other answers didn't work for me (in Electron 9.0.5), but I eventually found this, which worked:
app.on("ready", ()=> {
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders["User-Agent"] = "Chrome";
callback({ cancel: false, requestHeaders: details.requestHeaders });
});
CreateMainWindow(); // your regular code to create root browser window
});
EDIT: Two other approaches, which I haven't tested, but which may also work:
app.on("ready", ()=>{
session.defaultSession.setUserAgent("Chrome");
...
}
app.userAgentFallback = "Chrome";
EDIT2: Trying again sometime later, approach #2 did not work, but #1 still did. Haven't tried #3 yet.
EDIT3: Trying again later still, it seems that none of these workarounds are needed anymore! Google appears to accept sign-in popups from Electron apps again, without modifications to the user-agent. (odd that they'd revert this; perhaps I just did something wrong in my re-attempt)
EDIT4: While approach #1 still works atm, I recently found this blog post: https://developers.googleblog.com/2020/08/guidance-for-our-effort-to-block-less-secure-browser-and-apps.html Apparently Google is restricting usage of Google sign-in in non-standard browsers (which presumably includes Electron) starting in Jan. 2021, and warns developers not to modify their browser's user-agent (which all three of the possibilities I mention do). Use at your own risk! (they don't make clear what outcome will result, but for my own use, I'm opting to use the alternative shown below from now on)
As an alternative to using a Google sign-in popup in your app (which some might be wary of, since Electron apps could in principle insert code into the popup to read the raw password -- not that it matters that much, since Electron apps could just install keyloggers or the like anyway), you could instead open a tab in the user's regular external browser, pointed to a special page that triggers a sign-in popup there, and then just sends the credentials to your Electron app afterward.
Instructions can be seen here (approach 3): https://stackoverflow.com/a/64328193/2441655
After taking a wild guess I decided to alter the user agent string and to remove application name from it as well as Electron/ with version. After this alteration it started working again.
Example implementation:
const win = new BrowserWindow(params);
let ua = win.webContents.userAgent;
ua = ua.replace(/APPLICATION NAME HERE\/[0-9\.-]*/,'');
ua = ua.replace(/Electron\/*/,'');
win.webContents.userAgent = ua;
This assumes the application is using symver and no pre-release tags. Otherwise you would have to tweak the regexp a bit.

Auth0 Login is not working with routing strategy { useHash: true } in Angular 12

I am trying to integrate Auth0 Login with Microsoft Office Word Add-in, The issue i'm facing is, I've to use
HashLocationStrategy in order to make my routing work in add-in iframe. But it seems like the auth0 login is not working with given routing strategy as it constantly returning false to my 'IsAuthorized$' Observable.
Also, I've checked with given auth0-angular-samples-Sample-01 auth0 demo on git hub for browser angular application and it seem working fine, But when i tried to apply { useHash: true } in my routing imports it prevents me from getting authenticated, So Please verify this issue and let us know if there any suggestion and solution for the same.
For quick review of my demo code, here is the link: Auth0 sample with HashLocationStrategy
Any small help would be appreciated.
Thank you.

Empty object user when authenticating with Realm.Credentials.jwt(token) and Realm connection issue with RN hot reload

I am trying to use Mongo Realm (v10.0.0-beta.9) ; I use a JWT authentication (token being generated by AWS Cognito). It works pretty well since a user has been created (in Mongo Realms Users menu) and I was able to insert a data in my realm. But...
1. Empty user object
One strange thing nevertheless: the user I get from the authentication is empty
const credentials = Realm.Credentials.custom(jwt)
// Authenticate the user
const user: Realm.User = await app.logIn(credentials)
console.log("logged in with Jwt, user:", user) // display "logged in with Jwt, user: {}"
Is it normal? Examples speak about a identity field: console.log(`Logged in as ${newUser.identity}`);
2. React Native hot reload
A bothering thing: I can't reconnect to a realm when reloading the app (pressing r in the console where I npm started). I don't get any error, I just get... nothing. No log appears in Realm console.
The only solution I get is to kill the app, then restart it.
Did I miss a trick to handle that reconnection with RN hot relad?
I've had some troubles converting any Realm objects to printable strings; I always get {} just like you do. I think it could be related to this (unresolved) task on their GitHub.
On a similar note, there are some bugs in Realm's authentication system. I'm trying to get email/password, Facebook, and Google authentication going in my application but all of them currently seem to be broken on Realm's side.
Here are some related issues on their GitHub that you can follow for a solution.
Facebook
Google
Email/pass (fixed, but not released in the latest beta)
I don't have any information about JWT specifically but given these other authentication issues there's a good chance the issue isn't on your side. I recommend opening an Issue on their repository.

Google OAuth-2 how to ask user for a password on each login?

I need to ask user for a password each time he using Google OAuth.
There was an option I have used "max_auth_age", but it stops working.
Is there any replacement for this option. If not - could you please suggest where can I submit something like "feature request" to Google to restore this feature.
Thanks.
UPD
I have read possible duplicate topic and tried to use max_age instead max_auth_age. It did not help.
p.s I know that the main idea of OAuth2 not to use any passwords prompts, but its customer requirement. He is afraid that person, who not allowed to use system can have access on shared computer if someone forgot to logout from Gmail.
Aside from BCM and ehsan s' concerns, it is possible to revoke access to your application AND ask for a password on subsequent login attempts.
Following is a NodeJS example with googleapis, but is simple enough to work for all applications:
const google = require('googleapis').google;
const oauth2Client = new google.auth.OAuth2(
'client_id',
'client_secret',
'redirect_uri'
);
// Sign-in code (omitted) here
async function signOut() {
return await oauth2Client.request({
url: 'https://accounts.google.com/Logout',
method: 'GET'
});
}
Unlike oauth2Client.revokeCredentials, requesting https://accounts.google.com/Logout will make google ask for password on subsequent sign-in attempts.
Bare in mind that this request will sign the user out of all google services on the client.
This wont affect other clients on the device however - i.e. sign-out of NodeJS app will not cause the user to be logged out of gmail in Chrome browser running on the same machine and under the same user.
Hope this helps :)

Codeception Acceptance and Phantomjs Cookies outside your domain (Google oAuth)

I am at a crossroad where I have the "solution" but I am not sure its the best approach.
Part of my application is oAuth login and I want to test that too (Acceptance).
I have bogus accounts for my oAuth providers that i'll be using to Login. Problem is Cookies.
I am using Phantomjs. Even if I use clear_cookies: true on my yml file I have this problem where my test cannot login because Google remembers me.
The test is quite simple:
public function login_with_oauth(AcceptanceTester $I)
{
$I->amOnPage('/auth/logout');
$I->amOnPage('/');
$I->click(['id' => 'login']);
$I->click(['id' => 'btn_login_google']);
#$I->fillField(['id' => 'Email'], $this->login);
$I->fillField(['id' => 'Passwd'], $this->password);
$I->click(['id' => 'signIn']);
$I->waitForText($this->name);
$I->seeInCurrentUrl('/home');
}
First time it works, second it does not because Google remembers the logged in user so it doesnt show the login and password boxes anymore.
If I hit the google logout url (accounts.google.com/logout) it logs the user out, but the next time I try to login it will remember my EMAIL (thus not my password), the email field will be greyed out (disabled) so Codeception can't fill it and goes bananas.
Even if clear_cookies: true worked I would run into a problem where, for all my other test Cests that share the same Session, I would have to login _before(), which would add about 20% more time to run the tests.
The solution I've came up with: is to simply restart phantom before each test. Since phantom is managed by supervisord it is as easy as having a alias in my ~/bashrc, like so:
alias codecept=' supervisorctl stop phantomjs && supervisorctl start phantomjs && vendor/bin/codecept'
That way I can keep my cookies between each test and I can make sure my oAuth providers cookies are also cleared.
I also tried restarting phantom from within php on the __construct of the oAuth cest but that makes Codecept throw some weird errors.
Any ideas?
Thanks and best regards.