Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create none-interactive version of authentication #5

Open
shytikov opened this issue May 5, 2020 · 5 comments
Open

Create none-interactive version of authentication #5

shytikov opened this issue May 5, 2020 · 5 comments
Labels
enhancement New feature or request
Milestone

Comments

@shytikov
Copy link
Contributor

shytikov commented May 5, 2020

It is possible to implement none-interactive version of this package if we know:

  • Organization URL;
  • Login / Password;
  • MFA secret key;

Idea is instead of just opening Electron and let users enter their credentials, actually open Electron without head and type in data, which user will normally do manually, basically implement EasyRepro / Selenium approach.

The only challenge here is Electron. As far as I can see puppeteer needs to be used (to fill in forms), but Electron is not shipped with its support. There are packages like puppeteer-in-electron, but for me they are triggering firewall confirmation window, because a port on localhost needs to be open.

I was lucky to accomplish this task using https://github.com/segmentio/nightmare and it's API is much nicer than just bare puppeteer.

I can assist in implementing, but I see following issues which I would prefer achieve some support in:

  • additional command line parameters, it would be already quite a few, and many of them are optional, so it could be that arguments handling could need some love;
  • electron parts, I might ruin things that I don't know are needed;
  • blessing to implement this feature;
@scottdurow
Copy link
Owner

@shytikov Interesting idea - what is your use case for this? I envisioned cds-auth being used interactively and then the token picked up non-interactively later on by tests/cli commands etc. Could you outline the scenario you are thinking of?
Thanks for your help with this project!

@shytikov
Copy link
Contributor Author

shytikov commented May 6, 2020

Basically the same vision as yours, but maybe a bit more Dr. Evilish.

I don't have numbers on top of my head, but refresh token is not valid for eternity, so it could be that you would be prompted to to re-authenticate when you not expecting that. And being able to get token (or auth-cookie !!!) silently if needed, could be very nice option for CI scenarios.

Please note option to "steal" auth-cookie from CRM, because that will allow very interesting scenarios like being able to interact with CRM web resources, since if you inject that cookie to your requests you could get authenticated on front end UI interactions, like having global Xrm object available for your services. Which will expand cases when this library could be used.

@shytikov
Copy link
Contributor Author

shytikov commented May 6, 2020

Here is some code (not perfect, just an illustration):

import Nightmare from 'nightmare';
import authenticator from 'authenticator';

const environment = 'https://your-env.crm4.dynamics.com/main.aspx?app=d365default';
const username = 'admin@your-env.onmicrosoft.com';
const password = 'yourPA$$WORD';
const secret = 'sba3 p5tq ckgp 9fqz'; // MFA Secret Key

const page = new Nightmare({ show: true }); // Or { show: false }

page
  .goto(environment)
  .wait(1000)
  // Enter your login
  .type('.inner input[type="email"]', username)
  // Submit on first page
  .click('.inner input[type="submit"]')
  .wait(1000)
  .type('.inner input[type="password"]', password)
  .click('.inner input[type="submit"]')
  .wait(3000)
  // Make sure we have selected "use verification code from your authenticatior app"
  .click('#signInAnotherWay')
  .wait(1000)
  .click('#idDiv_SAOTCS_Proofs > div:nth-child(2) > div')
  .wait(1000)
  // Type in MFA code
  .type('.inner input[type="tel"]', authenticator.generateToken(secret))
  .click('.inner input[type="submit"]')
  .wait(1000)
  .click('.inner input[type="submit"]')
  // PROFIT
  .end()

@scottdurow
Copy link
Owner

In a CI/CD scenario, I think I would recommend using a Application/Client Secret style of auth - also I'm not convinced that we would able to use electron in a non-interactive pipeline/github action?

@shytikov
Copy link
Contributor Author

shytikov commented May 6, 2020

Most certainly it would be possible to call electron if npm has it pre-built for the OS on which runner is triggered.

Apart of pure CI/CD cases this none-interactive authentication could be used for JS/TS scripts that perform manipulations with CRM. Like I would love to use JS with Jupyter Notebook integration, and always having problems with a token retrieval, since it requires user interaction which is problematic in context of Jupyter Notebook webpage.

In general, it would be nice to have a command line tool which could provide you with CRM token and will not require browser to be opened.

@scottdurow scottdurow added this to the v2 milestone Jun 14, 2022
@scottdurow scottdurow added the enhancement New feature or request label Jun 14, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants