auto login, indicates whether a page is bookmarked
This commit is contained in:
parent
ee03754735
commit
115c71b873
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
web-ext-artifacts
|
web-ext-artifacts
|
||||||
|
node_modules
|
||||||
|
|||||||
@ -1,21 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "Web Extension for Shaarli",
|
"name": "Web Extension for Shaarli modified",
|
||||||
"description": "Share your link to your Shaarli on Firefox Quantum",
|
"description": "Share your link to your Shaarli, test version",
|
||||||
"version": "2.0.0",
|
"version": "2.0.1",
|
||||||
"homepage_url": "https://github.com/ikipatang/shaarli-web-extension",
|
"homepage_url": "https://git.hmthsn.com/mantao/shaarli-web-extension",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"icons": {
|
"icons": {
|
||||||
"48": "resources/icons/icon-48.png"
|
"48": "resources/icons/icon-48.png"
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"tabs",
|
"tabs",
|
||||||
"storage"
|
"storage",
|
||||||
|
"contextMenus"
|
||||||
],
|
],
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "src/options/options.html"
|
"page": "src/options/options.html"
|
||||||
},
|
},
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": ["src/storage.js", "src/background.js"]
|
"page": "src/background-page.html"
|
||||||
},
|
},
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
"default_icon": "resources/icons/icon-24.png",
|
"default_icon": "resources/icons/icon-24.png",
|
||||||
@ -25,5 +26,15 @@
|
|||||||
"browser_style": false,
|
"browser_style": false,
|
||||||
"default_icon": "resources/icons/icon-24.png",
|
"default_icon": "resources/icons/icon-24.png",
|
||||||
"default_title": "Share"
|
"default_title": "Share"
|
||||||
|
},
|
||||||
|
"content_scripts": [
|
||||||
|
{
|
||||||
|
"matches": ["*://sl.hmthsn.com/login*"],
|
||||||
|
"js": ["src/login_helper.js"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"matches": ["*://sl.hmthsn.com/*"],
|
||||||
|
"js": ["src/close_helper.js"]
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
9747
package-lock.json
generated
Normal file
9747
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,5 +26,9 @@
|
|||||||
"build": "web-ext build",
|
"build": "web-ext build",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"version": "version-changelog CHANGELOG.md"
|
"version": "version-changelog CHANGELOG.md"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"browserify": "^17.0.0",
|
||||||
|
"unirest": "^0.6.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
resources/icons/action-bookmarked-16.png
Normal file
BIN
resources/icons/action-bookmarked-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 701 B |
BIN
resources/icons/action-bookmarked-32.png
Normal file
BIN
resources/icons/action-bookmarked-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
BIN
resources/icons/action-bookmarked-64.png
Normal file
BIN
resources/icons/action-bookmarked-64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
resources/icons/action-default-16.png
Normal file
BIN
resources/icons/action-default-16.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 645 B |
BIN
resources/icons/action-default-32.png
Normal file
BIN
resources/icons/action-default-32.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
resources/icons/action-default-64.png
Normal file
BIN
resources/icons/action-default-64.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 KiB |
BIN
shaarli-web-extension.xpi
Normal file
BIN
shaarli-web-extension.xpi
Normal file
Binary file not shown.
13
src/background-page.html
Normal file
13
src/background-page.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
"scripts": ["src/storage.js", "src/background.js"]
|
||||||
|
<script src="lib/jquery-3.5.1.js"></script>
|
||||||
|
<script src="lib/crypto-js.js"></script>
|
||||||
|
<script src="lib/client.js"></script>
|
||||||
|
<script type="module" src="storage.js"></script>
|
||||||
|
<script type="module" src="background.js"></script>
|
||||||
|
</head>
|
||||||
|
</html>
|
||||||
@ -1,3 +1,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the given url in a popup
|
* Open the given url in a popup
|
||||||
* @param {string} url -
|
* @param {string} url -
|
||||||
@ -12,9 +16,9 @@ function openInPopup(url, width, height) {
|
|||||||
allowScriptsToClose: true,
|
allowScriptsToClose: true,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
var last_tab;
|
||||||
/**
|
/**
|
||||||
* Share Current Tab
|
* Share Current Tab
|
||||||
* @return {void} -
|
* @return {void} -
|
||||||
@ -59,9 +63,125 @@ browser.tabs.query({active: true, currentWindow: true}).then((tabs) => {
|
|||||||
showPageAction(tabs[0].id);
|
showPageAction(tabs[0].id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function getCurrentTab() {
|
||||||
|
// Get active tabs in current window
|
||||||
|
var tabs = await browser.tabs.query({
|
||||||
|
currentWindow: true,
|
||||||
|
active: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (tabs.length < 1) {
|
||||||
|
throw new Error("no tab available");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure URL protocol supported
|
||||||
|
var supportedProtocols = ["https:", "http:", "ftp:", "file:"],
|
||||||
|
activeTab = tabs[0],
|
||||||
|
url = document.createElement('a');
|
||||||
|
|
||||||
|
if (activeTab.url !== "") {
|
||||||
|
url.href = activeTab.url;
|
||||||
|
if (supportedProtocols.indexOf(url.protocol) === -1) {
|
||||||
|
throw new Error(`protocol "${url.protocol}" is not supported`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_tab = activeTab
|
||||||
|
return activeTab;
|
||||||
|
}
|
||||||
|
async function findLocalBookmark(url){
|
||||||
|
let data = await browser.storage.local.get("links");
|
||||||
|
let result = data.links.hasOwnProperty(url);
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
async function updateIcon() {
|
||||||
|
// Set initial icon
|
||||||
|
var runtimeUrl = await browser.runtime.getURL("/"),
|
||||||
|
icon = {path: {
|
||||||
|
16: "../resources/icons/action-default-16.png",
|
||||||
|
32: "../resources/icons/action-default-32.png",
|
||||||
|
64: "../resources/icons/action-default-64.png"
|
||||||
|
}};
|
||||||
|
|
||||||
|
// Firefox allows using empty object as default icon.
|
||||||
|
// This way, Firefox will use default_icon that defined in manifest.json
|
||||||
|
// if (runtimeUrl.startsWith("moz")) {
|
||||||
|
// icon = {};
|
||||||
|
// }
|
||||||
|
// Get current active tab
|
||||||
|
try {
|
||||||
|
var tab = await getCurrentTab()
|
||||||
|
var local = await findLocalBookmark(tab.url);
|
||||||
|
|
||||||
|
if (local) icon.path = {
|
||||||
|
16: "../resources/icons/action-bookmarked-16.png",
|
||||||
|
32: "../resources/icons/action-bookmarked-32.png",
|
||||||
|
64: "../resources/icons/action-bookmarked-64.png"
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("tab:", tab);
|
||||||
|
|
||||||
|
// icon.tabId = tab.id;
|
||||||
|
|
||||||
|
// browser.pageAction.setIcon(icon);
|
||||||
|
} catch {}
|
||||||
|
return browser.browserAction.setIcon(icon);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateActiveTab() {
|
||||||
|
updateIcon().catch(err => console.error(err.message));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Listeners
|
Listeners
|
||||||
*/
|
*/
|
||||||
browser.tabs.onActivated.addListener(tabActivation);
|
browser.tabs.onActivated.addListener(tabActivation);
|
||||||
browser.browserAction.onClicked.addListener(shareCurrentTab);
|
browser.browserAction.onClicked.addListener(shareCurrentTab);
|
||||||
browser.pageAction.onClicked.addListener(shareCurrentTab);
|
browser.pageAction.onClicked.addListener(shareCurrentTab);
|
||||||
|
|
||||||
|
|
||||||
|
browser.tabs.onUpdated.addListener(updateActiveTab);
|
||||||
|
browser.tabs.onActivated.addListener(updateActiveTab);
|
||||||
|
browser.windows.onFocusChanged.addListener(updateActiveTab);
|
||||||
|
updateActiveTab();
|
||||||
|
|
||||||
|
let onCreated = console.log;
|
||||||
|
browser.contextMenus.create({
|
||||||
|
id: "log-selection",
|
||||||
|
title: "Sync bookmarks",
|
||||||
|
contexts: ["all"]
|
||||||
|
}, onCreated);
|
||||||
|
|
||||||
|
async function sync_links(){
|
||||||
|
var token = await browser.storage.local.get("token")
|
||||||
|
token = token.token
|
||||||
|
var result = await getLinks(token);
|
||||||
|
let links = {}
|
||||||
|
result.forEach((value)=>{
|
||||||
|
links[value.url] = true;
|
||||||
|
})
|
||||||
|
browser.storage.local.set({"links":links});
|
||||||
|
console.log(links);
|
||||||
|
}
|
||||||
|
browser.contextMenus.onClicked.addListener(async function(info, tab) {
|
||||||
|
switch (info.menuItemId) {
|
||||||
|
case "log-selection":
|
||||||
|
await sync_links();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log("addon loaded")
|
||||||
|
|
||||||
|
browser.runtime.onMessage.addListener(async (message) => {
|
||||||
|
|
||||||
|
console.log("sync signal received",message)
|
||||||
|
if (message === "sync") {
|
||||||
|
await new Promise(r => setTimeout(r, 1000));
|
||||||
|
await sync_links();
|
||||||
|
await new Promise(r => setTimeout(r, 100));
|
||||||
|
updateIcon();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sync_links();
|
||||||
|
browser.storage.local.set({"attempt":0});
|
||||||
3
src/close_helper.js
Normal file
3
src/close_helper.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
window.onbeforeunload = function() {
|
||||||
|
browser.runtime.sendMessage("sync");
|
||||||
|
}
|
||||||
31
src/lib/client.js
Normal file
31
src/lib/client.js
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
var base64url = function(aStr) { return btoa(aStr.replace(/\+/g,'-').replace(/\//g,'_')).replace(/\=+$/m,'') }
|
||||||
|
function generateToken(secret){
|
||||||
|
header = base64url(`{
|
||||||
|
"typ": "JWT",
|
||||||
|
"alg": "HS512"
|
||||||
|
}`);
|
||||||
|
|
||||||
|
payload = base64url(`{
|
||||||
|
"iat": ${Math.floor(Date.now() / 1000)}
|
||||||
|
}`)
|
||||||
|
console.log(payload)
|
||||||
|
// payload = base64url(`{
|
||||||
|
// "iat": 1605996074
|
||||||
|
// }`)
|
||||||
|
var hash = CryptoJS.HmacSHA512(header + '.'+ payload, secret);
|
||||||
|
var signature = hash.toString(CryptoJS.enc.Base64).replace(/\=+$/m,'').replaceAll('/','_').replaceAll('+','-');
|
||||||
|
return header + "." + payload + "." + signature
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getLinks(api_token){
|
||||||
|
let token = generateToken(api_token)
|
||||||
|
var result = await $.ajax(
|
||||||
|
{
|
||||||
|
url: "https://sl.hmthsn.com/api/v1/links",
|
||||||
|
//url: "http://127.0.0.1:8081/",
|
||||||
|
type: 'GET',
|
||||||
|
headers:{"Authorization": 'Bearer ' + token}
|
||||||
|
} )
|
||||||
|
return result
|
||||||
|
}
|
||||||
6059
src/lib/crypto-js.js
Normal file
6059
src/lib/crypto-js.js
Normal file
File diff suppressed because it is too large
Load Diff
10872
src/lib/jquery-3.5.1.js
vendored
Normal file
10872
src/lib/jquery-3.5.1.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
10
src/login_helper.js
Normal file
10
src/login_helper.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
browser.storage.local.get().then(async (storage) => {
|
||||||
|
if(storage.attempt==0 && storage.login.length && storage.password.length){
|
||||||
|
await browser.storage.local.set({
|
||||||
|
attempt: 1
|
||||||
|
})
|
||||||
|
document.getElementsByName("login")[0].value=storage.login
|
||||||
|
document.getElementsByName("password")[0].value=storage.password
|
||||||
|
document.getElementsByName("loginform")[0].submit()
|
||||||
|
}
|
||||||
|
})
|
||||||
@ -14,6 +14,24 @@
|
|||||||
<input id="url" type="text" name="url">
|
<input id="url" type="text" name="url">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label>
|
||||||
|
<span>Shaarli API Token</span>
|
||||||
|
<input id="token" type="text" name="token">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label>
|
||||||
|
<span>Shaarli User</span>
|
||||||
|
<input id="login" type="text" name="login">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<label>
|
||||||
|
<span>Shaarli Password</span>
|
||||||
|
<input id="password" type="text" name="password">
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<label>
|
<label>
|
||||||
<span>Popup dimensions (px)</span>
|
<span>Popup dimensions (px)</span>
|
||||||
|
|||||||
@ -29,11 +29,18 @@ function updateUI(restoredSettings) {
|
|||||||
const popupHeight = document.querySelector("#popupHeight");
|
const popupHeight = document.querySelector("#popupHeight");
|
||||||
const pageAction = document.querySelector("#pageAction");
|
const pageAction = document.querySelector("#pageAction");
|
||||||
|
|
||||||
|
const token = document.querySelector("#token");
|
||||||
|
const login = document.querySelector("#login");
|
||||||
|
const password = document.querySelector("#password");
|
||||||
// Set HTML input with stored values
|
// Set HTML input with stored values
|
||||||
url.value = restoredSettings.url;
|
url.value = restoredSettings.url;
|
||||||
popupWidth.value = restoredSettings.popupWidth;
|
popupWidth.value = restoredSettings.popupWidth;
|
||||||
popupHeight.value = restoredSettings.popupHeight;
|
popupHeight.value = restoredSettings.popupHeight;
|
||||||
pageAction.checked = restoredSettings.pageAction;
|
pageAction.checked = restoredSettings.pageAction;
|
||||||
|
token.value = restoredSettings.token;
|
||||||
|
login.value = restoredSettings.login;
|
||||||
|
password.value = restoredSettings.password;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,12 +52,18 @@ function storeSettings() {
|
|||||||
const popupWidth = document.querySelector("#popupWidth");
|
const popupWidth = document.querySelector("#popupWidth");
|
||||||
const popupHeight = document.querySelector("#popupHeight");
|
const popupHeight = document.querySelector("#popupHeight");
|
||||||
const pageAction = document.querySelector("#pageAction");
|
const pageAction = document.querySelector("#pageAction");
|
||||||
|
const token = document.querySelector("#token");
|
||||||
|
const login = document.querySelector("#login");
|
||||||
|
const password = document.querySelector("#password");
|
||||||
const settings = {
|
const settings = {
|
||||||
url: url.value,
|
url: url.value,
|
||||||
popupWidth: parseIntDimension(popupWidth.value),
|
popupWidth: parseIntDimension(popupWidth.value),
|
||||||
popupHeight: parseIntDimension(popupHeight.value),
|
popupHeight: parseIntDimension(popupHeight.value),
|
||||||
pageAction: pageAction.checked,
|
pageAction: pageAction.checked,
|
||||||
|
token: token.value,
|
||||||
|
login: login.value,
|
||||||
|
password: password.value,
|
||||||
|
attempt: 0
|
||||||
};
|
};
|
||||||
// console.log('storeSettings settings');
|
// console.log('storeSettings settings');
|
||||||
// console.log(settings);
|
// console.log(settings);
|
||||||
|
|||||||
@ -6,6 +6,10 @@ var storage = {
|
|||||||
pageAction: false,
|
pageAction: false,
|
||||||
popupWidth: 900,
|
popupWidth: 900,
|
||||||
popupHeight: 600,
|
popupHeight: 600,
|
||||||
|
login: "",
|
||||||
|
password: "",
|
||||||
|
token: "",
|
||||||
|
attempt: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user