Does Safari's "Storage Access API" only work with iframes? - cookies

I am trying to use the Storage Access API in plain old JavaScript inside of a modal. I am not using an iframe. All of the docs that I see online for the Storage Access API reference iframes. Does this mean the technology only works with iframes or can I use it in a regular javascript file?
I've tried attaching it to an onclick event in html and also creating it programatically with javascript, but neither of these seem to be working. I cannot get the "Do you want to allow 'video.example' to use cookies and website data while browsing 'news.example.com'" to show.
<button onlick="showSafariMessage()" type="button">Show Safari Message</div>
<script>
var showSafariMessage = function () {
document.hasStorageAccess().then(hasAccess => {
if (!hasAccess) {
return document.requestStorageAccess();
}
}).then((result) => {
// Now we have first-party storage access!
// Let's access some items from the first-party cookie jar
document.cookie = "foo=bar"; // set a cookie
localStorage.setItem("username", "John"); // access a localStorage entry
}).catch((error) => {
// error obtaining storage access.
});
}
</script>
I expect to see the Safari popup, but I am not. Please help!

Related

Algorand WalletConnect connection not showing metadata on Pera Wallet

I'm trying to get a working connection between a NextJS application and my Algorand wallet (Pera) using WalletConnect. I am able to connect, but the NextJS application won't send any metadata like dApp name. Is there something wrong with my code?
import WalletConnect from "#walletconnect/client";
import QRCodeModal from "algorand-walletconnect-qrcode-modal";
export default function Index(props) {
// Create a connector
const connector = new WalletConnect({
bridge: "https://bridge.walletconnect.org", // Required
qrcodeModal: QRCodeModal,
clientMeta: {
description: "WalletConnect NodeJS Client",
url: "https://nodejs.org/en/",
icons: ["https://nodejs.org/static/images/logo.svg"],
name: "WalletConnect"
}
});
// Create a function to connect
let connectWallet = () => {
if (!connector.connected) {
connector.createSession()
}
// ... Event subscriptions down here ...
}
And I call the connectWallet function from a simple onClick
return (
<div>
{/* Add button to call connectWallet */}
<button onClick={() => connectWallet()}>Connect Wallet</button>
</div>
);
From what I understand, it should show the clientMeta data I send to the connector, but it just shows empty strings and no image on the Pera wallet app.
The WalletConnect documentation for Pera Wallet does not seem to indicate support of clientMeta unfortunately.
See https://github.com/algorandfoundation/ARCs/blob/main/ARCs/arc-0025.md and https://developer.algorand.org/docs/get-details/walletconnect/
However, it should still display the right URL.
You can compare what you see with https://algorand.github.io/walletconnect-example-dapp/ (that displays the URL https://algorand.github.io)
Small note: in general, you may get faster answers by posting Algorand-related questions on https://forum.algorand.org

Reading cookies or sending info to Google Tag Manager

What is the correct way to send data to my Google Tag Manager?
I got a cookie notice that gives the user the opportunity to accept certain cookies (performance, marketing and analytics). So far I got this script to read the user' choice:
...
if (e.detail.performance) {
setCookie('cookie_performance', e.detail.performance, 365);
}
if (e.detail.analytics) {
setCookie('cookie_analytics', e.detail.analytics, 365);
}
if (e.detail.marketing) {
setCookie('cookie_marketing', e.detail.marketing, 365);
}
...
However, this only sets a cookie in the user' browser. I like to know inside my Google Tag Manager container if the user accepted the cookie.
I have read stuff about using the dataLayer, but I am stuck on configuring the triggers or tags inside my container.
Is it possible to send an event to my container whenever the user accepts a certain cookie?
Sure. If you go to the variables section and click "new" one choice for the variable type you have is "First Part Cookie".
As an aside, if the "365" in your code refers to the lifetime of your cookie in days (I assume it does, since 365 days is a year), be aware that on Safari and iOs Cookie lifetime will be limited to seven days due to the new version of their "Intelligent Tracking Prevention".
While using cookies works fine for GTM, the datalayer usually is best practice (cookies come with a few caveats - the browser may not allow them, their size is limited, their number per domain is limited etc).
As mentioned before there are inbuilt cookie variables for use within GTM, this way you can reference these in an if statement by using {{cookieVar_Name}} within GTM code.
However to answer your question about clueing in GTM about those cookies one way is to probably send along a dataLayer.push event with the necessary data.
For example you could adapt your current code to push an event when those cookies are set:
...
if (e.detail.performance) {
setCookie('cookie_performance', e.detail.performance, 365);
window.dataLayer.push({
event: 'performanceEvent',
cookie_performance: true
});
}
if (e.detail.analytics) {
setCookie('cookie_analytics', e.detail.analytics, 365);
window.dataLayer.push({
event: 'analyticsEvent',
cookie_analytics: true
});
}
if (e.detail.marketing) {
setCookie('cookie_marketing', e.detail.marketing, 365);
window.dataLayer.push({
event: 'marketingEvent',
cookie_marketing: true
});
}
...
At this point you could create a custom event trigger named to say, marketingEvent, you could then use this trigger to fire a tag when that dataLayer.push is actioned/is consented to.
In regards to reading the cookies of returning customers, you could either use a customHTML tag with a cookie reading function:
//This function can be used to retrieve a cookie and its value by its key(name)
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
getCookie(cookie_marketing);
Or store the cookie value in an inbuilt GTM cookie variable and write an if statement:
if({{cookie_marketing}} == true){
// fire code here
}
Hope this helps get you on the right track.

Headless Chrome Puppeteer Skip Logging In To Twitter Using Cookies?

Is it possible to skip logging in to twitter by setting cookies?
I tried to copy an paste what I got from "document.cookie" in web console but that gave me the error Invalid parameters name: string value expected
await page.setCookie({
personalization_id: "v1_VDBAhQo+RMCSceKUBXfs3w==",
guest_id: "v1%3A150575165219105300",
ct0: "d9343a3b062832b6ec23a84747e518b3",
_gat: "1m",
ads_prefs: "HBERAAA=",
remember_checked_on: 1,
twid: "u=908918507005456384",
lang: "en",
tip_nightmode: true,
_ga: "GA1.2.1275876041.1505751657",
_gid: "GA1.2.1311587009.1505751657"
})
The correct syntax for setCookie is not what you used, it's:
setCookie(cookie1, cookie2, ...)
where cookie is an object containing name and value keys, like
setCookie({name: 'lang', value: 'en'})
Remember to set the cookies before loading Twitter, or to reload the page after setting them, and everything should work.
async function addCookies(cookies_str, page, domain){
let cookies = cookies_str.split(';').map(pair=>{
let name = pair.trim().slice(0,pair.trim().indexOf('='))
let value = pair.trim().slice(pair.trim().indexOf('=')+1)
return {name,value,domain}
});
await Promise.all(cookies.map((pair)=>{
return page.setCookie(pair);
}))
}
this is my way to add cookies, cookies_str was copied from browser;

How to login into a third-party website using google app script and manage data on login?

I am interested in creating a google app script that on run would login into a specific website (third-party) and complete certain functions within the website (pressing buttons/copying text).
After browsing the stackoverflow and other forums I have created a script that allows me to login into my website (source1 source2).
However, I am having difficulties staying logged in and managing the data.
//The current code is just testing if I can get data from within the website.
//The results are displayed in a google app.
function doGet() {
var app = UiApp.createApplication();
app.add(app.createLabel(display_basic_data()));
return app;
}
//logins into website and displays data
function display_basic_data() {
var data;
var url = "http://www.website.bla/users/sign_in";
var payload = {"user[username]":"usr","user[password]":"ps"};
var opt ={"method":"post","payload":payload, "followRedirects" : false};
var response = UrlFetchApp.fetch(url,opt);
data = response;
return data;
}
Currently, the data returned from display_basic_data() is
"<html><body>You are being redirected.</body></html>".
If I try to change my script so that "followRedirects" is true, the data is equivalent to the HTML of the login page.
I understand I have to play around with cookies in order to 'stay' logged in but I have no idea what to do as the examples online provided to be fruitless for me.
Any help would be much appreciated!!!
You may want to do something like this:
var cookie = response.getAllHeaders()['Set-Cookie'];
//maybe parse cookies here, depends on what cookie is
var headers = {'Cookie':cookie};
var opt2 = {"headers":headers};
var pagedata = UrlFetchApp.fetch("http://www.website.bla/home",opt2);

having trouble sending facebook notification via ajax call to php

In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.