Skip to content

Commit

Permalink
Merge branch 'main' into feature/recaptcha-google
Browse files Browse the repository at this point in the history
# Conflicts:
#	app.js
#	src/common/index.ejs
  • Loading branch information
gagan0123 committed Apr 18, 2024
2 parents 0510eba + df3d90b commit ff718ce
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 111 deletions.
5 changes: 3 additions & 2 deletions app.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ const scenarios = [
'personalization',
'personalization-localstorage',
'gsi',
'social-media',
'social-media-comments',
'facebook-like',
'facebook-comments',
'disqus-comments',
'spotify-embed',
'google-recaptcha',
];
scenarios.forEach(scenario => {
Expand Down
7 changes: 4 additions & 3 deletions src/common/index.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@
<%= renderCard('Single Sign-On', '🔐', '/single-sign-on') %>
<%= renderCard('Payment Gateway', '💳', '/payment-gateway') %>
<%= renderCard('Legacy GSI', '🔐', '/gsi') %>
<%= renderCard('Facebook Like', '👍', '/social-media') %>
<%= renderCard('Facebook Comments', '💬', '/social-media-comments') %>
<%= renderCard('Facebook Like', '👍', '/facebook-like') %>
<%= renderCard('Facebook Comments', '💬', '/facebook-comments') %>
<%= renderCard('Disqus Comments', '✉️', '/disqus-comments') %>
<%= renderCard('reCAPTCHA', '🤖', '/google-recaptcha') %>
<%= renderCard('Spotify embed', '🔊', '/spotify-embed') %>
<%= renderCard('CHIPS', '🍪', '/chips') %>
<%= renderCard('Storage Access API', '🗃️', '/storage-access-api') %>
</div>
</div>

<%- include(commonPath + '/footer.ejs') %>
<%- include(commonPath + '/footer.ejs') %>
3 changes: 1 addition & 2 deletions src/demos/chips/analytics-first-party.ejs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
<%- include(commonPath + '/header.ejs') %>

<%- include(commonPath + '/internal-page/header.ejs') %>
<p class="text-center">Track user interactions using the analytics code provided below:</p>
<div class="flex justify-center space-x-4 mt-4">
<button onclick="trackInteraction('buttonClicked')" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300">
Track me!
</button>
<button onclick="trackInteraction('buttonClickedCHIPS')" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300">
CHIPS Track me!
Track me! (CHIPS)
</button>
</div>
<div id="status" class="text-center mt-4"></div>
Expand Down
4 changes: 1 addition & 3 deletions src/demos/chips/analytics-third-party.ejs
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
<%- include(commonPath + '/header.ejs') %>

<%- include(commonPath + '/internal-page/header.ejs') %>
<p class="text-center">Track user interactions using the analytics code provided below:</p>

<div class="flex justify-center space-x-4 mt-4">
<button onclick="trackInteraction('buttonClicked')" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300">
Track me!
</button>
<button onclick="trackInteraction('buttonClickedCHIPS')" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300">
CHIPS Track me!
Track me! (CHIPS)
</button>
</div>
<div id="status" class="text-center mt-4"></div>
Expand Down
2 changes: 1 addition & 1 deletion src/demos/chips/analytics.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
} ).then( function ( data ) {
var statusDiv = document.getElementById( 'status' );
if ( statusDiv ) {
statusDiv.textContent = 'Interaction tracked for ID : ' + data;
statusDiv.textContent = 'Interaction tracked!';
statusDiv.style.color = 'green';
}
} ).catch( function ( error ) {
Expand Down
20 changes: 8 additions & 12 deletions src/demos/chips/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,15 @@ const uuid = require( 'uuid' );

router.get('/', (req, res) => {
// Send the default page
res.render(path.join(__dirname,'index'), {
res.render(path.join(__dirname,'analytics-third-party'), {
title: 'CHIPS'
});
});
router.get('/analytics-first-party', (req, res) => {
res.render(path.join(__dirname,'analytics-first-party'), {
title: 'First Party Cookie Experiments'
});
});

router.get('/analytics-third-party', (req, res) => {
// Send the default page
res.render(path.join(__dirname,'analytics-third-party'), {
title: 'Third Party Cookie Experiments'
title: 'CHIPS'
});
});
// Serve the analytics.js file to the site
Expand All @@ -39,16 +35,16 @@ router.get( '/analytics.js', ( req, res ) => {

}

let analyticsIdCHIPS = req.cookies['__Host-analyticsId-chips'];
let analyticsIdCHIPS = req.cookies['analyticsId-chips'];

if ( !analyticsIdCHIPS ) {
analyticsIdCHIPS = uuid.v4();
let expire = 30 * 24 * 60 * 60 * 1000;
res.append(
/*res.append(
'Set-Cookie', '__Host-analyticsId-chips=' + analyticsIdCHIPS + '; Max-Age=' + expire + '; HttpOnly; Secure; Path=/; SameSite=None; Partitioned;'
);
);*/
res.append(
'Set-Cookie', 'analyticsId-chips-test=' + analyticsIdCHIPS + ';Domain='+res.locals.domainC+'; Max-Age=' + expire + '; HttpOnly; Secure; Path=/; SameSite=None; Partitioned;'
'Set-Cookie', 'analyticsId-chips=' + analyticsIdCHIPS + ';Domain='+res.locals.domainC+'; Max-Age=' + expire + '; HttpOnly; Secure; Path=/; SameSite=None; Partitioned;'
);
}

Expand All @@ -73,7 +69,7 @@ router.post( '/track', ( req, res ) => {

router.post( '/trackCHIPS', ( req, res ) => {
const {interaction} = req.body;
const analyticsIdCHIPS = req.cookies['__Host-analyticsId-chips'];
const analyticsIdCHIPS = req.cookies['analyticsId-chips'];

if ( interaction && analyticsIdCHIPS ) {

Expand Down
202 changes: 116 additions & 86 deletions src/demos/storage-access-api/personalization.ejs
Original file line number Diff line number Diff line change
@@ -1,96 +1,126 @@
document.addEventListener('DOMContentLoaded', () => {
const baseURL = '<%= protocol %>://<%= domainC %><% if (isPortPresent) { %>:<%= port %><% } %>/personalization';
const pageContainer = document.getElementById('theme-container');
const themeSwitcher = document.getElementById('dark-mode-switch');
const errorMessages = document.getElementById('status-message');
const loadButton = document.getElementById('load-button');
const toggleContainer = document.querySelector('.dark-mode-toggle');
const isIframe = window.self !== window.top;
const containerClass = isIframe ? 'h-screen flex items-center justify-center' : 'flex items-center justify-center';
let hasStorageAccess = false;

document.hasStorageAccess().then(result => {
hasStorageAccess = result;
if ( hasStorageAccess ) {
updateUserPreference();
}
})

async function updateUserPreference() {
if ( hasStorageAccess ) {
fetchAndApplyTheme();
} else {
try {
await document.requestStorageAccess();
toggleContainer.classList.remove('hidden');
loadButton.classList.add('hidden');
fetchAndApplyTheme();
} catch (error) {
errorMessages.textContent = error?.message;
}
}
(() => {
let baseURL,
pageContainer,
themeSwitcher,
errorMessages,
loadButton,
toggleContainer,
isIframe,
containerClass,
hasStorageAccess;

async function fetchAndApplyTheme() {
try {
const response = await fetch(`${baseURL}/get-personalization`, {
method: 'GET',
credentials: 'include',
});

if (!response.ok) {
throw new Error('Network response was not ok');
errorMessages.textContent = `Network response was not ok ${response.status} - ${response.statusText}`;
}

const data = await response.json();
pageContainer.className = `${containerClass} ${data.theme}`;
if (data.theme === 'dark') {
themeSwitcher.checked = true;
}
} catch (error) {
errorMessages.textContent = error?.message;
}
}

async function updateUserPreference() {
errorMessages.textContent = '';
if (hasStorageAccess) {
fetchAndApplyTheme();
return;
}

try {
await document.requestStorageAccess();
hasStorageAccess = await document.hasStorageAccess();

if (!hasStorageAccess) {
errorMessages.textContent = 'User denied storage access';
return;
}

toggleContainer.classList.remove('hidden');
loadButton.classList.add('hidden');

fetchAndApplyTheme();
} catch (error) {
errorMessages.textContent = error?.message;
}
}

async function fetchSetPersonalization() {
try {
const response = await fetch(`${baseURL}/set-personalization`, {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
theme: themeSwitcher?.checked ? 'dark' : 'light',
}),
});
const data = await response.json();

function fetchAndApplyTheme() {
fetch(`${baseURL}/get-personalization`, {
method: 'GET',
credentials: 'include'
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
errorMessages.textContent = `Network response was not ok ${response.status} - ${response.statusText}`;
}
return response.json();
})
.then(data => {
const theme = data.theme;
pageContainer.className = `${containerClass} ${data.theme}`
if (theme === 'dark') {
themeSwitcher.checked = true;
}
})
.catch(error => {
errorMessages.textContent = error?.message;
});
pageContainer.className = `${containerClass} ${data.theme}`;
} catch (error) {
errorMessages.textContent = error?.message;
}
}

async function toggleTheme() {
errorMessages.textContent = '';

function fetchSetPersonalization() {
fetch( `${baseURL}/set-personalization`, {
method: 'POST',
credentials: 'include',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ theme: themeSwitcher?.checked ? 'dark' : 'light' })
})
.then(response => response.json())
.then(data => {
pageContainer.className = `${containerClass} ${data.theme}`;
});
if (hasStorageAccess) {
fetchSetPersonalization();
return;
}

async function toggleTheme() {
hasStorageAccess = await document.hasStorageAccess();

if( hasStorageAccess ) {
fetchSetPersonalization();
} else {
try {
await document.requestStorageAccess();
if ( await document.hasStorageAccess() ) {
fetchSetPersonalization();
} else {
errorMessages.textContent = 'User denied storage access';
}
} catch (error) {
errorMessages.textContent = `The request to storage access API was denied because the user never interacted with the top-level site context or the permission wasn't grant by the user`;
}
}
try {
await document.requestStorageAccess();
hasStorageAccess = await document.hasStorageAccess();

if (!hasStorageAccess) {
errorMessages.textContent = 'User denied storage access';
return;
}

fetchSetPersonalization();
} catch (error) {
errorMessages.textContent = error?.message;
}

}

// Main start point
document.addEventListener('DOMContentLoaded', async () => {
baseURL =
'<%= protocol %>://<%= domainC %><% if (isPortPresent) { %>:<%= port %><% } %>/personalization';
pageContainer = document.getElementById('theme-container');
themeSwitcher = document.getElementById('dark-mode-switch');
errorMessages = document.getElementById('status-message');
loadButton = document.getElementById('load-button');
toggleContainer = document.querySelector('.dark-mode-toggle');
isIframe = window.self !== window.top;
containerClass = isIframe
? 'h-screen flex items-center justify-center'
: 'flex items-center justify-center';
let hasStorageAccess = await document.hasStorageAccess();

if (hasStorageAccess) {
updateUserPreference();
}

window.toggleTheme = toggleTheme;
if (isIframe && !hasStorageAccess) {
toggleContainer.classList.add('hidden');
loadButton.classList.remove('hidden');
loadButton.addEventListener('click', updateUserPreference);
toggleContainer.classList.add('hidden');
loadButton.classList.remove('hidden');
loadButton.addEventListener('click', updateUserPreference);
}
});
});
})();
2 changes: 1 addition & 1 deletion src/demos/storage-access-api/theme-selection.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<div id="theme-container" class="flex items-center justify-center">
<%- include(commonPath + '/internal-page/header.ejs', {containerType: 'sm'}) %>
<div class="text-red-500 p-4 text-sm" id="status-message"></div>
<button id="load-button" class="hidden px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300" onclick="toggleTheme()">
<button id="load-button" class="hidden px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300">
Load user preferences
</button>
<div class="dark-mode-toggle">
Expand Down
1 change: 0 additions & 1 deletion src/scenarios/analytics/index.ejs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<%- include(commonPath + '/header.ejs') %>

<%- include(commonPath + '/internal-page/header.ejs') %>
<p class="text-lg mb-4 text-center">Here is a button that tracks clicks using a third-party analytics service; check if it works.</p>

<div class="flex justify-center space-x-4 my-10">
<button onclick="trackInteraction('buttonClicked')" class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-700 transition duration-300">
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 6 additions & 0 deletions src/scenarios/spotify-embed/index.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%- include(commonPath + '/header.ejs') %>

<%- include(commonPath + '/internal-page/header.ejs', {containerType: 'sm'}) %>
<iframe style="border-radius:12px" src="https://open.spotify.com/embed/episode/7makk4oTQel546B0PZlDM5?utm_source=generator" width="100%" height="352" frameBorder="0" allowfullscreen="" allow="autoplay; clipboard-write; encrypted-media; fullscreen; picture-in-picture" loading="lazy"></iframe>
<%- include(commonPath + '/internal-page/footer.ejs') %>
<%- include(commonPath + '/footer.ejs') %>
13 changes: 13 additions & 0 deletions src/scenarios/spotify-embed/routes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const express = require('express');
const path = require('path');
const router = express.Router();

router.get('/', (req, res) => {
// Send the default page
const currentDomain = req.get('host');
res.render(path.join(__dirname,'index'), {
title: 'Spotify Player'
});
});

module.exports = router;

0 comments on commit ff718ce

Please sign in to comment.