How do i only allow specific email to login into my page - javascript

There are two sides, Admin and Users. I am using the same database in firebase for both Users and Admin. It means that Users that are registered in my firebase authentication, can login to Admin webpage. How do i allow only specific admin's email to login into the Admin page.
For example:
Admin has an email of admin#admin.com
User has various email like 123#gmail.com, 222#gmail.com and etc.
What i want is only to allow admin#admin.com to be able to login into the Admin page but restrict login for User emails to login to the Admin page.

Using a Javascript, a simple solution would be to split the email String on the #, which will return you an Array of substrings and compare the second part which is the domain. Then, you could condition the rest of your code to work only if the criteria is true.
An example would be:
const allowedEmailDomain = 'admin.com';
const email = 'test#admin.com';
if (email.split('#')[1] === allowedEmailDomain) {
// do something, we accept this email
} else {
// return an error or do nothing
}

I make the assumption that, on the back-end side, your application is correctly secured, i.e. you have security rules in your database that only allow the users with an "admin" profile/role to read or write "admin" data in the database.
If this is not the case you MUST set correct security rules, since securing your Firebase instance only from a front-end perspective is not sufficient, as it is not very difficult to reverse engineer your app code and write some JavaScript code that will interact with your back-end. For that you could use Custom Claims.
So, with this assumption, it means that you need to adapt your front end in such a way the admin screens are only seen by the admin users.
One of the best answer is again to use Custom Claims, as explained here https://firebase.google.com/docs/auth/admin/custom-claims#access_custom_claims_on_the_client (Section "Access custom claims on the client") and in this official Firebase video: https://firebase.google.com/docs/auth/admin/custom-claims#access_custom_claims_on_the_client
Note that trying to block a user based on his email domain may not be a good solution as it is easy, in few lines of JavaScript code, to register to your Firebase project as a user with a mail like whatever#admin.com or with any other email (using createUserWithEmailAndPassword)

Just block every other domain as #admin.com.
$allowed_domains = array("admin.com");
$email_domain = array_pop(explode("#", $email));
if(!in_array($email_domain, $allowed_domains)) {
// Not an authorised email
}
It's simply. Make an array for allowed domains, explode by #, get the last element of the array and check if it exists in the allowed domains array.

Related

Password protect a page with Firebase

I'm building a CMS with Firebase, but struggling to assess whether what I require is possible, or if I'm missing something.
What I require is the ability to password-protect a page only, and remember that browser as having access. A full user account (using the in built auth) is required to edit the content of the page, but only a password is required to view it.
I know I can use the auth flow with email, but am looking for the editor to be able to create a password for viewing only.
Is this possible, or should I look elsewhere?
The way I commonly do this is a bit like Jeremy's answer, but simpler.
You ask the user for a password when they enter the page, and store that password locally (for reloads).
Then you store data in your database under a path that includes the password. So say that your password is geheim, you could store the data under:
data: {
geheim: {
value: "This is the secret value"
}
}
Now you secure your database with rules like these:
{
"rules": {
".read": false,
"data": {
"geheim": {
".read": true
}
}
}
}
Now somebody can only read the data at /data/geheim if they know the entire path. So you'll enter the data part in your code, but require them to enter geheim as the password. Then you attach a listener with:
firebase.database().ref("data").child(password).once("value", function(snapshot) {
console.log(snapshot.val());
});
And if the user entered the correct value for password, this will read the value.
Firebase Authentication only deals with authenticated user accounts. It doesn't deal with simple password protection of content.
It's definitely possible, but as Doug's answer indicated, you'll have to do it outside normal means. Off the top of my head, the way I would accomplish this is...
When a user enters a password, it stores the password in their local storage.
On page load, or on password entry... pull the password from local storage
Make a request to a Firebase cloud function, makes sure to include the password it just retrieved from local storage, and which page it is requesting content for
Firebase cloud function validates password
Firebase cloud function retrieves data for specific page
Firebase cloud function returns said data
Load data on front-end like normal
As you already identified, you should stick with the built-in Firebase auth for content editing.
I definitely suggest Frank's answer because it's simple and it works. Btw the moral of the story is that you use the firebase Database to store you view-only password but, if you want to complicate your life because you need a strong view-only password system, the Authentication product provides the custom authentication method that you can integrate with your existing auth system (for example fb login). It obviously needs a server-side implementation that is a code that takes the password, check if it's valid and sends the token back to the Auth system.
Here more details: https://firebase.google.com/docs/auth/web/custom-auth

Login Email with Google to Specific Domain Name

I am not able to find any documentation on how to restrict the login to my web application to only accept authentication requests from users with an email on a specific domain name or set of domain names. I would like to block as opposed to blacklist.
Does anyone have any document or template which how to achieve using jsp,angularjs,javascript, documentation on the officially accepted method of doing so, or an easy, secure work around?
For the record, I do not know any info about the user until they attempt to log in through Google's OAuth authentication. All I receive back is the basic user info and email.
You can use method of string class String. contain("#yourdomain") it will return boolean value true or false
It will go like..
if(request.getParameter("email").contains("#yourDomainName"))
Do something;

Is it possible to post to chat.postMessage as any user in a Slack team?

I'm building a Slack integration that is intended to modify some text and then post it to a Slack channel as though the user who triggered the command had said it.
e.g. /makeFace disapproval
#Ben 3:45pm
ಠ_ಠ
I ask for the client permission scope, which adds the chat:write:user permission. But when I hit the chat.postMessage endpoint, it only seems to allow you to post as the user who added the integration because the token it returns seems to be individuated for that user.
I know that giphy, for instance, sends its gif messages as though you are the originator, but I can't find out how they manage it. Is there any documentation for sending messages as other members of the team?
There are 2 ways to achieve this:
A. Overwriting username and icon
When you send a message with chat.postMessage it is possible to set a user name with the property username. The message will then appear as being send by that user (same for icon with icon_url).
However, this is not meant to impersonate real users, so even if you use the same username and icon as the real user the message will have the app tag, so that they can be distinguished from a real user.
Here is an example how it looks like (from a gamer Slack about flying and killing space ships):
But depending on what your requirements are that might work for you.
If you want to use it make sure to also set the as_user property to false (yes, really) and it will not work with a bot token, only with a user token.
See here for more details on how it works.
This also works for the legacy version of Incoming Webhooks, not with the current version of incoming webhooks though. (You can still get the legacy version, see this answer)
B. Having the user's token
Another approach is to always use the token from the respective user for sending the message. In combination with as_user = true messages sent by your app will look exactly as if they would come from the respective user (no APP tag).
To make that happen your app would need to collect tokens from all users on your workspace and store them for later use. This can be done by asking every user to install your app (called adding a "configuration") through the Oauth process (same you use to install your app to a workspace), which allows your app to collect and store those tokens for later use.
Update: This doesn't work. It impersonates the user who installed the app, so it merely seems to work... until another user tries to use it (and they end up impersonating you).
Go to your App's management page. Select "OAuth & Permissions".
Add the chat.write OAuth Scope to your app as a User Token Scope, not a Bot Token scope.
Take note of your User OAuth Token at the top of this page (not your But User OAuth Token).
Call chat.postMessage with
username = user id of the user you'd like to post on behalf of
token = the token from step 3. above
The resulting post will be 100% impersonated. Not just the name and icon as mentioned in other answers, but it'll 100% function as if it came from the user.
I hope this will help those who are still facing this issue.
First give the chat:write and chat:write.customize scope to your bot. The scope chat:write.customize Send messages as #your_slack_app with a customized username and avatar
From "OAuth & Permissions" settings get the bot OAuth token or even bot access token (both will work).
Then set the arguments like the following.
username to specify the username for the published message.
icon_url to specify a URL to an image to use as the profile photo alongside the message.
icon_emoji to specify an emoji (using colon shortcodes, eg. :white_check_mark:) to use as the profile photo alongside the message.
You can visit the docs from here

Token google analytics and relationship webPropertyId / profilId

I am currently developing a dashboard with Google Analytics API, which will be accessible website back office. I realized this during this developing javaScript I block on 2 things:
The first is the authentication must be transparent to the user via the use of a token.
In my approach I utlise OAuth2 of the API by generating a token with the playground for this token to be valid
I join my code
gapi.analytics.ready(function() {
var CLIENT_ID = 'XXXX.apps.googleusercontent.com';
var CLIENT_SECRET ='XXX...';
var ACCESS_TOKEN = 'XXX...';
var REFRESH_TOKEN ='XXXX....';
var EXPIRE_IN ='3600';
var TOKEN_TYPE ='Bearer';
var ACCESS_TYPE ='offline';
var SCOPE = 'https://www.googleapis.com/auth/analytics.readonly'
gapi.analytics.auth.authorize({
clientid: CLIENT_ID,
client_secret:CLIENT_SECRET,
serverAuth: {
access_token: ACCESS_TOKEN,
refresh_token: REFRESH_TOKEN,
//token_type: TOKEN_TYPE,
//expires_in: EXPIRE_IN,
//access_type: ACCESS_TYPE,
}
});
After the validity of the data are more accessible with a 401 error (logical because the token is no longer valid)
or to my first question about how to obtain a valid token all the time?
My second question concerns the recovery of data I based on the recovery of the profile number (like many such works).
However SEVERAL of my sites using the tracking number (UA-XXXXXXXX-N).
Knowing that sites use this number is the posibility to find the profilId thanks to the tracking number and accountId that lion can deduct.
But I do not know how to arive.
Es that someone already out how to make this relationship ???
Pending your answers thank you in advance
(Sorry for the translation I utlise google translation)
Authenticating using the playground is a bad idea, and wont work for long. You are going to have to code your own authentication process here. It sounds like you want to do this with your own websites this your own data, I would normally recommend you use a service account. A service account can be set up to authenticate without requiring the user to do anything. While some people say that you can use a Service account with JavaScript, I don't feel that it is a secure solution, I also wonder if it is ok to do this under the current terms of service. So my first recommendation to you is to look into using as service account with a server sided scripting language. say PHP. If you don't a user will have to authenticate and then they will only be seeing the information on there own website not your website.
Second how to find the Profile id:
The first and probably easiest option would be to just go to the admin section of Google analytics and find your profile id there. If you are looking for a way of doing this programmatically you, I would use the account summaries report from the Management API this will give you a list of all of the accounts for the current authenticated user you can then scan that to find the profile ids you want.

Node/Express Email + Token Authentication

I'm wondering if any Node/Express gurus could give me a little advice on if the following scenario that I'm trying to achieve is possible. I think it is, I'm just a little unsure on the best-practise way to tackle the problem.
I'm currently in the process of building a small client that will be protected. To gain access to the following the following steps must occur:
Input name + email address in a form that then sends this data in an email to an admin.
The email will containing a prebuilt link containing query params of the data that was input into the field. The link will have an API URL prior to the query params.
When the link is clicked an API request will be performed that takes the query params (mainly the email address) and grants this email address access to the client for a specific period of time such as 2 hours.
The client will go to subdomain.domain.com, enter their email address (which gets validated to check that an admin has approved the email address) and have access to the client for 2 hours. There will also be a timer with the remainding session length.
The majority of this I can take care of but I thought I'd give you an insight in to the full picture of what it is I'm trying to achieve. The part that I have queries about is section 3 and giving an email address access to the client for a specific period of time. I don't want any passwords to be involved so what is the most-secure, more-advisable solution to this? Would I have to use tokens?
I will be building the server-side using Express unless I strictly have to use Node for whatever reason.
Thanks in advance!
When the admin approves the request, the api inserts a row into a db (mongo would be easy) which expires in 2 hours (or however long). Next, when the user goes to the subdomain, they enter their email address. Your express app checks if the email is in mongo. If it is, they have access. You can stick their email in a cookie and check it that way on future requests.

Categories

Resources