Added privacy law compliance mechanism.

This commit is contained in:
Stefan Bohacek 2024-07-29 08:22:37 -04:00
parent 6f487f7858
commit 1b1464ff40
No known key found for this signature in database
GPG key ID: FC75CD588A42BC10
4 changed files with 29 additions and 9 deletions

View file

@ -68,11 +68,26 @@ My sharing button [detects the software](https://github.com/stefanbohacek/fedive
Threads are *technically* supported, but they don't currently provide software information, so the URL won't be recognized.
### Q: Does this button or the fediverse-info server collect any information?
### Q: Does this widget or the fediverse-info server collect any information? Does it comply with data privacy laws? (eg GDPR)
None at all. The [fediverse-info](https://github.com/stefanbohacek/fediverse-info) server is only needed to cache the software information for each domain as not to overwhelm the original server with too many requests.
The sharing widget uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to store two pieces of information:
The last domain used in the domain input field and the fediverse software it's running are both stored in the [site visitor's browser](https://en.wikipedia.org/wiki/Web_storage) so that when they view another page, or visit the site again later, this information can be reused.
- `fsb-domain`: used to store the last **domain name** used in the sharing widget (eg. "mastodon.social", "pixelfed.social", etc)
- `fsb-software`: used to store the **software** used by the selected fediverse server (eg. "mastodon", "pixelfed")
When stored, this information is used to prefill the widget form upon next visit.
To prevent this information from being stored, you can set the value of `fsb-consent-given` to `"false"` before loading the main JavaScript file.
```html
<script>
localStorage.setItem("fsb-consent-given", "false");
</script>
```
Using any other value, or the lack of presence of it, will be interpreted as a consent to store and retrieve the information detailed above. Please consult any applicable laws to determine whether consent is required for this functionality.
The [fediverse-info](https://github.com/stefanbohacek/fediverse-info) server is only needed to cache the software information for each domain as not to overwhelm the original server with too many requests. This information is not tied specifically to your site's visitor.
### Q: Are there any similar projects?

View file

@ -1,4 +1,8 @@
(async () => {
// Privacy law compliance.
const canUseLocalStorage = localStorage.getItem("fsb-consent-given") !== "false" ? true : false;
// List of suported fediverse software.
const knownSoftware = [
@ -111,7 +115,7 @@
el.dataset.software = software;
if (software) {
if (software && canUseLocalStorage) {
localStorage.setItem("fsb-software", software);
}
@ -173,8 +177,8 @@
let typingTimer;
const doneTypingInterval = 1300;
const savedDomain = localStorage.getItem("fsb-domain");
const savedSoftware = localStorage.getItem("fsb-software");
const savedDomain = canUseLocalStorage ? localStorage.getItem("fsb-domain") : false;
const savedSoftware = canUseLocalStorage ? localStorage.getItem("fsb-software") : false;
[...document.getElementsByClassName("fsb-prompt")].forEach((fsbPrompt) => {
const domainInput = fsbPrompt.getElementsByClassName("fsb-domain")[0];
@ -209,7 +213,9 @@
if (domain?.length) {
const shareText = getSelectedText() || getPageTitle();
localStorage.setItem("fsb-domain", domain);
if (canUseLocalStorage){
localStorage.setItem("fsb-domain", domain);
}
let shareURL = `https://${domain}/share?text=${
// getPageTitle() + " " + getPageURL()

View file

@ -1 +1 @@
(async()=>{const knownSoftware=["calckey","diaspora","ecko","firefish","friendica","glitch-soc","gnu_social","gotosocial","groundpolis","hometown","hubzilla","kepi","lemmy","mastodon","misskey","misty","osada","peertube","pixelfed","pleroma","sharkey","socialhome","threads","wordpress","xmpp","zap"];const supportedSoftware=["diaspora","firefish","friendica","glitch-soc","hometown","hubzilla","lemmy","mastodon","misskey","sharkey","threads"];const getFSBPath=()=>{var scripts=document.getElementsByClassName("fsb-script")[0];src=scripts.src;return src.replace("/script.min.js","")};const updateTheIcon=(iconElement,software)=>{const domainInput=iconElement.parentElement.parentElement.parentElement.getElementsByClassName("fsb-domain")[0];const supportNote=iconElement.parentElement.parentElement.parentElement.getElementsByClassName("fsb-support-note")[0];const supportNoteLink=iconElement.parentElement.parentElement.parentElement.getElementsByClassName("fsb-support-note-link")[0];iconElement.src=`${getFSBPath()}/icons/${software}.svg`;iconElement.alt=`${software} platform logo`;supportNote.classList.add("fsb-d-none");if(domainInput.value&&domainInput.value.trim().length>0&&!supportedSoftware.includes(software)){supportNoteLink.href=`https://${domainInput.value}`;supportNoteLink.innerHTML=domainInput.value;supportNote.classList.remove("fsb-d-none")}};const updateIcon=async domainInput=>{clearTimeout(typingTimer);if(domainInput.value){typingTimer=setTimeout((()=>{doneTyping(domainInput)}),doneTypingInterval)}else{const iconEl=domainInput.parentElement.getElementsByClassName("fsb-icon")[0];updateTheIcon(iconEl,"mastodon")}};const doneTyping=async el=>{const shareBtn=el.parentElement.getElementsByClassName("fsb-button")[0];const domain=getDomain(el.value);shareBtn.disabled=true;const resp=await fetch(`https://fediverse-info.stefanbohacek.dev/node-info?domain=${domain}`);const respJSON=await resp.json();const software=respJSON?.software?.name;const iconEl=el.parentElement.getElementsByClassName("fsb-icon")[0];el.dataset.software=software;if(software){localStorage.setItem("fsb-software",software)}if(software&&knownSoftware.includes(software)){updateTheIcon(iconEl,software)}else{updateTheIcon(iconEl,"question")}shareBtn.disabled=false};const getPageTitle=()=>{let pageTitle=document.title;try{pageTitle=document.querySelector("meta[property='og:title']").getAttribute("content")}catch(error){}return encodeURIComponent(pageTitle)};const getPageDescription=()=>{let pageDescription="";const metaDescription=document.querySelector("meta[name='description']")||document.querySelector("meta[property='og:description']")||null;if(metaDescription&&metaDescription.getAttribute){pageDescription=metaDescription.getAttribute("content")}return encodeURIComponent(pageDescription)};const getPageURL=()=>encodeURIComponent(window.location.href);const getDomain=str=>str.replace(/(^\w+:|^)\/\//,"");const truncate=input=>input.length>5?`${input.substring(0,450)}...`:input;const getSelectedText=()=>{let text="";if(window.getSelection){text=window.getSelection().toString()}else if(document.selection&&document.selection.type!="Control"){text=document.selection.createRange().text}return truncate(text)};let typingTimer;const doneTypingInterval=1300;const savedDomain=localStorage.getItem("fsb-domain");const savedSoftware=localStorage.getItem("fsb-software");[...document.getElementsByClassName("fsb-prompt")].forEach((fsbPrompt=>{const domainInput=fsbPrompt.getElementsByClassName("fsb-domain")[0];const shareBtn=fsbPrompt.getElementsByClassName("fsb-button")[0];if(savedDomain){domainInput.value=savedDomain;if(savedSoftware){domainInput.dataset.software=savedSoftware;const iconEl=domainInput.parentElement.getElementsByClassName("fsb-icon")[0];updateTheIcon(iconEl,savedSoftware)}else{updateIcon(domainInput)}}domainInput.addEventListener("input",(()=>{updateIcon(domainInput)}));domainInput.addEventListener("change",(()=>{}));fsbPrompt.addEventListener("submit",(ev=>{ev.preventDefault();const domain=getDomain(domainInput?.value?.trim());if(domain?.length){const shareText=getSelectedText()||getPageTitle();localStorage.setItem("fsb-domain",domain);let shareURL=`https://${domain}/share?text=${shareText+"%0A%0A"+getPageURL()}`;if(domainInput?.dataset?.software){if(["diaspora","friendica"].includes(domainInput.dataset.software)){shareURL=`https://${domain}/bookmarklet?url=${getPageURL()}&title=${shareText}&note=${getPageDescription()}`}else if(domainInput.dataset.software==="hubzilla"){shareURL=`https://${domain}/rpost?url=${getPageURL()}&body=${shareText}[br][br]`}else if(domainInput.dataset.software==="threads"){shareURL=`https://${domain}/intent/post?text=${shareText+"%0A%0A"+getPageURL()}`}}window.location.assign(shareURL)}}))}))})();
(async()=>{const canUseLocalStorage=localStorage.getItem("fsb-consent-given")!=="false"?true:false;const knownSoftware=["calckey","diaspora","ecko","firefish","friendica","glitch-soc","gnu_social","gotosocial","groundpolis","hometown","hubzilla","kepi","lemmy","mastodon","misskey","misty","osada","peertube","pixelfed","pleroma","sharkey","socialhome","threads","wordpress","xmpp","zap"];const supportedSoftware=["diaspora","firefish","friendica","glitch-soc","hometown","hubzilla","lemmy","mastodon","misskey","sharkey","threads"];const getFSBPath=()=>{var scripts=document.getElementsByClassName("fsb-script")[0];src=scripts.src;return src.replace("/script.min.js","")};const updateTheIcon=(iconElement,software)=>{const domainInput=iconElement.parentElement.parentElement.parentElement.getElementsByClassName("fsb-domain")[0];const supportNote=iconElement.parentElement.parentElement.parentElement.getElementsByClassName("fsb-support-note")[0];const supportNoteLink=iconElement.parentElement.parentElement.parentElement.getElementsByClassName("fsb-support-note-link")[0];iconElement.src=`${getFSBPath()}/icons/${software}.svg`;iconElement.alt=`${software} platform logo`;supportNote.classList.add("fsb-d-none");if(domainInput.value&&domainInput.value.trim().length>0&&!supportedSoftware.includes(software)){supportNoteLink.href=`https://${domainInput.value}`;supportNoteLink.innerHTML=domainInput.value;supportNote.classList.remove("fsb-d-none")}};const updateIcon=async domainInput=>{clearTimeout(typingTimer);if(domainInput.value){typingTimer=setTimeout((()=>{doneTyping(domainInput)}),doneTypingInterval)}else{const iconEl=domainInput.parentElement.getElementsByClassName("fsb-icon")[0];updateTheIcon(iconEl,"mastodon")}};const doneTyping=async el=>{const shareBtn=el.parentElement.getElementsByClassName("fsb-button")[0];const domain=getDomain(el.value);shareBtn.disabled=true;const resp=await fetch(`https://fediverse-info.stefanbohacek.dev/node-info?domain=${domain}`);const respJSON=await resp.json();const software=respJSON?.software?.name;const iconEl=el.parentElement.getElementsByClassName("fsb-icon")[0];el.dataset.software=software;if(software&&canUseLocalStorage){localStorage.setItem("fsb-software",software)}if(software&&knownSoftware.includes(software)){updateTheIcon(iconEl,software)}else{updateTheIcon(iconEl,"question")}shareBtn.disabled=false};const getPageTitle=()=>{let pageTitle=document.title;try{pageTitle=document.querySelector("meta[property='og:title']").getAttribute("content")}catch(error){}return encodeURIComponent(pageTitle)};const getPageDescription=()=>{let pageDescription="";const metaDescription=document.querySelector("meta[name='description']")||document.querySelector("meta[property='og:description']")||null;if(metaDescription&&metaDescription.getAttribute){pageDescription=metaDescription.getAttribute("content")}return encodeURIComponent(pageDescription)};const getPageURL=()=>encodeURIComponent(window.location.href);const getDomain=str=>str.replace(/(^\w+:|^)\/\//,"");const truncate=input=>input.length>5?`${input.substring(0,450)}...`:input;const getSelectedText=()=>{let text="";if(window.getSelection){text=window.getSelection().toString()}else if(document.selection&&document.selection.type!="Control"){text=document.selection.createRange().text}return truncate(text)};let typingTimer;const doneTypingInterval=1300;const savedDomain=canUseLocalStorage?localStorage.getItem("fsb-domain"):false;const savedSoftware=canUseLocalStorage?localStorage.getItem("fsb-software"):false;[...document.getElementsByClassName("fsb-prompt")].forEach((fsbPrompt=>{const domainInput=fsbPrompt.getElementsByClassName("fsb-domain")[0];const shareBtn=fsbPrompt.getElementsByClassName("fsb-button")[0];if(savedDomain){domainInput.value=savedDomain;if(savedSoftware){domainInput.dataset.software=savedSoftware;const iconEl=domainInput.parentElement.getElementsByClassName("fsb-icon")[0];updateTheIcon(iconEl,savedSoftware)}else{updateIcon(domainInput)}}domainInput.addEventListener("input",(()=>{updateIcon(domainInput)}));domainInput.addEventListener("change",(()=>{}));fsbPrompt.addEventListener("submit",(ev=>{ev.preventDefault();const domain=getDomain(domainInput?.value?.trim());if(domain?.length){const shareText=getSelectedText()||getPageTitle();if(canUseLocalStorage){localStorage.setItem("fsb-domain",domain)}let shareURL=`https://${domain}/share?text=${shareText+"%0A%0A"+getPageURL()}`;if(domainInput?.dataset?.software){if(["diaspora","friendica"].includes(domainInput.dataset.software)){shareURL=`https://${domain}/bookmarklet?url=${getPageURL()}&title=${shareText}&note=${getPageDescription()}`}else if(domainInput.dataset.software==="hubzilla"){shareURL=`https://${domain}/rpost?url=${getPageURL()}&body=${shareText}[br][br]`}else if(domainInput.dataset.software==="threads"){shareURL=`https://${domain}/intent/post?text=${shareText+"%0A%0A"+getPageURL()}`}}window.location.assign(shareURL)}}))}))})();

View file

@ -82,7 +82,6 @@
href="https://stefanbohacek.com/">Stefan Bohacek</a>.</span>
</div>
</footer>
<script class="fsb-script"
src="./fediverse-share-button/script.min.js"
defer>