Skip to content

Commit

Permalink
feat: add extension menu
Browse files Browse the repository at this point in the history
The  click-to-enable / disable logic of the extension icon did not
follow extension development guidelines, as it was not clear what
happens when clicking the icon.

To fix this, we switch to a menu-based approach. In the future, this
menu can be extended to also switch between accounts / identities.

Signed-off-by: Felix Moessbauer <[email protected]>
  • Loading branch information
fmoessbauer committed Aug 6, 2024
1 parent afc79fb commit 0d309e4
Show file tree
Hide file tree
Showing 10 changed files with 282 additions and 16 deletions.
26 changes: 19 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ ARCHIVE_NAME=$(PACKAGE_NAME)-$(RELEASE_TAG)

COMMON_INPUT_FILES= \
LICENSES/MPL-2.0.txt \
background.js
background.js \
popup/menu.css \
popup/menu.js \
popup/menu.html

CHROME_INPUT_FILES= \
$(COMMON_INPUT_FILES) \
Expand All @@ -45,13 +48,16 @@ CHROME_INPUT_FILES= \
icons/linux-entra-sso_48.png \
icons/linux-entra-sso_48.png.license \
icons/linux-entra-sso_128.png \
icons/linux-entra-sso_128.png.license
icons/linux-entra-sso_128.png.license \
icons/profile-outline_48.png \
icons/profile-outline_48.png.license

FIREFOX_INPUT_FILES= \
$(COMMON_INPUT_FILES) \
platform/firefox/manifest.json \
platform/firefox/manifest.json.license \
icons/linux-entra-sso.svg
icons/linux-entra-sso.svg \
icons/profile-outline.svg

# common files for all platforms (relative to build directory)
CHROME_PACKAGE_FILES= \
Expand All @@ -61,13 +67,17 @@ CHROME_PACKAGE_FILES= \
icons/linux-entra-sso_48.png \
icons/linux-entra-sso_48.png.license \
icons/linux-entra-sso_128.png \
icons/linux-entra-sso_128.png.license
icons/linux-entra-sso_128.png.license \
icons/profile-outline_48.png \
icons/profile-outline_48.png.license \
popup/profile-outline.svg

FIREFOX_PACKAGE_FILES= \
$(COMMON_INPUT_FILES) \
manifest.json \
manifest.json.license \
icons/linux-entra-sso.svg
icons/linux-entra-sso.svg \
popup/profile-outline.svg

UPDATE_VERSION='s|"version":.*|"version": "$(VERSION)",|'

Expand All @@ -85,12 +95,14 @@ DEBIAN_PKG_FILE = $(DEBIAN_PKG_DIR)/$(DEBIAN_PN)_$(DEBIAN_PV)_$(DEBIAN_ARCH).deb

all package: clean $(CHROME_INPUT_FILES) $(FIREFOX_INPUT_FILES)
for P in firefox chrome; do \
mkdir -p build/$$P/icons; \
mkdir -p build/$$P/icons build/$$P/popup; \
cp platform/$$P/manifest* build/$$P; \
cp -rf LICENSES background.js build/$$P/; \
done
cp icons/*.svg build/firefox/icons/
cp icons/*.png* build/chrome/icons/
cp icons/*.png* icons/profile-outline.svg build/chrome/icons/
cp popup/menu.* icons/linux-entra-sso.svg icons/profile-outline.svg build/firefox/popup/
cp popup/menu.* icons/linux-entra-sso.svg icons/profile-outline.svg build/chrome/popup/
cd build/firefox && zip -r ../$(ARCHIVE_NAME).firefox.xpi $(FIREFOX_PACKAGE_FILES) && cd ../../;
cd build/chrome && zip -r ../$(ARCHIVE_NAME).chrome.zip $(CHROME_PACKAGE_FILES) && cd ../../;

Expand Down
56 changes: 47 additions & 9 deletions background.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ let graph_api_token = null;
let state_active = true;
let broker_online = false;
let port_native = null;
let port_menu = null;

function ssoLog(message) {
console.log('[Linux Entra SSO] ' + message)
Expand All @@ -42,6 +43,17 @@ async function waitFor(f) {
return f();
};

function notify_state_change() {
if (!port_menu)
return;
port_menu.postMessage({
'event': 'stateChanged',
'account': accounts.registered.length > 0 ? accounts.registered[0] : null,
'broker_online': broker_online,
'enabled': state_active
});
}

async function load_accounts() {
port_native.postMessage({'command': 'getAccounts'});
await waitFor(() => {
Expand All @@ -55,6 +67,7 @@ async function load_accounts() {
return;
}
accounts.active = accounts.registered[0];
accounts.active.avatar = null;
ssoLog('active account: ' + accounts.active.username);

// load profile picture and set it as icon
Expand Down Expand Up @@ -83,12 +96,28 @@ async function load_accounts() {
chrome.action.setIcon({
'imageData': ctx.getImageData(0, 0, 48, 48)
});
/* serialize image to data URL (ugly, but portable) */
let blob = await canvas.convertToBlob();
const dataUrl = await new Promise(r => {let a=new FileReader(); a.onload=r; a.readAsDataURL(blob)}).then(e => e.target.result);
accounts.active.avatar = dataUrl;
} else {
ssoLog('Warning: Could not get profile picture.');
if (isFirefox()) {
chrome.action.setIcon({
'path': 'icons/profile-outline.svg'
});
} else {
chrome.action.setIcon({
'path': {
'48': 'icons/profile-outline_48.png'
}
});
}
}
chrome.action.setTitle({
title: 'EntraID SSO: ' + accounts.active.username}
);
notify_state_change();
}

function logout() {
Expand All @@ -110,6 +139,7 @@ function logout() {
if (state_active)
title = 'EntraID SSO disabled (waiting for broker).'
chrome.action.setTitle({title: title});
notify_state_change();
}

async function get_or_request_prt(ssoUrl) {
Expand Down Expand Up @@ -224,6 +254,18 @@ async function on_message_native(response) {
}
}

async function on_message_menu(request) {
if (request.command == "login") {
state_active = !state_active;
if (state_active && broker_online) {
load_accounts();
}
} else if (request.command == "logout") {
state_active = !state_active;
logout();
}
}

function on_startup() {
if (initialized) {
ssoLog('linux-entra-sso already initialized');
Expand All @@ -246,6 +288,11 @@ function on_startup() {
});

port_native.onMessage.addListener(on_message_native);
chrome.runtime.onConnect.addListener((port) => {
port_menu = port;
port_menu.onMessage.addListener(on_message_menu);
notify_state_change();
});

if (isFirefox()) {
browser.webRequest.onBeforeSendHeaders.addListener(
Expand All @@ -263,15 +310,6 @@ function on_startup() {
}
});
}

chrome.action.onClicked.addListener(() => {
state_active = !state_active;
if (state_active && broker_online) {
load_accounts();
} else {
logout();
}
});
}

// use this API to prevent the extension from being disabled
Expand Down
25 changes: 25 additions & 0 deletions icons/profile-outline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icons/profile-outline_48.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions icons/profile-outline_48.png.license
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SPDX-FileCopyrightText: Copyright 2021 YANDEX LLC

SPDX-License-Identifier: MPL-2.0
1 change: 1 addition & 0 deletions platform/chrome/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"128": "icons/linux-entra-sso_128.png"
},
"action": {
"default_popup": "popup/menu.html",
"default_icon": {
"48": "icons/linux-entra-sso_48.png",
"128": "icons/linux-entra-sso_128.png"
Expand Down
1 change: 1 addition & 0 deletions platform/firefox/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
}
},
"action": {
"default_popup": "popup/menu.html",
"default_icon": "icons/linux-entra-sso.svg",
"default_title": "Linux Entra SSO",
"default_area": "navbar"
Expand Down
82 changes: 82 additions & 0 deletions popup/menu.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* SPDX-License-Identifier: MPL-2.0
* SPDX-FileCopyrightText: Copyright 2024 Siemens AG
*/

html,
body {
width: 320px;
padding: 0;
margin: 0;
}

.entity {
padding: 10px;
margin: 10px;
border-radius: 15px;
color: #707070;
cursor: pointer;
}

body.pending .entity {
cursor: wait;
}

.entity:hover {
background-color: #e0e0e0;
}

.entity.active {
background-color: #e0e0e0;
color: #000;
cursor: default;
}

.entity .avatar {
display: inline-block;
margin-right: 10px;
}

.entity .info {
display: inline-block;
vertical-align: top;
max-width: 200px;
overflow: hidden;
}
.entity .info .email
{
font-size: 0.8em;
}

.entity .avatar img {
width: 48px;
height: 48px;
}

.hidden {
display:none !important;
}

.footer {
padding: 5px 5px 10px 5px;
border-top: 1px solid #e0e0e0;
font-size: 0.8em;
text-align: right;
min-height: 1em;
color: #707070;
}

.footer a,
.footer a:visited {
color: #707070;
}

.footer .left {
display: block;
float: left;
}

.footer .right {
display: block;
float: right;
}
37 changes: 37 additions & 0 deletions popup/menu.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<!--
SPDX-License-Identifier: MPL-2.0
SPDX-FileCopyrightText: Copyright 2024 Siemens AG
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" href="menu.css" />
</head>
<body>
<div class="entity active" id="entity-me">
<div class="avatar">
<canvas id="me-avatar" width="48" height="48" class="hidden"></canvas>
<img id="me-avatar-fallback" src="profile-outline.svg" width="48", height="48", alt="Avatar"/>
</div>
<div class="info" id="entity-me">
<div id="me-name" class="name">No account registered</div>
<div id="me-email" class="email"></div>
</div>
</div>
<div class="entity" id="entity-guest">
<div class="avatar">
<img src="profile-outline.svg" alt="Avatar" />
</div>
<div class="info">
<div class="name">Guest</div>
<div class="email">(no device trust)</div>
</div>
</div>
<div class="footer">
<a href="https://github.com/siemens/linux-entra-sso" target="_blank" class="left">linux-entra-sso</a>
<span id="version" class="right"></span>
</div>
<script src="menu.js"></script>
</body>
</html>
Loading

0 comments on commit 0d309e4

Please sign in to comment.