Merge branch 'master' of github.com:Aetherinox/keeweb

This commit is contained in:
Aetherinox 2024-04-04 17:18:43 -07:00
commit 0fd3690ec2
No known key found for this signature in database
GPG Key ID: CB5C4C30CD0D4028
19 changed files with 652 additions and 318 deletions

31
.github/workflows/verify.yaml vendored Normal file
View File

@ -0,0 +1,31 @@
name: Verify
on:
push:
pull_request:
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install npm modules
run: npm ci
- name: Lint
run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
cache: 'npm'
- name: Install npm modules
run: npm ci
- name: Test
run: npm test

View File

@ -1,44 +0,0 @@
name: Verify
on:
push:
pull_request:
workflow_dispatch:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: "Lint Checkout"
uses: actions/checkout@v3
- name: "Lint Setup NodeJS"
uses: actions/setup-node@v3
with:
node-version: '16'
- name: "Lint Install NPM Modules"
run: npm ci
- name: "Lint Run"
run: npm run lint
test:
needs:
- lint
runs-on: ubuntu-latest
steps:
- name: "Test Checkout"
uses: actions/checkout@v3
- name: "Test Setup NodeJS"
uses: actions/setup-node@v3
with:
node-version: '16'
- name: "Test Install NPM Modules"
run: npm ci
- name: "Test Run"
run: npm test

1
.nvmrc Normal file
View File

@ -0,0 +1 @@
v16.20.2

View File

@ -16,7 +16,8 @@ Donate: [OpenCollective](https://opencollective.com/keeweb#support), [GitHub](ht
## Status ## Status
The app is quite stable now. Basic stuff, as well as more advanced operations, should be rather reliable. The app is quite stable now. Basic stuff, as well as more advanced operations, should be rather reliable.
Looking for a new maintainer, see [#2022](https://github.com/keeweb/keeweb/issues/2022)
## Self-hosting ## Self-hosting

View File

@ -209,6 +209,10 @@ const YubiKey = {
complete: (err, stdout) => { complete: (err, stdout) => {
this.process = null; this.process = null;
if (window.debugYubiKey) {
logger.info('received codes', err, stdout);
}
if (this.aborted) { if (this.aborted) {
return callback('Aborted'); return callback('Aborted');
} }

View File

@ -37,4 +37,17 @@ const OneDriveApps = {
} }
}; };
export { DropboxApps, GDriveApps, OneDriveApps }; const MsTeamsApps = {
Local: {
id: '8fbe2245-13d5-446f-bedc-74c3b2e1f635'
},
Production: {
id: '8fbe2245-13d5-446f-bedc-74c3b2e1f635'
},
Desktop: {
id: '8fbe2245-13d5-446f-bedc-74c3b2e1f635',
secret: 'F02~HYaWs-~7MndJcVRtv9~h-50Brk_9ho'
}
};
export { DropboxApps, GDriveApps, OneDriveApps, MsTeamsApps };

View File

@ -90,10 +90,10 @@ const DefaultAppSettings = {
onedriveClientSecret: null, // custom OneDrive client secret onedriveClientSecret: null, // custom OneDrive client secret
onedriveTenantId: null, // custom OneDrive tenant id onedriveTenantId: null, // custom OneDrive tenant id
teams: true, // enable Teams integration msteams: false, // enable Microsoft Teams integration
teamsClientId: null, // custom Teams client id msteamsClientId: null, // custom Microsoft Teams client id
teamsClientSecret: null, // custom Teams client secret msteamsClientSecret: null, // custom Microsoft Teams client secret
teamsTenantId: null // custom Teams tenant id msteamsTenantId: null // custom Microsoft Teams tenant id
}; };
export { DefaultAppSettings }; export { DefaultAppSettings };

View File

@ -23,17 +23,14 @@ const Links = {
HaveIBeenPwnedPrivacy: 'https://haveibeenpwned.com/Passwords', HaveIBeenPwnedPrivacy: 'https://haveibeenpwned.com/Passwords',
ExtensionHelpForOtherBrowsers: ExtensionHelpForOtherBrowsers:
'https://github.com/keeweb/keeweb/wiki/Browser-AutoFill#other-browsers', 'https://github.com/keeweb/keeweb/wiki/Browser-AutoFill#other-browsers',
ExtensionHelpForKPXC:
'https://github.com/keeweb/keeweb/wiki/Browser-AutoFill#keepassxc-browser',
KWCForChrome: KWCForChrome:
'https://chrome.google.com/webstore/detail/keeweb-connect/pikpfmjfkekaeinceagbebpfkmkdlcjk', 'https://chrome.google.com/webstore/detail/keeweb-connect/pikpfmjfkekaeinceagbebpfkmkdlcjk',
KWCForFirefox: 'https://addons.mozilla.org/firefox/addon/keeweb-connect/', KWCForFirefox: 'https://addons.mozilla.org/firefox/addon/keeweb-connect/',
KWCForEdge: KWCForEdge:
'https://microsoftedge.microsoft.com/addons/detail/keewebconnect/nmggpehkjmeaeocmaijenpejbepckinm', 'https://microsoftedge.microsoft.com/addons/detail/keewebconnect/nmggpehkjmeaeocmaijenpejbepckinm',
KWCForSafari: 'https://apps.apple.com/app/keeweb-connect/id1565748094', KWCForSafari: 'https://apps.apple.com/app/keeweb-connect/id1565748094'
KPXCForChrome:
'https://chrome.google.com/webstore/detail/keepassxc-browser/oboonakemofpalcgghocfoadofidjkkk',
KPXCForFirefox: 'https://addons.mozilla.org/firefox/addon/keepassxc-browser/',
KPXCForEdge:
'https://microsoftedge.microsoft.com/addons/detail/keepassxcbrowser/pdffhmdngciaglkoonimfcmckehcpafo'
}; };
export { Links }; export { Links };

View File

@ -43,7 +43,7 @@
"dropbox": "Dropbox", "dropbox": "Dropbox",
"gdrive": "Google Drive", "gdrive": "Google Drive",
"onedrive": "OneDrive", "onedrive": "OneDrive",
"teams": "Microsoft Teams", "msteams": "Microsoft Teams",
"menuAllItems": "All Items", "menuAllItems": "All Items",
"menuColors": "Colors", "menuColors": "Colors",
"menuTrash": "Trash", "menuTrash": "Trash",

View File

@ -14,6 +14,7 @@
"or": "ou", "or": "ou",
"history": "historique", "history": "historique",
"template": "modèle", "template": "modèle",
"templates": "templates",
"notImplemented": "Non Implémenté", "notImplemented": "Non Implémenté",
"saveChanges": "Sauvegarder les modifications", "saveChanges": "Sauvegarder les modifications",
"discardChanges": "Annuler les modifications", "discardChanges": "Annuler les modifications",
@ -46,6 +47,7 @@
"menuColors": "Couleurs", "menuColors": "Couleurs",
"menuTrash": "Corbeille", "menuTrash": "Corbeille",
"menuSetGeneral": "Général", "menuSetGeneral": "Général",
"menuSetBrowser": "Navigateur",
"menuSetAbout": "À propos", "menuSetAbout": "À propos",
"menuSetDevices": "Appareils", "menuSetDevices": "Appareils",
"menuAlertNoTags": "Aucun tag", "menuAlertNoTags": "Aucun tag",
@ -60,7 +62,7 @@
"sysMenuServices": "Services", "sysMenuServices": "Services",
"sysMenuHide": "Cacher {}", "sysMenuHide": "Cacher {}",
"sysMenuHideOthers": "Cacher autres", "sysMenuHideOthers": "Cacher autres",
"sysMenuUnhide": "Montrer tous", "sysMenuUnhide": "Montrer tout",
"sysMenuQuit": "Quitter {}", "sysMenuQuit": "Quitter {}",
"sysMenuEdit": "Editer", "sysMenuEdit": "Editer",
"sysMenuUndo": "Annuler", "sysMenuUndo": "Annuler",
@ -80,6 +82,8 @@
"alertCopy": "Copier", "alertCopy": "Copier",
"alertClose": "Fermer", "alertClose": "Fermer",
"alertDoNotAsk": "Ne plus me le redemander", "alertDoNotAsk": "Ne plus me le redemander",
"alertAllow": "Autoriser",
"alertDeny": "Refuser",
"appBeta": "ATTENTION: version beta, aperçu seulement", "appBeta": "ATTENTION: version beta, aperçu seulement",
"footerOpen": "Ouvrir/Nouveau", "footerOpen": "Ouvrir/Nouveau",
"footerSyncError": "Erreur de synchronisation", "footerSyncError": "Erreur de synchronisation",
@ -139,6 +143,7 @@
"keyChangeMessageExpired": "La clé maître pour cette base de donnée est expirée. Merci de saisir une nouvelle clé.", "keyChangeMessageExpired": "La clé maître pour cette base de donnée est expirée. Merci de saisir une nouvelle clé.",
"keyChangeRepeatPassword": "Mot de passe, encore une fois", "keyChangeRepeatPassword": "Mot de passe, encore une fois",
"keyEnter": "Entrée", "keyEnter": "Entrée",
"keyEsc": "Esc",
"iconFavTitle": "Télécharger et utiliser le favicon du site web", "iconFavTitle": "Télécharger et utiliser le favicon du site web",
"iconSelCustom": "Sélectionner une icône personnalisée", "iconSelCustom": "Sélectionner une icône personnalisée",
"listEmptyTitle": "Vide", "listEmptyTitle": "Vide",
@ -267,6 +272,7 @@
"detMore": "plus", "detMore": "plus",
"detClickToAddField": "cliquez pour ajouter un nouveau champ", "detClickToAddField": "cliquez pour ajouter un nouveau champ",
"detMenuAddNewField": "Ajouter nouveau champ", "detMenuAddNewField": "Ajouter nouveau champ",
"detMenuAddNewWebsite": "Ajouter un autre site",
"detMenuShowEmpty": "Montrer les champs vides", "detMenuShowEmpty": "Montrer les champs vides",
"detMenuHideEmpty": "Cacher les champs vides", "detMenuHideEmpty": "Cacher les champs vides",
"detMenuAddField": "Ajouter {}", "detMenuAddField": "Ajouter {}",
@ -340,6 +346,7 @@
"autoTypeSelectionHintOpt": "Entrez seulement le compte", "autoTypeSelectionHintOpt": "Entrez seulement le compte",
"autoTypeSelectionHintShift": "Autres champs", "autoTypeSelectionHintShift": "Autres champs",
"autoTypeSelectionOtp": "code à usage unique", "autoTypeSelectionOtp": "code à usage unique",
"autoTypeUnlockMessage": "Déverrouiller pour saisir automatiquement",
"appSecWarn": "Non sécurisé !", "appSecWarn": "Non sécurisé !",
"appSecWarnBody1": "Vous avez chargé cette appli avec une connexion non sécurisée. Quelqu'un peut vous observer et voler vos mots de passe. Nous vous recommandons fortement d'arrêter cette connexion, à moins que vous ne compreniez exactement ce que vous faites.", "appSecWarnBody1": "Vous avez chargé cette appli avec une connexion non sécurisée. Quelqu'un peut vous observer et voler vos mots de passe. Nous vous recommandons fortement d'arrêter cette connexion, à moins que vous ne compreniez exactement ce que vous faites.",
"appSecWarnBody2": "Oui, votre base est chiffrée mais personne ne peut garantir que l'application n'a pas été modifiée avant d'arriver à vous.", "appSecWarnBody2": "Oui, votre base est chiffrée mais personne ne peut garantir que l'application n'a pas été modifiée avant d'arriver à vous.",
@ -614,6 +621,38 @@
"setPlTranslateLink": "traduire l'appli dans votre langue", "setPlTranslateLink": "traduire l'appli dans votre langue",
"setPlAutoUpdate": "Mise à jour automatique", "setPlAutoUpdate": "Mise à jour automatique",
"setPlLoadGallery": "Charger le catalogue", "setPlLoadGallery": "Charger le catalogue",
"setBrowserTitle": "Navigateur",
"setBrowserIntroDesktop": "KeeWeb peut entrer des mots de passe en utilisant la saisie automatique, cependant, une extension peut être un moyen plus pratique de le faire. KeeWeb prend en charge deux extensions de navigateur:",
"setBrowserIntroKeeWebConnect": "l'extension officielle KeeWeb est construite avec les fonctionnalités de KeeWeb, mais vous risquez de manquer certaines fonctionnalités avancées que l'on peut trouver dans l'autre extension.",
"setBrowserIntroKeePassXcBrowser": "cette extension a été développée pour KeePassXC, elle existe depuis un moment et est assez fiable. L'extension ne fait pas partie de KeeWeb et il peut y avoir des problèmes de compatibilité.",
"setBrowserIntroWeb": "Installez notre extension de navigateur pour remplir automatiquement les mots de passe de KeeWeb sur différentes pages. L'extension de navigateur se connectera à un onglet KeeWeb de votre navigateur pour récupérer les mots de passe. Cliquez ici pour télécharger l'extension:",
"setBrowserNotEnabled": "L'intégration du navigateur n'est pas activée, les extensions ne pourront pas se connecter à KeeWeb. Utilisez les cases à cocher ci-dessous pour l'activer:",
"setBrowserEnablePerBrowser": "Activer l'intégration dans le navigateur en cochant ci dessous:",
"setBrowserFocusIfLocked": "Ouvrir KeeWeb si le navigateur essaye de se connecter alors que aucun fichier n'est ouvert",
"setBrowserFocusIfEmpty": "Afficher la liste si aucune correspondance n'est trouvée avec l'URL",
"setBrowserOtherBrowsers": "Autres navigateurs",
"setBrowserExtensionFor": "pour {}",
"setBrowserExtensionNotSupported": "Non supporté",
"setBrowserExtensionHelp": "Comment installer ?",
"setBrowserExtensionInstall": "Installer l'application",
"setBrowserExtensionKPXCWarnHeader": "{} cessera de fonctionner",
"setBrowserExtensionKPXCWarnBody1": "Malheureusement, il n'est pas possible de connecter une extension à plusieurs applications. Si vous connectez l'extension à KeeWeb, nous remplacerons son association d'application, ce qui signifie que l'intégration avec {} cessera de fonctionner. Même si vous décochez cette case, l'association avec {} ne sera pas restaurée. Pour le faire fonctionner à nouveau, configurez l'intégration du navigateur dans les paramètres de {}.",
"setBrowserExtensionKPXCWarnBody2": "Configurer l'extension pour utiliser KeeWeb?",
"setBrowserSessions": "Sessions",
"setBrowserSessionsEmpty": "Aucune session connectée",
"setBrowserSessionsIntro": "Ces extensions sont connectées à KeeWeb",
"setBrowserSessionsActiveTooltip": "Session active",
"setBrowserSessionsActiveText": "Cette session est active. Elle peut échanger des données avec KeeWeb selon les permissions:",
"setBrowserSessionsInactiveTooltip": "session inactive",
"setBrowserSessionsInactiveText": "Cette session est inactive. L'extension est connectée à KeeWeb, cependant, elle n'a pas essayé d'échanger des données. Lorsque l'extension demande quelque chose, vous pourrez choisir ce que vous souhaitez partager.",
"setBrowserSessionsDeniedTooltip": "Accès interdit",
"setBrowserSessionsDeniedText": "Cette session est inactive. L'extension est connectée à KeeWeb mais vous avez refusé l'accès aux données.",
"setBrowserSessionsConnectedDate": "Connecté",
"setBrowserSessionsTerminate": "Clôturer la session",
"setBrowserSessionsAccessToFiles": "Autoriser l'accès aux fichiers",
"setBrowserSessionsNoFileAccess": "L'extension n'a accès à aucun fichier, elle ne pourra pas récupérer les mots de passe de KeeWeb.",
"setBrowserSessionsPasswordsRead": "Accès aux mot de passe",
"setBrowserSessionsPasswordsWritten": "Mots de passe enregistrés",
"setDevicesTitle": "Appareils", "setDevicesTitle": "Appareils",
"setDevicesEnableUsb": "Autoriser les interactions avec les appareils USB", "setDevicesEnableUsb": "Autoriser les interactions avec les appareils USB",
"setDevicesYubiKeyIntro": "Il est recommandé de lire {} avant d'utiliser une YubiKey.", "setDevicesYubiKeyIntro": "Il est recommandé de lire {} avant d'utiliser une YubiKey.",
@ -648,12 +687,12 @@
"setHelpProblems2": "ou {}", "setHelpProblems2": "ou {}",
"setHelpOpenIssue": "faire connaître le problème sur GitHub", "setHelpOpenIssue": "faire connaître le problème sur GitHub",
"setHelpContactLink": "contactez le développeur directement", "setHelpContactLink": "contactez le développeur directement",
"setHelpAppInfo": "Information", "setHelpAppInfo": "Informations",
"setHelpOtherPlatforms": "Autres plateformes", "setHelpOtherPlatforms": "Autres plateformes",
"setHelpDesktopApps": "Applis Desktop", "setHelpDesktopApps": "Applis Desktop",
"setHelpWebApp": "Appli web", "setHelpWebApp": "Appli web",
"setHelpUpdates": "Mises à jour", "setHelpUpdates": "Mises à jour",
"setHelpTwitter": "Appli twitter", "setHelpTwitter": "Twitter",
"dropboxSetupDesc": "Une configuration particulière est nécessaire pour utiliser Dropbox dans une application auto-hébergée. Merci de créer votre propre application Dropbox et d'inscrire sa clé ci-dessous.", "dropboxSetupDesc": "Une configuration particulière est nécessaire pour utiliser Dropbox dans une application auto-hébergée. Merci de créer votre propre application Dropbox et d'inscrire sa clé ci-dessous.",
"dropboxAppKey": "Clé Dropbox", "dropboxAppKey": "Clé Dropbox",
"dropboxAppKeyDesc": "Copier la clé de votre appli Dropbox (Réglages développeur)", "dropboxAppKeyDesc": "Copier la clé de votre appli Dropbox (Réglages développeur)",
@ -669,6 +708,8 @@
"dropboxLinkFull": "Tout Dropbox ou n'importe quel dossier", "dropboxLinkFull": "Tout Dropbox ou n'importe quel dossier",
"dropboxLinkCustom": "Votre appli Dropbox", "dropboxLinkCustom": "Votre appli Dropbox",
"gdriveSharedWithMe": "Partagé avec moi", "gdriveSharedWithMe": "Partagé avec moi",
"gdriveSharedDrives": "Lecteurs partagés",
"gdriveTeamDrives": "Team drives",
"webdavSaveMethod": "Méthode de sauvegarde", "webdavSaveMethod": "Méthode de sauvegarde",
"webdavSaveMove": "Envoyer un fichier temporaire et le déplacer", "webdavSaveMove": "Envoyer un fichier temporaire et le déplacer",
"webdavSavePut": "Écraser le fichier kdbx avec PUT", "webdavSavePut": "Écraser le fichier kdbx avec PUT",
@ -697,5 +738,39 @@
"yubiKeyDisabledErrorHeader": "L'USB est désactivé", "yubiKeyDisabledErrorHeader": "L'USB est désactivé",
"yubiKeyDisabledErrorBody": "Yubikey est nécessaire pour ouvrir ce fichier, merci d'activer les appareils USB dans les paramètres", "yubiKeyDisabledErrorBody": "Yubikey est nécessaire pour ouvrir ce fichier, merci d'activer les appareils USB dans les paramètres",
"yubiKeyErrorWithCode": "Erreur Yubikey code {}.", "yubiKeyErrorWithCode": "Erreur Yubikey code {}.",
"bioOpenAuthPrompt": "ouvrir \"{}\"" "bioOpenAuthPrompt": "ouvrir \"{}\"",
"extensionErrorNoOpenFiles": "Aucun fichier ouvert",
"extensionErrorUserRejected": "La requête a été refusée",
"extensionErrorNoMatches": "Aucune correspondance",
"extensionErrorAlertDisplayed": "Impossible de poser une question maintenant car une autre boîte de dialogue est affichée, veuillez réessayer",
"extensionConnectHeader": "Échange de données avec l'extension",
"extensionConnectIntro": "Une extension de navigateur qui a pour nom {} essaie d'échanger des données avec KeeWeb.",
"extensionConnectUnknownActivity": "KeeWeb ne vérifie pas que l'application connectée est ce qu'elle prétend être. N'approuvez la demande que si vous en connaissez l'origine.",
"extensionConnectFiles": "Lors de cette session, autoriser l'accès à:",
"extensionConnectAllOtherFiles": "Tous les autres fichiers",
"extensionConnectAllFiles": "Tous les fichiers",
"extensionConnectAskGet": "Demandez avant d'envoyer les mots de passe à l'extension:",
"extensionConnectAskGetMultiple": "s'il y a plus d'une correspondance",
"extensionConnectAskGetAlways": "Toujours",
"extensionConnectAskSave": "Demandez avant d'enregistrer de nouveaux mots de passe dans KeeWeb:",
"extensionConnectAskSaveAlways": "Toujours",
"extensionConnectAskSaveAuto": "quand ce n'est pas possible de sauvegarder automatiquement",
"extensionConnectSettingsAreForSession": "Les paramètres que vous sélectionnez ici ne sont valides que pour la session en cours. Vous pouvez afficher et gérer les sessions dans les paramètres de KeeWeb.",
"extensionUnlockMessage": "Déverrouiller pour connecter l'extension du navigateur",
"extensionNewGroupHeader": "Nouveau groupe",
"extensionNewGroupBody": "{} essaye de créer un nouveau groupe. Autoriser cela?",
"extensionNewGroupPath": "Dossier du groupe",
"extensionNewGroupFile": "Ce groupe sera créé dans:",
"extensionSaveEntryHeader": "Sauvegarder mot de passe",
"extensionSaveEntryBody": "{} essaye de sauvegarder un mot de passe. Autoriser cela?",
"extensionSaveEntryAuto": "Sauvegarder les autres mots de passe automatiquement lors de cette session",
"extensionSaveEntryNewGroup": "nouveau groupe",
"extensionSelectPasswordFor": "Sélectionner un mot de passe pour {}",
"selectEntryHeader": "Sélectionner une entrée",
"selectEntryEnterHint": "Utiliser la ligne sélectionnée",
"selectEntryTypingHint": "Ecrire pour filtrer",
"selectEntryContains": "Contient le texte",
"selectEntrySubdomains": "Sous-domaines",
"selectEntryFieldHeader": "Sélectionnez un champ",
"selectEntryFieldTouch": "Appuyez sur le bouton de votre appareil pour générer un code à usage unique."
} }

View File

@ -1,5 +1,5 @@
import { StorageBase } from 'storage/storage-base'; import { StorageBase } from 'storage/storage-base';
import { TeamsApps } from 'const/cloud-storage-apps'; import { MsTeamsApps } from 'const/cloud-storage-apps';
import { Features } from 'util/features'; import { Features } from 'util/features';
// https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow // https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
@ -12,7 +12,7 @@ import { Features } from 'util/features';
// https://graph.microsoft.com/v1.0/groups/{group id}/drive/root/children // https://graph.microsoft.com/v1.0/groups/{group id}/drive/root/children
class StorageTeams extends StorageBase { class StorageTeams extends StorageBase {
name = 'teams'; name = 'msteams';
enabled = true; enabled = true;
uipos = 50; uipos = 50;
icon = 'user-friends'; icon = 'user-friends';
@ -34,7 +34,6 @@ class StorageTeams extends StorageBase {
} }
genUrl(path) { genUrl(path) {
// console.warn('genUrl', path);
if (!path) { if (!path) {
const groupId = null; const groupId = null;
const dir = null; const dir = null;
@ -212,17 +211,11 @@ class StorageTeams extends StorageBase {
this.logger.debug('List', dir); this.logger.debug('List', dir);
const ts = this.logger.ts(); const ts = this.logger.ts();
// console.warn('dir ', dir);
const urlParts = this.genUrl(dir); const urlParts = this.genUrl(dir);
const groupId = urlParts[0]; const groupId = urlParts[0];
dir = urlParts[1]; dir = urlParts[1];
const urlPath = groupId ? (dir ? ':/children' : '/drive/root/children') : ''; const urlPath = groupId ? (dir ? ':/children' : '/drive/root/children') : '';
const url = urlParts[2] + urlPath; const url = urlParts[2] + urlPath;
// console.warn('urlParts', urlParts);
// console.warn('groupId ', groupId);
// console.warn('dir ', dir);
// console.warn('urlPath ', urlPath);
// console.warn('url ', url);
const self = this; const self = this;
self._groupId = groupId; self._groupId = groupId;
@ -337,17 +330,17 @@ class StorageTeams extends StorageBase {
} }
_getOAuthConfig() { _getOAuthConfig() {
let clientId = this.appSettings.teamsClientId; let clientId = this.appSettings.msteamsClientId;
let clientSecret = this.appSettings.teamsClientSecret; let clientSecret = this.appSettings.msteamsClientSecret;
let tenant = this.appSettings.teamsTenantId; let tenant = this.appSettings.msteamsTenantId;
if (!clientId) { if (!clientId) {
if (Features.isDesktop) { if (Features.isDesktop) {
({ id: clientId, secret: clientSecret, tenantId: tenant } = TeamsApps.Desktop); ({ id: clientId, secret: clientSecret, tenantId: tenant } = MsTeamsApps.Desktop);
} else if (Features.isLocal) { } else if (Features.isLocal) {
({ id: clientId, secret: clientSecret, tenantId: tenant } = TeamsApps.Local); ({ id: clientId, secret: clientSecret, tenantId: tenant } = MsTeamsApps.Local);
} else { } else {
({ id: clientId, secret: clientSecret, tenantId: tenant } = TeamsApps.Production); ({ id: clientId, secret: clientSecret, tenantId: tenant } = MsTeamsApps.Production);
} }
} }
tenant = tenant || 'common'; tenant = tenant || 'common';

View File

@ -18,7 +18,7 @@ const ThirdPartyStorage = {
dropbox: new StorageDropbox(), dropbox: new StorageDropbox(),
gdrive: new StorageGDrive(), gdrive: new StorageGDrive(),
onedrive: new StorageOneDrive(), onedrive: new StorageOneDrive(),
teams: new StorageTeams(), msteams: new StorageTeams(),
webdav: new StorageWebDav() webdav: new StorageWebDav()
}; };

View File

@ -72,6 +72,9 @@ class SettingsBrowserView extends View {
enabled: !!AppSettingsModel[`extensionEnabled${ext.alias}${browser}`], enabled: !!AppSettingsModel[`extensionEnabled${ext.alias}${browser}`],
installUrl: Links[`${ext.alias}For${browser}`] installUrl: Links[`${ext.alias}For${browser}`]
}; };
if (ext.alias === 'KPXC') {
ext.manualUrl = Links.ExtensionHelpForKPXC;
}
if (!ext.installUrl) { if (!ext.installUrl) {
if (browser === 'Other') { if (browser === 'Other') {
ext.helpUrl = Links.ExtensionHelpForOtherBrowsers; ext.helpUrl = Links.ExtensionHelpForOtherBrowsers;

View File

@ -24,33 +24,42 @@
<td>{{perBrowser.browserName}}</td> <td>{{perBrowser.browserName}}</td>
{{#each perBrowser.extensions as |setting|}} {{#each perBrowser.extensions as |setting|}}
<td> <td>
{{#if setting.supported}} {{#if setting.manualUrl}}
<input type="checkbox" <a href="{{setting.manualUrl}}" target="_blank" rel="noreferrer"
class="check-enable-for-browser" class="settings__browser-extension-link icon-link"
{{#if setting.enabled}}checked{{/if}} title="{{res 'setBrowserExtensionHelp'}}"
id="check-enable-{{setting.alias}}-for-{{perBrowser.browser}}" >
data-browser="{{perBrowser.browser}}" <i class="fa fa-info-circle"></i>
data-extension="{{setting.alias}}" /> </a>
<label for="check-enable-{{setting.alias}}-for-{{perBrowser.browser}}"></label>
{{else}} {{else}}
<i class="fa fa-times muted-color" title="{{res 'setBrowserExtensionNotSupported'}}"></i> {{#if setting.supported}}
{{/if}} <input type="checkbox"
{{#if setting.enabled}} class="check-enable-for-browser"
{{#if setting.helpUrl}} {{#if setting.enabled}}checked{{/if}}
<a href="{{setting.helpUrl}}" target="_blank" rel="noreferrer" id="check-enable-{{setting.alias}}-for-{{perBrowser.browser}}"
class="settings__browser-extension-link icon-link" data-browser="{{perBrowser.browser}}"
title="{{res 'setBrowserExtensionHelp'}}" data-extension="{{setting.alias}}" />
> <label for="check-enable-{{setting.alias}}-for-{{perBrowser.browser}}"></label>
<i class="fa fa-info-circle"></i> {{else}}
</a> <i class="fa fa-times muted-color" title="{{res 'setBrowserExtensionNotSupported'}}"></i>
{{/if}} {{/if}}
{{#if setting.installUrl}} {{#if setting.enabled}}
<a href="{{setting.installUrl}}" target="_blank" rel="noreferrer" {{#if setting.helpUrl}}
class="settings__browser-extension-link icon-link" <a href="{{setting.helpUrl}}" target="_blank" rel="noreferrer"
title="{{res 'setBrowserExtensionInstall'}}" class="settings__browser-extension-link icon-link"
> title="{{res 'setBrowserExtensionHelp'}}"
<i class="fa fa-download"></i> >
</a> <i class="fa fa-info-circle"></i>
</a>
{{/if}}
{{#if setting.installUrl}}
<a href="{{setting.installUrl}}" target="_blank" rel="noreferrer"
class="settings__browser-extension-link icon-link"
title="{{res 'setBrowserExtensionInstall'}}"
>
<i class="fa fa-download"></i>
</a>
{{/if}}
{{/if}} {{/if}}
{{/if}} {{/if}}
</td> </td>

View File

@ -7,9 +7,7 @@ module.exports = function (grunt) {
const puppeteer = require('puppeteer'); const puppeteer = require('puppeteer');
(async function () { (async function () {
grunt.log.writeln('Running tests...'); grunt.log.writeln('Running tests...');
const fullPath = 'file://' + path.resolve(file); const fullPath = 'file://' + path.resolve(file);
const browser = await puppeteer.launch({ const browser = await puppeteer.launch({
headless: opt.headless, headless: opt.headless,
executablePath: process.env.CHROME_BIN || null, executablePath: process.env.CHROME_BIN || null,
@ -18,7 +16,6 @@ module.exports = function (grunt) {
grunt.log.writeln('puppeteer launched...'); grunt.log.writeln('puppeteer launched...');
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto(fullPath); await page.goto(fullPath);
async function check() { async function check() {
const result = await page.evaluate(() => { const result = await page.evaluate(() => {
const { output, done } = window; const { output, done } = window;

View File

@ -1,6 +1,6 @@
{ {
"name": "KeeWeb", "name": "KeeWeb",
"version": "1.18.6", "version": "1.18.7",
"description": "Free cross-platform password manager compatible with KeePass", "description": "Free cross-platform password manager compatible with KeePass",
"main": "main.js", "main": "main.js",
"homepage": "https://keeweb.info", "homepage": "https://keeweb.info",

View File

@ -398,7 +398,11 @@ function sendMessageToSocket(socket, message) {
const lengthBytes = Buffer.from(lengthBuf); const lengthBytes = Buffer.from(lengthBuf);
const data = Buffer.concat([lengthBytes, responseData]); const data = Buffer.concat([lengthBytes, responseData]);
socket.write(data); try {
socket.write(data);
} catch (e) {
logger.error(`Error writing to socket ${state.socketId}`, e);
}
} }
function sendToRenderer(event, socketId, data) { function sendToRenderer(event, socketId, data) {

665
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,12 @@
Release notes Release notes
------------- -------------
##### v1.18.7 (2021-07-18)
`+` added Microsoft Teams storage
`+` added a possibility to override tenant in Microsoft OneDrive
`!` disabled automatic installation of KeePassXC-Browser extension
`+` added an option to diagnose YubiKey code listing issues
`-` fix #1845: fixed a visible crash on socket write error
##### v1.18.6 (2021-05-19) ##### v1.18.6 (2021-05-19)
`-` fix #1824: saving KDBX3 files with compression disabled `-` fix #1824: saving KDBX3 files with compression disabled
`-` fix #1818: extension connection error if browser cannot be identified `-` fix #1818: extension connection error if browser cannot be identified