Node.js Meteor create a splash page with password to enter into the app. Keeping user login separate and inside the app past the splash page - node.js

Wanting to create a splash page where a user can enter a site password that is the same for everyone. It's to hide the site while it's in preview only. Not sure why I'm not getting how to do this. It's got to be relatively straight forward in meteor.
Currently have Meteor-Router installed. Is this the best approach? How do I go about this?
Thank you

Here is one possible answer in CoffeeScript:
Add a filter on the Router like:
Meteor.Router.filters
'authorizeUser': (page) ->
if Session.get 'knowsTheSecret' then page else 'splash'
Meteor.Router.filter 'authorizeUser'
That says every page request must have the knowsTheSecret session variable set or the user will get booted back to the splash page (defined elsewhere).
On the server (as in put this in the server directory). Create a method to validate the password:
Meteor.methods
checkSecret: (string) ->
string is 'super secret password'
When the user clicks the login button on your splash page, you can call the method like so:
Template.splash.events
'click button': ->
password = $('#text-field').val()
Meteor.call 'checkSecret', password, (err, result) ->
Session.set 'knowsTheSecret', result
So the Session varable will only get set if the user actually knows the secret. This, of course, is not secure in any real way (They user could just open a console and set the session variable manually) but it's a start. Play around with all that and see if it gets you closer to a working solution.

Related

How to fill login prompt with Webdriver IO?

I'm working on a CLI with OCLIF. In one of the commands, I need to simulate a couple of clicks on a web page (using the WebdriverIO framework for that). Before you're able to reach the desired page, there is a redirect to a page with a login prompt. When I use WebdriverIO methods related to alerts such as browser.getAlertText(), browser.sendAlertText() or browser.acceptAlert, I always get the error no such alert.
As an alternative, I tried to get the URL when I am on the page that shows the login prompt. With the URL, I wanted to do something like browser.url(https://<username>:<password>#<url>) to circumvent the prompt. However, browser.url() returns chrome-error://chromewebdata/ as URL when I'm on that page. I guess because the focus is on the prompt and that doesn't have an URL. I also don't know the URL before I land on that page. When being redirected, a query string parameter containing a token is added to the URL that I need.
A screenshot of the prompt:
Is it possible to handle this scenario with WebdriverIO? And if so, how?
You are on the right track, probably there are some fine-tunings that you need to address to get it working.
First off, regarding the chrome-error://chromewebdata errors, quoting Chrome DOCs:
If you see errors with a location like chrome-error://chromewebdata/
in the error stack, these errors are not from the extension or from
your app - they are usually a sign that Chrome was not able to load
your app.
When you see these errors, first check whether Chrome was able to load
your app. Does Chrome say "This site can't be reached" or something
similar? You must start your own server to run your app. Double-check
that your server is running, and that the url and port are configured
correctly.
A lot of words that sum up to: Chrome couldn't load the URL you used inside the browser.url() command.
I tried myself on The Internet - Basic Auth page. It worked like a charm.
URL without basic auth credentials:
URL WITH basic auth credentials:
Code used:
it('Bypass HTTP basic auth', () => {
browser.url('https://admin:admin#the-internet.herokuapp.com/basic_auth');
browser.waitForReadyState('complete');
const banner = $('div.example p').getText().trim();
expect(banner).to.equal('Congratulations! You must have the proper credentials.');
});
What I'd do is manually go through each step, trying to emulate the same flow in the script you're using. From history I can tell you, I dealt with some HTTP web-apps that required a refresh after issuing the basic auth browser.url() call.
Another way to tackle this is to make use of some custom browser profiles (Firefox | Chrome) . I know I wrote a tutorial on it somewhere on SO, but I'm too lazy to find it. I reference a similar post here.
Short story, manually complete the basic auth flow (logging in with credentials) in an incognito window (as to isolate the configurations). Open chrome://version/ in another tab of that session and store the contents of the Profile Path. That folder in going to keep all your sessions & preserve cookies and other browser data.
Lastly, in your currentCapabilities, update the browser-specific options to start the sessions with a custom profile, via the '--user-data-dir=/path/to/your/custom/profile. It should look something like this:
'goog:chromeOptions': {
args: [
'--user-data-dir=/Users/iamdanchiv/Desktop/scoped_dir18256_17319',
],
}
Good luck!

How to transfer data from page to another in node js

Hello there i am learning node.js and got stuck in a scenario.The flow is that in website user register himself and after successfully registering i will be sending him to route named create_profile which in is post request and also i want to send userId to create_profile route.In case if user close the website then if he agains open it and login then if profile is incomplete then i will be taking his userId and send to create_profile route.And after that to home page.What i was thinking to store session for user authentication in create profile page and login.This is because if login there can be tow cases : If user has successfully completed his profile then take him to home and store a global session there and second case it to take him to create profile as its incomplete then after successfully creating take him to home store global session for user authentication.But my confusion is to how to pass userId from login to create profile which is post request.Do i need to make temp session ? Please solve my issue i am confused how to solve this .
You can create a "profile_completed" coloumn in DB and set it as "false" (default), update it to "true" if user has completed the profile. While user login check if his profile is updated ,if yes send him to home else ask him to update.
You can pass user I'd to create_profile via request or get it from session storage you saved earlier

How can I get a token for the Drive API?

I want to implement the Google Drive API to my web application using NodeJS and I'm struggling when I try to get a token via OAuth.
I've copied the code from this guide and run the script using Node and it returns an error in this line:
var redirectUrl = credentials.installed.redirect_uris[0];
Googling around I found that I can set that variable as http://localhost:8080 and set the same value in the Authorized redirect URIs configuration in the Google Developers Console and that error goes away, fine, it works. Now it asks for a code that I should get by using an URL.
https://accounts.google.com/o/oauth2/auth?access_type=offline&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&response_type=code&client_id=CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A8080
Then I've added the client id and enter to that URL with Chrome and then returns a connection refused error. No clue what to do in here, I searched about my problem and I can't found an answer. By looking at the direction bar in Chrome I see that there's a parameter called code and after it, there's random numbers and letters. Like this:
http://localhost:8080/?code=#/r6ntY87F8DAfhsdfadf78F7D765lJu_Vk-5qhc#
If I add any of these values it returns this error...
Error while trying to retrieve access token { [Error: invalid_request] code: 400 }
Any ideas on what should I do? Thanks.
Did you follow all the directions on the page you indicated, including all of those in Step 1 where you create the credentials in the console and download the JSON for it? There are a few things to note about creating those credentials and the JSON that you get from it:
The steps they give are a little different from what I went through. They're essentially correct, but the "Go to credentials" didn't put me on the page that has the "OAuth Consent Screen" and "Credentials" tabs on the top. I had to click on the "Credentials" left navigation for the project first.
Similarly, on the "Credentials" page, my button was labeled "Create Credentials", not "Add Credentials". But it was a blue button on the top of the page either way.
It is very important that you select "OAuth Client ID" and then Application Type of "Other". This will let you create an OAuth token that runs through an application and not through a server.
Take a look at the client_secret.json file it tells you to download. In there, you should see an entry that looks something like "redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"] which is the JSON entry that the line you reported having problems with was looking for.
That "urn:ietf:wg:oauth:2.0:oob" is a magic string that says that you're not going to redirect anywhere as part of the auth stage in your browser, but instead you're going to get back a code on the page that you will enter into the application.
I suspect that the "connection refused" error you're talking about is that you used "http://localhost:8080/" for that value, so it was trying to redirect your browser to an application running on localhost... and I suspect you didn't have anything running there.
The application will prompt you to enter the code, will convert the code into the tokens it needs, and then save the tokens for future use. See the getNewToken() function in the sample code for where and how it does all this.
You need to use this code to exchange for a token. I'm not sure with nodejs how to go about this but in PHP I would post the details to the token exchange url. In javascript you post array would look similar to this ....
var query = {'code': 'the code sent',
'client_id': 'your client id',
'client_secret': 'your client secret',
'redirect_uri': 'your redirect',
'grant_type': 'code' };
Hope this helps
Change redirect uri from http://localhost:8080 to https://localhost:8080.
For this add SSL certificates to your server.

How to redirect to special page when user is not in database in Yesod/Haskell

So, I really like the Yesod authentication options, since it means I don't have to manage securely storing passwords and hashes and such.
What I'm wondering is, how do I detect if someone is logging in for the first time, and then redirect them to a "Create an account" page so that they can link their credentials to the account for my web app (username, profile picture, etc.)
Right now, it's easy to detect whether the user is in my database. The part that's giving me trouble is figuring out how to do the redirect. Ideally, I want a flow like this
user tries to access page FOO requiring login
if they are logged in
they go to FOO
if they are not logged in
they log in with credentials
if the credentials are in the database
they go to FOO
if the credentials are not in the database
they get redirected to CreateProfile
when the submit CreateProfile, they are redirected to FOO
Right now, I've set the loginDest to redirect them to a "check if in database" page, which then either redirects home or prompts them to create a profile. The problem with this is that the check only occurs if they go to AuthR LoginR. It does not occur if they go to a page which uses requireAuth.
I could do a check every time they go to a require page, but that would be a lot of code reuse, and seems ugly and non-modular.
Another potential solution is to redirect during getAuthId, but I have no idea how to do that, since it has type Handler credentials, not Html.
I'm open to suggestions about what is possible, and what is the best practice.
Isn't this what isAuthorized is for? You can view an example in the yesod cook book under "Authorization". The relevant part being,
-- route name, then a boolean indicating if it's a write request
isAuthorized HomeR True = isAdmin
isAuthorized AdminR _ = isAdmin
-- anyone can access other pages
isAuthorized _ _ = return Authorized
where instead of the isAdmin function, you'd simply check if they are logged in or not, and redirect them to the login page by returning AuthenticationRequired if they aren't.
EDIT: You mentioned something about checking if they are a "new" user. You should be able to do this in the function where you check if they are logged in. If you want to catch this for all pages, you could use isAuthorized _ _ and run the function there.
I am not 100% sure I have followed your question because your first paragraph just asks for detecting new users but later on you ask about requireAuth which you may be doing on all users not just new users. Anyways, assuming it is just for new users, I do something like this:
getMyLoginR :: Handler Html
getMyLoginR = do
ur <- getUserRecord -- this is your check in the DB function
-- (you will have to write it)
if (isNothing ur)
then do
setMessage "Please set your preference"
redirect PrefHandlerR -- this is where you put your form asking for details
else do
redirect OtherHandlerR

session variable destroyed

I have an issue with login session. Basically the flow is like this:
user creates account and defines a username;
user logins using url 'http://[username].website.com'
(coded in php & mysql, using session cookie)
My problem is: when trying to directly login from the index page 'www.website.com' I don't manage to get my user logged to his URL http://username.website.com
Let say i have opened url "www.example.com" and created a session variable in this url. Now i want to access that session variable in url "test.example.com". How to do that? any solution welcomed
Note: at the top of every php file i have used the below code but my session variable was destroyed and i can't access the session variable in another page. I have also set session.cookie_domain = ".website.com" on "php.ini" file.
ini_set('session.cookie_domain', '.website.com');
session_name("sessionid"); session_start();
Try to put session_start() at the beginning? Remove all other lines and see what happens. It's difficult to diagnose without seeing the actual code.

Resources