Skip to content

Commit

Permalink
Privacy Consent Screen (#78)
Browse files Browse the repository at this point in the history
* Privacy Consent Screen

This introduces a privacy consent screen that needs to be accepted before using the extension, as requested by Mozilla in order to allow it to be publicly available in their Add-ons marketplace.

It also releases this as 0.7.0.

* Don't show privacy consent popup in chrome

* add link to new browser privacy policy

* fix privacy policy link

* Update popup.html

---------

Co-authored-by: Hugh O'Brien <[email protected]>
  • Loading branch information
BrunoBernardino and hughobrien authored Jun 4, 2024
1 parent 8934a2d commit eef60af
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 7 deletions.
2 changes: 1 addition & 1 deletion chrome/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Kagi Search for Chrome",
"version": "0.6.1",
"version": "0.7.0",
"description": "A simple extension for setting Kagi as a default search engine, and automatically logging in to Kagi in incognito browsing windows",
"background": {
"service_worker": "src/background.js",
Expand Down
2 changes: 1 addition & 1 deletion firefox/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "Kagi Search for Firefox",
"version": "0.6.1",
"version": "0.7.0",
"description": "A simple helper extension for setting Kagi as a default search engine, and automatically logging in to Kagi in incognito browsing windows.",
"background": {
"page": "src/background_page.html"
Expand Down
17 changes: 16 additions & 1 deletion shared/src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let sessionApiToken = undefined;
let sessionApiEngine = undefined;
let sessionSummaryType = undefined;
let sessionTargetLanguage = undefined;
let sessionPrivacyConsent = false;
let IS_CHROME = true;

// Very hacky, but currently works flawlessly
Expand All @@ -18,7 +19,15 @@ if (typeof browser.runtime.getBrowserInfo === 'function') {
}

async function saveToken(
{ token, api_token, api_engine, sync, summary_type, target_language } = {},
{
token,
api_token,
api_engine,
sync,
summary_type,
target_language,
privacy_consent,
} = {},
isManual = false,
) {
sessionToken = typeof token !== 'undefined' ? token : sessionToken;
Expand All @@ -32,6 +41,10 @@ async function saveToken(
typeof target_language !== 'undefined'
? target_language
: sessionTargetLanguage;
sessionPrivacyConsent =
typeof privacy_consent !== 'undefined'
? privacy_consent
: sessionPrivacyConsent;

let shouldSync = sync || !isManual;
if (typeof sessionToken === 'undefined' || sessionToken.trim().length === 0) {
Expand All @@ -49,6 +62,7 @@ async function saveToken(
api_engine: sessionApiEngine,
summary_type: sessionSummaryType,
target_language: sessionTargetLanguage,
privacy_consent: sessionPrivacyConsent,
});
} catch (error) {
console.error(error);
Expand All @@ -70,6 +84,7 @@ async function saveToken(
api_engine: sessionApiEngine,
summary_type: sessionSummaryType,
target_language: sessionTargetLanguage,
privacy_consent: sessionPrivacyConsent,
});
}

Expand Down
6 changes: 6 additions & 0 deletions shared/src/lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@ export async function fetchSettings() {
const summaryTypeObject = await browser.storage.local.get('summary_type');
const targetLanguageObject =
await browser.storage.local.get('target_language');
const privacyConsentObject =
await browser.storage.local.get('privacy_consent');

return {
token: sessionObject?.session_token,
Expand All @@ -119,6 +121,10 @@ export async function fetchSettings() {
api_engine: apiEngineObject?.api_engine,
summary_type: summaryTypeObject?.summary_type,
target_language: targetLanguageObject?.target_language,
privacy_consent:
typeof privacyConsentObject?.privacy_consent !== 'undefined'
? privacyConsentObject.privacy_consent
: false,
};
}

Expand Down
4 changes: 2 additions & 2 deletions shared/src/popup.css
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ p {
margin-bottom: 5px;
}

#summarize_page, #request_permissions_button, #fastgpt_submit {
#summarize_page, #request_permissions_button, #fastgpt_submit, #privacy_consent_button {
background-color: #ffb319;
border: 1px solid #ffb319;
color: #191919;
Expand All @@ -369,7 +369,7 @@ p {
margin-right: auto;
}

#summarize_page:hover, #request_permissions_button:hover, #fastgpt_submit {
#summarize_page:hover, #request_permissions_button:hover, #fastgpt_submit:hover, #privacy_consent_button:hover {
background-color: #f7a808;
border: 1px solid #d9950d;
}
19 changes: 18 additions & 1 deletion shared/src/popup.html
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,23 @@
</span>
</div>

<div id="privacy_consent_message" class="setting_row" style="display: none">
<div>
<div class="title" style="font-size: 1.2rem; margin-bottom: 1rem; text-align: center;">
Privacy Notice
</div>
<div class="desc" style="font-size: 0.9rem;">
With your permission, this extension will access your Kagi account (via the session cookie) and automatically configure the extension so that won't need to log-in when in private browsing mode. Please note you will need to set 'allow in private browsing' in your extensions page as the extension cannot set this automatically.
<br /><br />
Granting access to the current tab will enable the Universal Summarizer, which receives the URL of your tab and generates a summary.
<br /><br />
<a href="https://kagi.com/privacy#Browser-Extension" target="_blank" rel="noopener noreferrer">For more information, please refer to our Privacy Policy</a>
<br /><br />
<button id="privacy_consent_button">Allow access</button>
</div>
</div>
</div>

<span id="status_error_message" style="display: none">
No kagi session found.<br />
Login to Kagi or open a Kagi tab and the extension should automatically configure.<br />
Expand Down Expand Up @@ -262,7 +279,7 @@
<div class="desc">Allow accessing the currently active tab, so it can be summarized.</div>

<div class="setting_row">
<button id="request_permissions_button">Request Permissions</button>
<button id="request_permissions_button">Request permissions</button>
</div>
</div>

Expand Down
40 changes: 39 additions & 1 deletion shared/src/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,20 @@ async function setup() {
return;
}

const privacyConsentDiv = document.querySelector('#privacy_consent_message');
if (!privacyConsentDiv) {
console.error('Could not find privacy div');
return;
}

const privacyConsentButton = document.querySelector(
'#privacy_consent_button',
);
if (!privacyConsentButton) {
console.error('No privacy consent button found.');
return;
}

const tokenDiv = document.querySelector('#token');
if (!tokenDiv) {
console.error('Could not find token div');
Expand Down Expand Up @@ -220,6 +234,19 @@ async function setup() {
return;
}

privacyConsentButton.addEventListener('click', async () => {
try {
await browser.runtime.sendMessage({
type: 'save_token',
privacy_consent: true,
});
} catch (error) {
console.error(error);

showSavingError();
}
});

saveTokenButton.addEventListener('click', async () => {
let token = tokenInput.value;

Expand Down Expand Up @@ -390,8 +417,9 @@ async function setup() {
api_engine,
summary_type,
target_language,
privacy_consent,
} = {}) {
if (token) {
if ((privacy_consent || IS_CHROME) && token) {
tokenInput.value = token;

if (api_token) {
Expand Down Expand Up @@ -474,7 +502,16 @@ async function setup() {
}
}
}
} else if (!privacy_consent && !IS_CHROME) {
setStatus('');
privacyConsentDiv.style.display = '';
tokenDiv.style.display = 'none';
advancedToggle.style.display = 'none';
saveErrorDiv.style.display = 'none';
toggleAdvancedDisplay('close');
} else {
privacyConsentDiv.style.display = 'none';
advancedToggle.style.display = '';
setStatus('no_session');
}
}
Expand Down Expand Up @@ -510,6 +547,7 @@ async function setup() {
setStatus('manual_token');
saveTokenButton.innerText = 'Saved!';
saveErrorDiv.style.display = 'none';
advancedToggle.style.display = '';

const newlyFetchedSettings = await fetchSettings();
await handleGetData(newlyFetchedSettings);
Expand Down

0 comments on commit eef60af

Please sign in to comment.