java googlemail blocks multiple access - jakarta-mail

I need to allow a user of my App to email themselves when an even occurs. I am not sure how to do this.
My first idea is to create a dummy gmail account, and have my App sign-in and send from there via java code. This means hardcoding the password BUT as account not used for anything other than one way emailing - it does not seem to be a problem.
However, I understand that google is pretty proactive about security and if my App (which is global) tries to log into same account in several different countries during a 24 hour period - it will block the email.
I have seen the "delegate" functionality, but that would mean that each user needs their own gmail account which is not practical.
Is there a way to force gmail to allow the sign-ins to happen from wherever?
Or is there a better approach to this problem?

probably not a good idea to have your app to mail from a private account, if I understand you correctly. Best to use email service like http://expresspigeon.com or http://sendgrid.com and simply send a transactional email from your app account. In other words, use an ESP.

The safest would be to ask the user for all the configuration information necessary to access their email server as themself, then send the email as themself to themself. You can use JavaMail to send the message, but you'll need to ask for all the configuration information that any other email application would ask for in order to configure access to their mail server.
There may also be Android-specific ways to do this using the default email application.

Related

how to send email on Code Name One using Gmail Api

I want to know if There Is a solution to send an email on a Code Name One app using Gmail Api,
i have an exception When i m using javaxmail,
error: cannot find symbol
import java.util.Properties;
symbol: class Properties
thanks in Advance.
You can use Display.sendMessage to send an email in Codename One. However, this is an "interactive" API that will launch the users email client and he'll need to press send to perform the actual emailing.
Alternatively you can use the sendgrid cn1lib to send an email via sendgrid. I would recommend against that though. If you send an email from the device that means your credentials (password etc.) would be on the device. A better way would be to contact your backend server and ask it to send the email for you. That way a hacker can't decompile your app and find out your credentials.
I agree with Shai's response, I'd just like to add a few more thoughts.
Sending emails from a mobile application (regardless of whether it is developed with Codename One) has two major problems:
the first problem, as mentioned by Shai, concerns the credentials: putting your Gmail account inside the client app code is a very bad idea;
the second problem is specifically about Gmail, since you're not referring to a generic mail service, but to Gmail itself: Stack Overflow is not the place to make recommendations on which services to use, however I can tell you why Gmail is probably not what you want to use. The main problem is that Gmail, when used for "third-party apps" (which Gmail considers insecure), doesn't allow you to change IP addresses frequently: if it notices an IP change, it blocks the service and forces you to manually unblock it in the security settings. Obviously the problem is minor if Gmail is contacted by your server that has a static IP address, but it becomes a big problem if Gmail is contacted directly from your users' phones, each of which will have a different IP.
That said, if your app made with Codename One needs to send emails (e.g. to activate new users), I recommend:
your app can use Codename One's Rest class to make a REST call to your RESTful server backend;
in your server, you could use an alternative service to Gmail that doesn't give problems if you change the server IP address every now and then or if you use the server both locally and remotely. For what is my experience, I can tell you that on my Spring Boot server I use org.springframework.mail.javamail.JavaMailSender, which is compatible with various mail services (just for information, I use a free ZohoMail account, however there may be many other alternative and equally valid mail services that I do not know).
As for using Codename One's Rest class, I'll point you to the developer guide (https://www.codenameone.com/developer-guide.html#_rest_api) and to this blog posts: https://www.codenameone.com/blog/terse-rest-api.html and https://www.codenameone.com/blog/new-rest-calls.html
When making Rest calls with Codename One, always keep in mind that there may be no Internet connection or other connectivity issues (or server-side errors), so careful handling of possible errors is critical.

Salesforce Server-to-Server integration without any user involved

I am working on a integration with Salesforce using REST APIs and, as part of the project, I need to send updates to Salesforce and these updates are not user triggered, they are system triggered.
Because of that, what I expect to see on Salesforce Field History is not a user name but the name of our Connected App (the app that made the update).
What I see today is the user name because the way the integration was made initially using OAuth Authorization Code flow.
To change that part of the project, I followed the link (OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration): https://help.salesforce.com/articleView?id=sf.remoteaccess_oauth_flows.htm&type=5
Making that, I was expeting to generate a token for a System, not for a User, but that's not what happened: when I used the token generate from the JWT Bearer Flow and ran the update, the Field History still shows the user name.
What could I do then?
Which are the options in Salesforce to achieve the behavior I'm expecting?
The most important, in my opinion, is to have a Token for our system, not for a user.
Thanks!
Everybody is an user in Salesforce. Even if you access unauthenticated pages (some contact us form? case or lead capture) - it gets tracked under special Guest User.
It sounds stupid but gives you unified interface to control permissions (Profiles/Permission sets). You want guests to access only FAQ articles and make cases? Sure thing, do it in profile, don't get paranoid about people trying to guess right URLs. You think an app was hacked? You can terminate the session just like any other "user". Want to allow login only in certain hours and from certain IP? Sure.
An app connecting with JWT will still need username (main difference being it's "just" certificate for signing the request instead of password).
Your best bet is to create dedicated "Mr System", "SystemX integration" account. It sounds like waste of license but in the long run saves you questions "why did you edit my account at 1 am" and you could even use it as backup account if you use SSO and it ever fails...

Salesforce: How to automate report extraction as JSON/CSV

I am new to Salesforce, but am an experienced developer. I am provided a link to a Salesforce report, which mostly has the right filters (query). I would like to use an REST API to pull that information as CSV or JSON so that I can do further processing on it.
Here are my questions:
Do I need special permissions to make API calls? What are they?
Do I need to create an "app" with client-key & secret? Does my admin need to grant me permission for this too?
There are a lot of REST APIs from Salesforce, which one do I need to get the info from the report? Analytics?
How do I authenticate in code?
You'd have to work with the System Administrator on the security pieces. Anybody who knows how the company works, can all users see everything, is there Single Sign-On in place, how likely is the report to change...
You will need an user account to pull the data. You need to decide if it'll be some "system account" (you know username and password and have them stored in your app) or can it run for any user in this org. It might not matter much but reports are "fun". If there will be data visibility issues 6 months from now, you'll be asked to make sure the report shows only French data to French users etc... you can make it in report filters or have multiple reports - or you can just use current users access and then it's the sysadmin that has to set the sharing rules right. (would you ever think about packaging what you did and reusing in another SF instance? Making a mobile app out of it? Things like that, they may sound stupid now but will help you decide on best path)
The user (whether it'll be system account or human) needs Profile permissions like "API Enabled" + whatever else you'd need normally ("Run Reports" etc). If you're leaning towards doing it with system user - you might want to look at Password Policies and maybe set password to Never Expires. Now this is bit dangerous so there would be other things you might want to read up about: "API only user" (can't login to website), maybe even locking down the account so it can login only from certain IP ranges or at certain times when the job's supposed to be scheduled...
Connected App and OAUth2 stuff - it's a good idea to create one, yes. Technically you don't have to, you could use SOAP API to call login, get session id... But it's bit weak, OAuth2 would give you more control over security. If you have sandboxes - there's little-known trick. You can make connected app in production (or even totally unrelated Developer Edition) and use client id & secret from it to login to sandboxes. If you create app in sandbox and you refresh it - keys stop working.
(back to security piece - in connected app you can let any user allow/deny access or sysadmin would allow only say these 3 users to connect, "pre-authorize". Could be handy)
Login - there are few REST API ways to login. Depends on your decision. if you have 1 dedicated user you'll probably go with "web server flow". I've added example https://stackoverflow.com/a/56034159/313628 if you don't have a ready SF connection library in your programming language.
If you'll let users login with their own credentials there will be typical OAuth "dance" of going to the target page (Google login, LinkedIn, Twitter...) and back to your app on success. This even works if client has Single Sign-On enabled. Or you could let people type in their username and pass into your app but that's not a great solution.
Pull the actual report already
Once you have session id. Official way would be to use Reporting API, for example https://developer.salesforce.com/docs/atlas.en-us.api_analytics.meta/api_analytics/sforce_analytics_rest_api_get_reportdata.htm
A quick & dirty and officially not supported thing is to mimic what happens when user clicks the report export in UI. Craft a GET request with right cookie and you're golden. See https://stackoverflow.com/a/57745683/313628. No idea if this will work if you went with dedicated account and "API access only" permission.

send email on Google App Engine from custom domain

What I have done:
I have added my domain app.mydomain.com to my app engine project, and can successfully visit id.appspot.com using app.mydomain.com.
I have registered mydomain.com on google app for business.
The problem:
The problem is -- I am NOT able to send emails using #mydomain.com address. If I register an info#mydomain.com as an developer, this will probably solve the problem, but we need to send from more than one address, and I don't think registering a new developer for each address is reasonable.
Anybody knows how to solve this? Thanks!
You have two options:
Register all emails that you want to use as administrators/developers but as you mentioned in your post you don't want to do that.
Use SendGrid (or any other email services like Mandrill, Mailgun, etc.) which will give you a lot more features comparing to what GAE offers, including 25k free emails instead of GAE's 100.
According to the docs, the sender would need to be an administrator on the project (called "owner" in the new Developers Console). Another route would be to just use a separate email sending service like SendGrid or Postmark.
You can use the GMail API to send emails as users of your domain. Note that the emails need to be aliases, groups or users of your domain.
You shouldn't have any problem adding and verifying your domain, adding the necessary permissions to send emails. Then, every email address in your domain can be used. See here in the docs: https://developers.google.com/appengine/docs/java/mail/#Java_Sending_mail

Email confirmation best practices for mobile apps

So I'm writing a mobile app and have reached a point where I need to allow users to register a username. I'm doing this by asking for an email address, username and password.
Typically, it's been normal to set this sort of thing up on the web by having the user confirm his email address by clicking on a link sent to his inbox.
Needless to say, on a mobile app this is a bit clunky as the user will be redirected out of your app and into his browser.
So I had a look at how other mobile apps are doing it (WP7) and was surprised to see that DropBox and Evernote both allow you to sign up without confirming your email address. The end result of this is that I was able to sign up with completely bogus email addresses and/or valid email addresses that don't belong to me.
I assume this is done on purpose.
Your thoughts?
I came across the same issue when writing a social networking style app. I chose to have the user create a username and then provide and email and password. I do not verify the email address and I've never attempted to send any email to them (yet).
What I would suggest would be alternate ways to validate a users email address. My app allows users to do Facebook Connect. All they have to do is log into Facebook, and the app talks to Facebook to confirm that they are using a valid email address. No need to verify it with a URL in an email.
I believe Twitter has a similar service and there may even be a few others that provide an API.
I've also discovered that a lot of people just want to tinker around in the app and not create an account at all. It's definitely a balancing act
I'd say it depends on your app and how important it is to ensure users have valid email addresses. In an app I'm creating now, we want to discourage users from signing up with multiple bogus accounts (because our system could be gamed that way) so we're not allowing users to log in until their email address if verified. On other sites however, it might not be such a big deal so why bother users with that extra step?
As for a mobile device, I don't see why you can't still send a verification email that sends them to your website to verify their email address. There are plenty of mobile apps that also have a website users can log into to manage their account.
Another option is have multiple "states" for users. Before they validate their email, they are in a "pending" state. Once they click it, they're in an "active" state. If you store the createDate for the user, you can periodically remove pending users older than 1 week (or however long).
The bonus is that you can easily add more states, such as suspended or deleted.
Personally, I wasn't too happy for users to create accounts with any old email address.
I think a few decent options are:
send a confirmation email with a link that uses a Custom Url Schema to redirect back to the app (although this is only good if they use the link on the same device)
send a short PIN in the email for them to enter back in the app.
send a confirmation email with a web link, have your server confirm the valid email/token, and have your app check the account status either periodically or with some sort of realtime tech like SignalR or Firebase.
I prefer the last one, although hardest to implement. A user might well have their phone in their hand and their laptop next to them, register in the app and try to click the link in the email that just showed up on their laptop. I like the idea of the app then just "knowing" that they've validated.
Do you have a web server? Write a web service that does the validation for you on the server side, and sends back the result.
Either you can use some platform, such as Facebook connect as #Brian replied above, or you may give users a reasonable timeframe to verify, for example, a few days or even a week. After that, the account gets removed.
You can even have your app issue notifications to remind the user to verify his account (such as every day, or on the last date of the verification.
Don't ask for email confirmation on mobile and allow the user to use the service. When the user is using a PC, then ask the user to confirm his email.
I won't defend my recommendation because most of the solutions here are valid. There isn't one correct way. You asked for ideas and here's one.
A good strategy is to allow people to use as much of your app as possible given the amount of data they've provided.
For example, in the case of a newsreader you might let someone browse your app without registering, then require an account for offline syncing, and a verified email for alerts. Always give people a good reason to take the next step, and build engagement first, then people will forgive you pestering them later.

Resources