How do I know whether my user is from EU countries? [closed] - gdprconsentform

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 months ago.
Improve this question
Since the EU is having special laws for ads publishers. I want to display the cookie consent for my users. But I just couldn't find any good frameworks on the internet to determine whether a user is from an EU country.
Is there any way I can achieve this?
Hope to get some answers covering stuff in detail.
Thanks

If I correctly understand your question, you can easily do this by determining the local timezone of a user. There are several ways of doing it.
Moment.js
Moment Timezone has a function that guesses the timezone of a user. It is quite accurate, provided you are using the most recent version.
Example:
<div id="guess"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.23/moment-timezone-with-data-2012-2022.min.js"></script>
<script>
document.getElementById('guess').innerText = moment.tz.guess();
</script>
Moment.js uses Intl API which is a built-in JavaScript internationalization API. It also has its data bank it checks the result of the Intl API against to provide more accurate information. It also requires you to have included Moment.js before it can work.
Jstz package
Jstz is a simple lighter package for detecting timezone. It also makes use of the Intl API, so you can be confident of its results. To use the package, you can grab the CDN as follows:
<div id="guess"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>
<script>
document.getElementById('guess').innerText = jstz.determine().name();
</script>
Intl API Itself:
You can use the Intl API directly!
The Intl object is the namespace for the ECMAScript Internationalization API, which provides language sensitive string comparison, number formatting, and date and time formatting. The Intl object provides access to several constructors as well as functionality common to the internationalization constructors and other language sensitive functions.
Example usage:
<div id="guess"></div>
<script>
document.getElementById('guess').innerText = Intl.DateTimeFormat().resolvedOptions().timeZone;
</script>
What you can notice from these libraries used for detecting timezone is that they do not require any network calls from your end. This means if you intend to only pick user timezones, you may not need to do IP lookups.
Then you can just match the timezone with the specific EU timezone and determine if your user is from within EU.
If you want to do an actual/accurate pinpointing of a user, you have to use GeoLocation. Here is a simple script which does that: https://raw.githubusercontent.com/AdeyinkaAdegbenro/Detect_Location/master/detect_location.js.
Other APIs you might want to check (whatever suits you):
http://ip-api.com/json
https://ipinfo.io/
https://geoip-db.com

Adding to the accepted answer, I did all the hard work in determining which time zones are subject to the GDPR laws. I used the dayjs package, which is similar to momentjs.
const EU_TIMEZONES = [
'Europe/Vienna',
'Europe/Brussels',
'Europe/Sofia',
'Europe/Zagreb':
'Asia/Famagusta',
'Asia/Nicosia',
'Europe/Prague',
'Europe/Copenhagen',
'Europe/Tallinn',
'Europe/Helsinki',
'Europe/Paris',
'Europe/Berlin',
'Europe/Busingen',
'Europe/Athens',
'Europe/Budapest',
'Europe/Dublin',
'Europe/Rome',
'Europe/Riga',
'Europe/Vilnius',
'Europe/Luxembourg',
'Europe/Malta',
'Europe/Amsterdam',
'Europe/Warsaw',
'Atlantic/Azores',
'Atlantic/Madeira',
'Europe/Lisbon',
'Europe/Bucharest',
'Europe/Bratislava',
'Europe/Ljubljana',
'Africa/Ceuta',
'Atlantic/Canary',
'Europe/Madrid',
'Europe/Stockholm'
];
const isConsentRequired = () => {
dayjs.extend(timezone);
return EU_TIMEZONES.includes(dayjs.tz.guess());
}

This is based on #Andrew Samole answer but works with vanilla js:
function determineIfCookieConsentRequired() {
const EU_TIMEZONES = [
'Europe/Vienna',
'Europe/Brussels',
'Europe/Sofia',
'Europe/Zagreb',
'Asia/Famagusta',
'Asia/Nicosia',
'Europe/Prague',
'Europe/Copenhagen',
'Europe/Tallinn',
'Europe/Helsinki',
'Europe/Paris',
'Europe/Berlin',
'Europe/Busingen',
'Europe/Athens',
'Europe/Budapest',
'Europe/Dublin',
'Europe/Rome',
'Europe/Riga',
'Europe/Vilnius',
'Europe/Luxembourg',
'Europe/Malta',
'Europe/Amsterdam',
'Europe/Warsaw',
'Atlantic/Azores',
'Atlantic/Madeira',
'Europe/Lisbon',
'Europe/Bucharest',
'Europe/Bratislava',
'Europe/Ljubljana',
'Africa/Ceuta',
'Atlantic/Canary',
'Europe/Madrid',
'Europe/Stockholm'
];
var dayjs_script = document.createElement('script');
var dayjs_tz_script = document.createElement('script');
dayjs_script.onload = function(e) {
document.head.appendChild(dayjs_tz_script);
}
dayjs_tz_script.onload = function () {
dayjs.extend(dayjs_plugin_timezone);
var tz = dayjs.tz.guess();
if(EU_TIMEZONES.includes(tz)) {
checkIfAcceptedCookies();
} else {
onAcceptedCookies();
}
};
dayjs_script.onerror = function() {
checkIfAcceptedCookies();
}
dayjs_tz_script.onerror = function() {
checkIfAcceptedCookies();
}
dayjs_tz_script.src = 'https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.6/plugin/timezone.min.js';
dayjs_script.src = 'https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.11.6/dayjs.min.js';
document.head.appendChild(dayjs_script);
}
Simply run determineIfCookieConsentRequired() to check if consent is required.
You then need to create two functions:
checkIfAcceptedCookies() which should check if the user has already consented or display a banner asking them to
onAcceptedCookies() to do whatever you want once cookies are consented (or if they're not required)

Steps to check if user is living in Europe/EU:
Obtain the object from the resolvedOptions function from the DateTimeFormat function from the Intl object
Set isInEu to a boolean if the timeZone property contains Europe
isInEu = Intl.DateTimeFormat().resolvedOptions().timeZone.indexOf("Europe") == 0
Yep, it's that simple! - Leonardo Da Tyrunt

Related

lucene query filter not working

I am using this filter hook in my Auth0 Delegated Administration Extension.
function(ctx, callback) {
// Get the company from the current user's metadata.
var company = ctx.request.user.app_metadata && ctx.request.user.app_metadata.company;
if (!company || !company.length) {
return callback(new Error('The current user is not part of any company.'));
}
// The GREEN company can see all users.
if (company === 'GREEN') {
return callback();
}
// Return the lucene query.
return callback(null, 'app_metadata.company:"' + company + '"');
}
When user logged in whose company is GREEN can see all users. But when user logged in whose company is RED can't see any users whose company is RED.
I need to make this when user logged in, user should only be able to access users within his company. (except users from GREEN company).
But above code is not giving expected result. What could be the issue?
This might be related to a little warning note on the User Search documentation page
Basically they don't let you search for properties in the app_metadata field anymore. Unfortunately, this change was breaking and unannounced.
We had to make changes to our API so that we keep a copy of the app_metadatas in a separate database and convert lucene syntax to MongoDB queries, so that we can query by a chain of user_id:"<>" OR user_id:"<>" OR ....
One caveat though, you can't pass a query that's longer than 72 user_ids long. This number is so far undocumented and obtained empirically.
Also, you can't rely on Auth0's hooks to add new users to your database, as these don't fire for social logins, only for Username-Password-Authentication connections.
I hope this gave you some explanation as for why it wasn't working as well as a possible solution.
If I were you, I would look for an alternative for Auth0, which is what we are currently doing.
I finally ended up with this solution.
Used search functionality to filter users. I had to change below two files.
fetchUsers function in client\actions\user.js
changed
export function fetchUsers(search = '', reset = false, page = 0)
to
export function fetchUsers(search = '#red.com', reset = false,
page = 0)
AND
onReset function in client\containers\Users\Users.jsx
changed
onReset = () => { this.props.fetchUsers('', true); }
to
onReset = () => { this.props.fetchUsers('#red.com', true); }

Protractor e2e testing suggestions about code complexity [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 6 years ago.
Improve this question
I know my question will get marked as to broad but I didn't think of another place to ask it.I work in QA and month ago i started learning protractor by myself so i can test our projects with protractor there was no one to guide me i learned all by myself and google so I wanted you guys to check the code i made and give me some suggestions. Does it look like it should,because i think its worthless it gets the job done but i feel it is still beginner level, and there is none to guide me so i know the level i am at the moment any suggestions are welcome.My config file pretty basic.
exports.config = {
framework: 'jasmine2',
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['page.js'],
onPrepare: function() {
var jasmineReporters = require('jasmine-reporters');
}
}
My specification file:
/*
##############################################
FUNCTIONS in helper_functons:
getsite();
logIn();
mainPageItem(); | 0 - Recipes | 1 - Collections | 2 - Profiles |
openRecipe(index);
createRecipe (name,description,step,numStep,ingName,numIngr,addToCollections,share);
deleteRecipe(recipeName); //must use getMainPageAndRefresh()
openRecipe(index);
browseRecipe();
openCollection(index);
createCollection(name,description);
openUser(index);
getNotifications();
goToProfile();
browseProfile();
getMainPageAndRefresh();
goToTimeline();
openLegal(index);
useSearch(textString);
createPost(postName);
logOut();
##############################################
*/
var functions = require('./helper_functions.js');
var uName = 'asd';
var pass = 'asd';
describe('Hooray',function(){
it('Gets site',function(){
functions.getSite();
});
it('Logs in ',function(){
functions.logIn(uName,pass);
});
it('Recipe options',function(){
browser.sleep(9000);
});
it('Logs out',function(){
functions.getMainPageAndRefresh();
functions.logOut();
});
});
And I am using another file where i created helper functions so my tests look more readable this is where the main code is http://pastebin.com/KgXCh74m I uploaded on pastebin because it is 500 lines. My idea was to call a function whenever you need it and test it in the page.js file.
By looking at your code, it seems you have put all your elements in a function and accessing them in your specs. In general this way of accessing elements would lead to some Flaky tests and you would not be able to run test scripts confidently and error free.
Protractor's community widely encourages the usage of Page Objects. Protractor has some good documentation,they have specifically mentioned style guide http://www.protractortest.org/#/style-guide to get started.
Some of the tips from my experience while writing protractor tests:
Avoid browser.sleep for page loads , instead use browser.manage().timeouts().pageLoadTimeout(10000);
Use Expected Conditions for interacting with web elements elementToBeClickable, elementToBeSelected etc.
Use Page Objects efficiently. Avoid accessing/performing actions on elements in page objects. It has to be done inside the specs i.e.
your page.js should look like this -
var somePage = function() {
this.username = element(by.id('someId')); //Here we are only defining the elements
this.password = element(by.id('someId'));
this.button = element(by.css('someCss'));
this.login = function(uid,pwd) { // If we are using functions in page objects, we would just access the defined elements above rather than defining them in the function (reusability & decoupling).
this.username.sendKeys(uid);
this.password.sendKeys(pwd);
this.button.click();
};
};
In the above page object if the username or password element changes you only have to change them, no need to touch the login function.
your spec.js should look like this -
var SomePage = require('path to your page.js');
describe('page', function() {
var page = new SomePage();
it('should test page', function() {
page.username.sendKeys('username'); // Here we are performing the action on the elements.
page.password.sendKeys('password');
page.login(username,password);
});
});
Maintaining test data in a separate JSON file.
Set browser.ignoreSynchronization = true while dealing with non-angular pages
Use CssSelectors as much as you can to identify elements.
Since Protractor is community driven --> Follow protractor on GitHub, StackOverflow & Gitter.
You would get all the updates/issues from these platforms so that you can solve your issues or ask for help, these awesome folks would help you!

Handle different markets (language / locale) in Angular 2 application using an Web Api

I could use some advice how I should handle different markets in my angular 2 application. By that I mean a new market (like the German market) where the language is in German, as an example. Right now, I have hardcoded the text inside the html (in english ofc) to make it easy for myself.
An example you see here:
<div class="row">
<h2>Booking number: {{bookingNumber}}</h2>
Your changes has been confirmed.
</div>
I have read something about pipes in angular 2, and i guess I should be using something like that. My problem is, that I really don't know where to start.
Already have an Web Api application created in Visual Studio 2015 which I can use and call.
I'm thinking of making two lists in my Web Api project (one for english, one for german), but there should still be some sort of indicator. By that I mean something like:
BOOKING_NUMBER_TEXT, 'the text in english or german'
CONFIRMATION_TEXT, 'the text...'
That list should have two params like, string string or something like that.. any idea how I could make this?
From my angular 2 application, I'm thinking of calling the api and given it an id (number, lets say 1 and 2, where 1 = english, 2 = germany)
My Web Api finds the correct list and sends it back as JSON.
Then I'm guessing of building a pipe my own where I can filter the words I set in the html. I'm thinking of something like:
<div class="row">
<h2>{{BOOKING_NUMBER_TEXT | 'PIPE NAME' }}: {{bookingNumber}}</h2>
{{CONFIRMATION_TEXT | 'PIPE NAME' }}.
</div>
So when it has name BOOKING_NUMBER_TEXT, it should look into the pipe which has the list object, and take out the text from the right one and place it instead.
Is that a good plan or can you maybe give any advice? (I'm don't want to use any translate angular 2 frameworks, because I have to do different things on each market)
Cheers :)
UPDATE
Ok.. I have created some test data and allowed it to be send via my Web Api. Here is how it looks.
public Dictionary<string, string> createEnglishLocaleKeys()
{
Dictionary<string, string> Locale_EN = new Dictionary<string, string>();
// Account Component
Locale_EN.Add("ACCOUNT_LOGIN_TEXT", "Login");
Locale_EN.Add("ACCOUNT_LOGOUT_TEXT", "Logout");
// Booking Component
Locale_EN.Add("BOOKING_ACTIVE_HEADER_TEXT", "ACTIVE BOOKINGS");
Locale_EN.Add("BOOKING_LOADING_TEXT", "Loading bookings");
Locale_EN.Add("BOOKING_NONACTIVE_HEADER_TEXT", "NON ACTIVE BOOKINGS");
Locale_EN.Add("BOOKING_NOPREBOOKING_TEXT", "You currently do not have any previous bookings");
// Booking List Component
Locale_EN.Add("BOOKING_LIST_BOOKINGNUMBER_TEXT", "Booking number");
Locale_EN.Add("BOOKING_LIST_LEAVING_TEXT", "Leaving");
Locale_EN.Add("BOOKING_LIST_RETURNING_TEXT", "Returning");
Locale_EN.Add("BOOKING_LIST_ROUTE_TEXT", "Route");
Locale_EN.Add("BOOKING_LIST_PASSENGERS_TEXT", "Passengers");
Locale_EN.Add("BOOKING_LIST_VEHICLETYPE_TEXT", "Vehicle type");
// Menu Component
// Passenger Component
// DepartureDate Component
// Confirmation Component
Locale_EN.Add("KEY_NOT_FOUND", "KEY NOT FOUND");
return Locale_EN;
}
Have created an LocaleController which takes a string locale "EN" or "DE" as parameter. Then I'm injecting a service for the controller, which will, based on the locale string choose which method to run (For now I'm only sending back the LocaleEN dictionary).
How can I create an value in my Angular 2 application which should be EN as default and should be changeable?
By changeable, you should be able to set it in the URL or some sort of, like:
localhost:3000/amendment?locale=DE
There are several things here:
You could HTTP content negotiation Conneg - See this link: http://restlet.com/blog/2015/12/10/understanding-http-content-negotiation/) and the Accept-Language to tell the server which messages to return.
You need to wait for messages to be there before displaying the screen with for example: <div ngIf="messages">…</div>
I don't think you need to implement a pipe to display messages if they are defined in a map (key / value): {{messages['SOME_KEY']}}
If messages correspond to list a custom filtering pipe can be implemented and used like that: {{messages | key:'SOME_KEY'}}
The implementation of this pipe could be:
#Pipe({name: 'key'})
export class KeyPipe implements PipeTransform {
transform(value, args:string[]) : any {
// Assuming the message structure is:
// { key: 'SOME_KEY', value: 'some message' }
return value.find((message) => {
return (message.key === args[0]);
});
}
}

Is there a way to implement some sort of auto translation in an react native app?

I know this isn't google, but I wasn't able to find anything usefull and maybe you can give me some advice.
What I am looking for is some way to add an auto translation to strings in my react native application.
Right now I am using a workaround in which I translate some of the most common words manually - since that doesn't cover the whole language the outcome looks pretty unsatisfying :)
You could use react-native-i18n.
var I18n = require('react-native-i18n');
var Demo = React.createClass({
render: function() {
return (
<Text>{I18n.t('greeting')}</Text>
)
}
});
// Enable fallbacks if you want `en-US` and `en-GB` to fallback to `en`
I18n.fallbacks = true;
I18n.translations = {
en: {
greeting: 'Hi!'
},
fr: {
greeting: 'Bonjour!'
}
}
take user phone OS language using device info
https://www.npmjs.com/package/react-native-device-info#getdevicelocale
or using
I18n = require('react-native-i18n')
locale = I18n.currentLocale()
then Use power translator
https://www.npmjs.com/package/react-native-power-translator
//set your device language as a Target_Language on app start
TranslatorConfiguration.setConfig('Provider_Type', 'Your_API_Key','Target_Language', 'Source_Language');
//Fill with your own details
TranslatorConfiguration.setConfig(ProviderTypes.Google, 'xxxx','fr');
Use it as a component
<PowerTranslator text={'Engineering physics or engineering science refers to the study of the combined disciplines of physics'} />
add-on :
Use redux store or async storage to store all your string on first app start.
Then use translated text from store or storage.
IT will save your api bill as you have fixed strings.
sir for auto-translate. you can create one component where you can pass all strings (text) in your app, And use '#aws-sdk/client-translate' for translation, it's very fast and also works on dynamic data \
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-translate/index.html
https://www.npmjs.com/package/#aws-sdk/client-translate

How do I get data from a background page to the content script in google chrome extensions

I've been trying to send data from my background page to a content script in my chrome extension. i can't seem to get it to work. I've read a few posts online but they're not really clear and seem quite high level. I've got managed to get the oauth working using the Oauth contacts example on the Chrome samples. The authentication works, i can get the data and display it in an html page by opening a new tab.
I want to send this data to a content script.
i'm having a lot of trouble with this and would really appreciate if someone could outline the explicit steps you need to follow to send data from a bg page to a content script or even better some code. Any takers?
the code for my background page is below (i've excluded the oauth paramaeters and other )
` function onContacts(text, xhr) {
contacts = [];
var data = JSON.parse(text);
var realdata = data.contacts;
for (var i = 0, person; person = realdata.person[i]; i++) {
var contact = {
'name' : person['name'],
'emails' : person['email']
};
contacts.push(contact); //this array "contacts" is read by the
contacts.html page when opened in a new tab
}
chrome.tabs.create({ 'url' : 'contacts.html'}); sending data to new tab
//chrome.tabs.executeScript(null,{file: "contentscript.js"});
may be this may work?
};
function getContacts() {
oauth.authorize(function() {
console.log("on authorize");
setIcon();
var url = "http://mydataurl/";
oauth.sendSignedRequest(url, onContacts);
});
};
chrome.browserAction.onClicked.addListener(getContacts);`
As i'm not quite sure how to get the data into the content script i wont bother posting the multiple versions of my failed content scripts. if I could just get a sample on how to request the "contacts" array from my content script, and how to send the data from the bg page, that would be great!
You have two options getting the data into the content script:
Using Tab API:
http://code.google.com/chrome/extensions/tabs.html#method-executeScript
Using Messaging:
http://code.google.com/chrome/extensions/messaging.html
Using Tab API
I usually use this approach when my extension will just be used once in a while, for example, setting the image as my desktop wallpaper. People don't set a wallpaper every second, or every minute. They usually do it once a week or even day. So I just inject a content script to that page. It is pretty easy to do so, you can either do it by file or code as explained in the documentation:
chrome.tabs.executeScript(tab.id, {file: 'inject_this.js'}, function() {
console.log('Successfully injected script into the page');
});
Using Messaging
If you are constantly need information from your websites, it would be better to use messaging. There are two types of messaging, Long-lived and Single-requests. Your content script (that you define in the manifest) can listen for extension requests:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'ping')
sendResponse({ data: 'pong' });
else
sendResponse({});
});
And your background page could send a message to that content script through messaging. As shown below, it will get the currently selected tab and send a request to that page.
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendRequest(tab.id, {method: 'ping'}, function(response) {
console.log(response.data);
});
});
Depends on your extension which method to use. I have used both. For an extension that will be used like every second, every time, I use Messaging (Long-Lived). For an extension that will not be used every time, then you don't need the content script in every single page, you can just use the Tab API executeScript because it will just inject a content script whenever you need to.
Hope that helps! Do a search on Stackoverflow, there are many answers to content scripts and background pages.
To follow on Mohamed's point.
If you want to pass data from the background script to the content script at initialisation, you can generate another simple script that contains only JSON and execute it beforehand.
Is that what you are looking for?
Otherwise, you will need to use the message passing interface
In the background page:
// Subscribe to onVisited event, so that injectSite() is called once at every pageload.
chrome.history.onVisited.addListener(injectSite);
function injectSite(data) {
// get custom configuration for this URL in the background page.
var site_conf = getSiteConfiguration(data.url);
if (site_conf)
{
chrome.tabs.executeScript({ code: 'PARAMS = ' + JSON.stringify(site_conf) + ';' });
chrome.tabs.executeScript({ file: 'site_injection.js' });
}
}
In the content script page (site_injection.js)
// read config directly from background
console.log(PARAM.whatever);
I thought I'd update this answer for current and future readers.
According to the Chrome API, chrome.extension.onRequest is "[d]eprecated since Chrome 33. Please use runtime.onMessage."
See this tutorial from the Chrome API for code examples on the messaging API.
Also, there are similar (newer) SO posts, such as this one, which are more relevant for the time being.