diff --git a/app/config/README.md b/app/config/README.md
index 48b3466..fcdb7b1 100644
--- a/app/config/README.md
+++ b/app/config/README.md
@@ -57,6 +57,8 @@ Here is the list of available arguments and its usage:
| spellCheckerLanguages | Array of languages to use with Electron's spell checker | [] |
| ssoBasicAuthUser | Login that will be sent for basic_auth SSO login. | string |
| ssoBasicAuthPasswordCommand | Command to execute, grab stdout and use it as a password for basic_auth SSO login. | string |
+| ssoIntuneEnabled | Enable InTune Single-Sign-On | false
+| ssoIntuneAuthUser | User (e-mail) to be used for InTune SSO login. | string |
| trayIconEnabled | Enable tray icon | true |
| url | Microsoft Teams URL | string |
| useMutationTitleLogic | Use MutationObserver to update counter from title | true |
diff --git a/app/config/index.js b/app/config/index.js
index 117c655..fb1bec1 100644
--- a/app/config/index.js
+++ b/app/config/index.js
@@ -275,6 +275,16 @@ function argv(configPath, appVersion) {
describe: 'Command to execute to retrieve password for SSO basic auth.',
type: 'string'
},
+ ssoInTuneEnabled: {
+ default: false,
+ describe: 'Enable Single-Sign-On using Microsoft InTune.',
+ type: 'boolean'
+ },
+ ssoInTuneAuthUser: {
+ default: '',
+ describe: 'User (e-mail) to use for InTune SSO.',
+ type: 'string'
+ },
trayIconEnabled: {
default: true,
describe: 'Enable tray icon',
diff --git a/app/intune/index.js b/app/intune/index.js
new file mode 100644
index 0000000..e4474f3
--- /dev/null
+++ b/app/intune/index.js
@@ -0,0 +1,91 @@
+const dbus = require('@homebridge/dbus-native');
+const { LucidLog } = require('lucid-log');
+
+var sessionBus = dbus.sessionBus();
+
+var intuneAccount = null;
+
+var brokerService = sessionBus.getService('com.microsoft.identity.broker1');
+
+function processInTuneAccounts(logger, resp, ssoInTuneAuthUser) {
+ response = JSON.parse(resp);
+ if ('error' in response) {
+ logger.warn('Failed to retrieve InTune account list: ' + response.error.context);
+ return;
+ };
+
+ if (ssoInTuneAuthUser == '') {
+ intuneAccount = response.accounts[0];
+ logger.debug('Using first available InTune account (' + intuneAccount.username + ')');
+ } else {
+ for (account in response.accounts) {
+ if (account.username == ssoIntuneAuthUser) {
+ intuneAccount = account;
+ logger.debug('Found matching InTune account (' + intuneAccount.username + ')');
+ break;
+ }
+ }
+ if (intuneAccount == null) {
+ logger.warn('Failed to find matching InTune account for ' + ssoIntuneAuthUser + '.');
+ }
+ }
+}
+
+exports.initSso = function initIntuneSso(logger, ssoInTuneAuthUser) {
+ logger.debug("Initializing InTune SSO");
+ brokerService.getInterface(
+ '/com/microsoft/identity/broker1',
+ 'com.microsoft.identity.Broker1', function(err, broker) {
+ if (err) {
+ logger.warn('Failed to find microsoft-identity-broker DBus interface');
+ return;
+ }
+ broker.getAccounts('0.0', '', JSON.stringify({'clientId': '88200948-af09-45a1-9c03-53cdcc75c183', 'redirectUri':'urn:ietf:oob'}), function(err, resp) {
+ if (err) {
+ logger.warn('Failed to communicate with microsoft-identity-broker');
+ return;
+ }
+ processInTuneAccounts(logger, resp, ssoInTuneAuthUser);
+ });
+ });
+}
+
+exports.setupUrlFilter = function setupUrlFilter(filter) {
+ filter.urls.push('https://login.microsoftonline.com/*');
+}
+
+exports.isSsoUrl = function isSsoUrl(url) {
+ return intuneAccount != null && url.startsWith('https://login.microsoftonline.com/');
+}
+
+function processPrtResponse(logger, resp, detail) {
+ response = JSON.parse(resp);
+ if ('error' in response) {
+ logger.warn('Failed to retrieve Intune SSO cookie: ' + response.error.context);
+ } else {
+ logger.debug('Adding SSO credential');
+ detail.requestHeaders['X-Ms-Refreshtokencredential'] = response['cookieContent'];
+ }
+}
+
+exports.addSsoCookie = function addIntuneSsoCookie(logger, detail, callback) {
+ logger.debug('Retrieving InTune SSO cookie');
+ if (intuneAccount == null) {
+ logger.info("InTune SSO not active");
+ callback({
+ requestHeaders: detail.requestHeaders
+ });
+ return;
+ }
+ brokerService.getInterface(
+ '/com/microsoft/identity/broker1',
+ 'com.microsoft.identity.Broker1', function(err, broker) {
+ broker.acquirePrtSsoCookie('0.0', '', JSON.stringify({'ssoUrl':detail.url, 'account':intuneAccount, 'authParameters':{'authority':'https://login.microsoftonline.com/common/'}}), function(err, resp) {
+ processPrtResponse(logger, resp, detail);
+ callback({
+ requestHeaders: detail.requestHeaders
+ });
+ });
+ });
+}
+
diff --git a/app/mainAppWindow/index.js b/app/mainAppWindow/index.js
index 4f33baa..043237c 100644
--- a/app/mainAppWindow/index.js
+++ b/app/mainAppWindow/index.js
@@ -16,6 +16,7 @@ const TrayIconChooser = require('../browser/tools/trayIconChooser');
const { AppConfiguration } = require('../appConfiguration');
const connMgr = require('../connectionManager');
const fs = require('fs');
+const intune = require('../intune');
/**
* @type {TrayIconChooser}
@@ -65,6 +66,10 @@ exports.onAppReady = async function onAppReady(configGroup) {
levels: config.appLogLevels.split(',')
});
+ if (config.ssoInTuneEnabled) {
+ intune.initSso(logger, config.ssoInTuneAuthUser);
+ }
+
window = await createWindow();
if (config.trayIconEnabled) {
@@ -323,12 +328,16 @@ function setImgSrcSecurityPolicy(policies) {
* @param {Electron.BeforeSendResponse} callback
*/
function onBeforeSendHeadersHandler(detail, callback) {
- if (detail.url.startsWith(customBGServiceUrl.href)) {
- detail.requestHeaders['Access-Control-Allow-Origin'] = '*';
+ if (intune.isSsoUrl(detail.url)) {
+ intune.addSsoCookie(logger, detail, callback);
+ } else {
+ if (detail.url.startsWith(customBGServiceUrl.href)) {
+ detail.requestHeaders['Access-Control-Allow-Origin'] = '*';
+ }
+ callback({
+ requestHeaders: detail.requestHeaders
+ });
}
- callback({
- requestHeaders: detail.requestHeaders
- });
}
/**
@@ -409,6 +418,7 @@ function addEventHandlers() {
function getWebRequestFilterFromURL() {
const filter = customBGServiceUrl.protocol === 'http:' ? { urls: ['http://*/*'] } : { urls: ['https://*/*'] };
+ intune.setupUrlFilter(filter);
return filter;
}
diff --git a/com.github.IsmaelMartinez.teams_for_linux.appdata.xml b/com.github.IsmaelMartinez.teams_for_linux.appdata.xml
index ae44d16..0fe11ed 100644
--- a/com.github.IsmaelMartinez.teams_for_linux.appdata.xml
+++ b/com.github.IsmaelMartinez.teams_for_linux.appdata.xml
@@ -14,6 +14,13 @@
https://github.com/IsmaelMartinez/teams-for-linux/issues
com.github.IsmaelMartinez.teams_for_linux.desktop
+
+
+
+ - Add support for Single Sign On using Microsoft Intune
+
+
+
diff --git a/package.json b/package.json
index 66b7a9a..e79bd81 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "teams-for-linux",
- "version": "1.5.2",
+ "version": "1.5.3",
"main": "app/index.js",
"description": "Unofficial client for Microsoft Teams for Linux",
"homepage": "https://github.com/IsmaelMartinez/teams-for-linux",
@@ -40,6 +40,7 @@
"release": "electron-builder"
},
"dependencies": {
+ "@homebridge/dbus-native": "0.6.0",
"@electron/remote": "^2.1.2",
"electron-is-dev": "2.0.0",
"electron-store": "8.2.0",
diff --git a/yarn.lock b/yarn.lock
index 3fe93d2..ea11a3c 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -119,6 +119,29 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.0.0.tgz#1a9e4b4c96d8c7886e0110ed310a0135144a1691"
integrity sha512-RThY/MnKrhubF6+s1JflwUjPEsnCEmYCWwqa/aRISKWNXGZ9epUwft4bUMM35SdKF9xvBrLydAM1RDHd1Z//ZQ==
+"@homebridge/dbus-native@0.6.0":
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/@homebridge/dbus-native/-/dbus-native-0.6.0.tgz#25052dd03216b977298e4c9db19b7aeb1d2363f4"
+ integrity sha512-xObqQeYHTXmt6wsfj10+krTo4xbzR9BgUfX2aQ+edDC9nc4ojfzLScfXCh3zluAm6UCowKw+AFfXn6WLWUOPkg==
+ dependencies:
+ "@homebridge/long" "^5.2.1"
+ "@homebridge/put" "^0.0.8"
+ event-stream "^4.0.1"
+ hexy "^0.3.5"
+ minimist "^1.2.6"
+ safe-buffer "^5.1.2"
+ xml2js "^0.6.2"
+
+"@homebridge/long@^5.2.1":
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/@homebridge/long/-/long-5.2.1.tgz#1c7568775b78e1a0fd75a7b3fa7a995f0388ab37"
+ integrity sha512-i5Df8R63XNPCn+Nj1OgAoRdw9e+jHUQb3CNUbvJneI2iu3j4+OtzQj+5PA1Ce+747NR1SPqZSvyvD483dOT3AA==
+
+"@homebridge/put@^0.0.8":
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/@homebridge/put/-/put-0.0.8.tgz#4b8b99f2c4d58bc762718863699df2c5bc0b4b8a"
+ integrity sha512-mwxLHHqKebOmOSU0tsPEWQSBHGApPhuaqtNpCe7U+AMdsduweANiu64E9SXXUtdpyTjsOpgSMLhD1+kbLHD2gA==
+
"@humanwhocodes/config-array@^0.12.3":
version "0.12.3"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.12.3.tgz#a6216d90f81a30bedd1d4b5d799b47241f318072"
@@ -795,6 +818,11 @@ dotenv@^9.0.2:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05"
integrity sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==
+duplexer@^0.1.1, duplexer@~0.1.1:
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
+ integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
+
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
@@ -1012,6 +1040,19 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+event-stream@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-4.0.1.tgz#4092808ec995d0dd75ea4580c1df6a74db2cde65"
+ integrity sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA==
+ dependencies:
+ duplexer "^0.1.1"
+ from "^0.1.7"
+ map-stream "0.0.7"
+ pause-stream "^0.0.11"
+ split "^1.0.1"
+ stream-combiner "^0.2.2"
+ through "^2.3.8"
+
extract-zip@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
@@ -1116,6 +1157,11 @@ form-data@^4.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
+from@^0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
+ integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==
+
fs-extra@^10.0.0, fs-extra@^10.1.0:
version "10.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
@@ -1302,6 +1348,11 @@ hasown@^2.0.0:
dependencies:
function-bind "^1.1.2"
+hexy@^0.3.5:
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/hexy/-/hexy-0.3.5.tgz#adcd5ee47d66aca3581d771743a509a5176e45f9"
+ integrity sha512-UCP7TIZPXz5kxYJnNOym+9xaenxCLor/JyhKieo8y8/bJWunGh9xbhy3YrgYJUQ87WwfXGm05X330DszOfINZw==
+
hosted-git-info@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224"
@@ -1585,6 +1636,11 @@ lucid-log@^0.0.3:
dependencies:
chalk "^4.1.2"
+map-stream@0.0.7:
+ version "0.0.7"
+ resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8"
+ integrity sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ==
+
matcher@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/matcher/-/matcher-3.0.0.tgz#bd9060f4c5b70aa8041ccc6f80368760994f30ca"
@@ -1821,6 +1877,13 @@ path-scurry@^1.10.2:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
+pause-stream@^0.0.11:
+ version "0.0.11"
+ resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445"
+ integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==
+ dependencies:
+ through "~2.3"
+
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
@@ -1951,6 +2014,11 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
+safe-buffer@^5.1.2:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
"safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
@@ -1963,6 +2031,11 @@ sanitize-filename@^1.6.3:
dependencies:
truncate-utf8-bytes "^1.0.0"
+sax@>=0.6.0:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f"
+ integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==
+
sax@^1.2.4:
version "1.3.0"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
@@ -2043,6 +2116,13 @@ source-map@^0.6.0:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+split@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9"
+ integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==
+ dependencies:
+ through "2"
+
sprintf-js@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
@@ -2053,6 +2133,14 @@ stat-mode@^1.0.0:
resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-1.0.0.tgz#68b55cb61ea639ff57136f36b216a291800d1465"
integrity sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==
+stream-combiner@^0.2.2:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858"
+ integrity sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ==
+ dependencies:
+ duplexer "~0.1.1"
+ through "~2.3.4"
+
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
@@ -2129,6 +2217,11 @@ text-table@^0.2.0:
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
+through@2, through@^2.3.8, through@~2.3, through@~2.3.4:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+
tmp-promise@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7"
@@ -2241,11 +2334,24 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+xml2js@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499"
+ integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==
+ dependencies:
+ sax ">=0.6.0"
+ xmlbuilder "~11.0.0"
+
xmlbuilder@>=11.0.1, xmlbuilder@^15.1.1:
version "15.1.1"
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5"
integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==
+xmlbuilder@~11.0.0:
+ version "11.0.1"
+ resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3"
+ integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==
+
y18n@^5.0.5:
version "5.0.8"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"