mirror of
https://github.com/keeweb/keeweb.git
synced 2024-06-26 07:39:04 +02:00
Merge branch 'release-1.14'
This commit is contained in:
commit
dae3d57d1e
20
Gruntfile.js
20
Gruntfile.js
|
@ -61,14 +61,11 @@ module.exports = function(grunt) {
|
||||||
dest: 'tmp/index.html',
|
dest: 'tmp/index.html',
|
||||||
nonull: true
|
nonull: true
|
||||||
},
|
},
|
||||||
'html-dist': {
|
'content-dist': {
|
||||||
src: 'tmp/app.html',
|
cwd: 'app/content/',
|
||||||
dest: 'dist/index.html',
|
src: '**',
|
||||||
nonull: true
|
dest: 'dist/',
|
||||||
},
|
expand: true,
|
||||||
'404-dist': {
|
|
||||||
src: 'app/404.html',
|
|
||||||
dest: 'dist/404.html',
|
|
||||||
nonull: true
|
nonull: true
|
||||||
},
|
},
|
||||||
favicon: {
|
favicon: {
|
||||||
|
@ -194,7 +191,7 @@ module.exports = function(grunt) {
|
||||||
},
|
},
|
||||||
app: {
|
app: {
|
||||||
src: 'tmp/app.html',
|
src: 'tmp/app.html',
|
||||||
dest: 'tmp/app.html'
|
dest: 'dist/app.html'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
htmlmin: {
|
htmlmin: {
|
||||||
|
@ -270,7 +267,10 @@ module.exports = function(grunt) {
|
||||||
sha: 'dev'
|
sha: 'dev'
|
||||||
}),
|
}),
|
||||||
publicPath: '/',
|
publicPath: '/',
|
||||||
contentBase: path.resolve(__dirname, 'tmp'),
|
contentBase: [
|
||||||
|
path.resolve(__dirname, 'tmp'),
|
||||||
|
path.resolve(__dirname, 'app/content')
|
||||||
|
],
|
||||||
progress: false
|
progress: false
|
||||||
},
|
},
|
||||||
js: {
|
js: {
|
||||||
|
|
16
app/content/oauth-result/dropbox.html
Normal file
16
app/content/oauth-result/dropbox.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>KeeWeb</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
window.opener.postMessage(
|
||||||
|
{ storage: 'dropbox', search: location.search },
|
||||||
|
window.location.origin
|
||||||
|
);
|
||||||
|
window.close();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
16
app/content/oauth-result/gdrive.html
Normal file
16
app/content/oauth-result/gdrive.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>KeeWeb</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
window.opener.postMessage(
|
||||||
|
{ storage: 'gdrive', search: location.search },
|
||||||
|
window.location.origin
|
||||||
|
);
|
||||||
|
window.close();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
16
app/content/oauth-result/onedrive.html
Normal file
16
app/content/oauth-result/onedrive.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<title>KeeWeb</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
window.opener.postMessage(
|
||||||
|
{ storage: 'onedrive', search: location.search },
|
||||||
|
window.location.origin
|
||||||
|
);
|
||||||
|
window.close();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -5,7 +5,6 @@ import { AppRightsChecker } from 'comp/app/app-rights-checker';
|
||||||
import { ExportApi } from 'comp/app/export-api';
|
import { ExportApi } from 'comp/app/export-api';
|
||||||
import { SingleInstanceChecker } from 'comp/app/single-instance-checker';
|
import { SingleInstanceChecker } from 'comp/app/single-instance-checker';
|
||||||
import { Updater } from 'comp/app/updater';
|
import { Updater } from 'comp/app/updater';
|
||||||
import { AuthReceiver } from 'comp/browser/auth-receiver';
|
|
||||||
import { FeatureTester } from 'comp/browser/feature-tester';
|
import { FeatureTester } from 'comp/browser/feature-tester';
|
||||||
import { FocusDetector } from 'comp/browser/focus-detector';
|
import { FocusDetector } from 'comp/browser/focus-detector';
|
||||||
import { IdleTracker } from 'comp/browser/idle-tracker';
|
import { IdleTracker } from 'comp/browser/idle-tracker';
|
||||||
|
@ -33,11 +32,6 @@ const ready = (Launcher && Launcher.ready) || $;
|
||||||
ready(() => {
|
ready(() => {
|
||||||
StartProfiler.milestone('document ready');
|
StartProfiler.milestone('document ready');
|
||||||
|
|
||||||
if (AuthReceiver.receive()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
StartProfiler.milestone('checking auth');
|
|
||||||
|
|
||||||
const appModel = new AppModel();
|
const appModel = new AppModel();
|
||||||
StartProfiler.milestone('creating app model');
|
StartProfiler.milestone('creating app model');
|
||||||
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { Features } from 'util/features';
|
|
||||||
|
|
||||||
const AuthReceiver = {
|
|
||||||
receive() {
|
|
||||||
if (!Features.isPopup) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const opener = window.opener || window.parent;
|
|
||||||
const message = this.urlArgsToMessage(window.location.href);
|
|
||||||
const hasKeys = Object.keys(message).filter(key => key !== 'config').length > 0;
|
|
||||||
if (!hasKeys) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
opener.postMessage(message, window.location.origin);
|
|
||||||
window.close();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
urlArgsToMessage(url) {
|
|
||||||
const message = {};
|
|
||||||
url.split(/[?#&]/g).forEach(part => {
|
|
||||||
const parts = part.split('=');
|
|
||||||
if (parts.length === 2) {
|
|
||||||
message[parts[0]] = decodeURIComponent(parts[1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export { AuthReceiver };
|
|
|
@ -261,8 +261,7 @@ class StorageBase {
|
||||||
if (redirectUrl.lastIndexOf('file:', 0) === 0) {
|
if (redirectUrl.lastIndexOf('file:', 0) === 0) {
|
||||||
redirectUrl = Links.WebApp;
|
redirectUrl = Links.WebApp;
|
||||||
}
|
}
|
||||||
redirectUrl = redirectUrl.split('?')[0];
|
return new URL(`oauth-result/${this.name}.html`, redirectUrl).href;
|
||||||
return redirectUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_oauthAuthorize(callback) {
|
_oauthAuthorize(callback) {
|
||||||
|
@ -284,7 +283,7 @@ class StorageBase {
|
||||||
|
|
||||||
let listener;
|
let listener;
|
||||||
if (Features.isDesktop) {
|
if (Features.isDesktop) {
|
||||||
listener = StorageOAuthListener.listen();
|
listener = StorageOAuthListener.listen(this.name);
|
||||||
session.redirectUri = listener.redirectUri;
|
session.redirectUri = listener.redirectUri;
|
||||||
} else {
|
} else {
|
||||||
session.redirectUri = this._getOauthRedirectUrl();
|
session.redirectUri = this._getOauthRedirectUrl();
|
||||||
|
@ -334,15 +333,27 @@ class StorageBase {
|
||||||
if (e.origin !== location.origin) {
|
if (e.origin !== location.origin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.data && e.data.error) {
|
if (!e.data || !e.data.storage || !e.data.search) {
|
||||||
this.logger.error('OAuth error', e.data.error, e.data.error_description);
|
this.logger.debug('Skipped empty OAuth message', e.data);
|
||||||
callback('OAuth: ' + e.data.error);
|
return;
|
||||||
} else if (e.data && e.data.code) {
|
}
|
||||||
|
if (e.data.storage !== this.name) {
|
||||||
|
this.logger.debug('Skipped OAuth message for another storage', e.data.storage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = {};
|
||||||
|
for (const [key, value] of new URLSearchParams(e.data.search).entries()) {
|
||||||
|
data[key] = value;
|
||||||
|
}
|
||||||
|
if (data.error) {
|
||||||
|
this.logger.error('OAuth error', data.error, data.error_description);
|
||||||
|
callback('OAuth: ' + data.error);
|
||||||
|
} else if (data.code) {
|
||||||
Events.off('popup-closed', popupClosed);
|
Events.off('popup-closed', popupClosed);
|
||||||
window.removeEventListener('message', windowMessage);
|
window.removeEventListener('message', windowMessage);
|
||||||
this._oauthCodeReceived(e.data, session, callback);
|
this._oauthCodeReceived(data, session, callback);
|
||||||
} else {
|
} else {
|
||||||
this.logger.debug('Skipped OAuth message', e.data);
|
this.logger.debug('Skipped OAuth message', data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Events.on('popup-closed', popupClosed);
|
Events.on('popup-closed', popupClosed);
|
||||||
|
|
|
@ -9,7 +9,7 @@ const logger = new Logger('storage-oauth-listener');
|
||||||
const StorageOAuthListener = {
|
const StorageOAuthListener = {
|
||||||
server: null,
|
server: null,
|
||||||
|
|
||||||
listen() {
|
listen(storageName) {
|
||||||
if (this.server) {
|
if (this.server) {
|
||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,17 @@ const StorageOAuthListener = {
|
||||||
});
|
});
|
||||||
|
|
||||||
const http = Launcher.req('http');
|
const http = Launcher.req('http');
|
||||||
|
let resultHandled = false;
|
||||||
const server = http.createServer((req, resp) => {
|
const server = http.createServer((req, resp) => {
|
||||||
resp.writeHead(200, 'OK', {
|
resp.writeHead(200, 'OK', {
|
||||||
'Content-Type': 'text/plain; charset=UTF-8'
|
'Content-Type': 'text/plain; charset=UTF-8'
|
||||||
});
|
});
|
||||||
resp.end(Locale.appBrowserAuthComplete);
|
resp.end(Locale.appBrowserAuthComplete);
|
||||||
this.handleResult(req.url, listener);
|
if (!resultHandled) {
|
||||||
|
this.stop();
|
||||||
|
this.handleResult(req.url, listener);
|
||||||
|
resultHandled = true;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const port = DefaultPort;
|
const port = DefaultPort;
|
||||||
|
@ -43,7 +48,7 @@ const StorageOAuthListener = {
|
||||||
listener.emit('ready');
|
listener.emit('ready');
|
||||||
});
|
});
|
||||||
|
|
||||||
listener.redirectUri = `http://localhost:${port}/oauth-result`;
|
listener.redirectUri = `http://localhost:${port}/oauth-result/${storageName}.html`;
|
||||||
return listener;
|
return listener;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -55,9 +60,12 @@ const StorageOAuthListener = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handleResult(url, listener) {
|
handleResult(url, listener) {
|
||||||
|
url = new URL(url, listener.redirectUri);
|
||||||
|
if (url.origin + url.pathname !== listener.redirectUri) {
|
||||||
|
logger.info('Skipped result', url, listener.redirectUri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
logger.info('OAuth result with code received');
|
logger.info('OAuth result with code received');
|
||||||
this.stop();
|
|
||||||
url = new URL(url, 'http://localhost');
|
|
||||||
const state = url.searchParams.get('state');
|
const state = url.searchParams.get('state');
|
||||||
const code = url.searchParams.get('code');
|
const code = url.searchParams.get('code');
|
||||||
listener.emit('result', { state, code });
|
listener.emit('result', { state, code });
|
||||||
|
|
2
desktop/package-lock.json
generated
2
desktop/package-lock.json
generated
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "KeeWeb",
|
"name": "KeeWeb",
|
||||||
"version": "1.14.1",
|
"version": "1.14.2",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "KeeWeb",
|
"name": "KeeWeb",
|
||||||
"version": "1.14.1",
|
"version": "1.14.2",
|
||||||
"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",
|
||||||
|
|
|
@ -12,8 +12,7 @@ module.exports = function(grunt) {
|
||||||
'inline',
|
'inline',
|
||||||
'htmlmin',
|
'htmlmin',
|
||||||
'csp-hashes',
|
'csp-hashes',
|
||||||
'copy:html-dist',
|
'copy:content-dist',
|
||||||
'copy:404-dist',
|
|
||||||
'string-replace:service-worker',
|
'string-replace:service-worker',
|
||||||
'string-replace:manifest',
|
'string-replace:manifest',
|
||||||
'copy:dist-icons',
|
'copy:dist-icons',
|
||||||
|
|
1438
package-lock.json
generated
1438
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "keeweb",
|
"name": "keeweb",
|
||||||
"version": "1.14.1",
|
"version": "1.14.2",
|
||||||
"description": "Free cross-platform password manager compatible with KeePass",
|
"description": "Free cross-platform password manager compatible with KeePass",
|
||||||
"main": "Gruntfile.js",
|
"main": "Gruntfile.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -10,10 +10,10 @@
|
||||||
"url": "https://github.com/keeweb/keeweb"
|
"url": "https://github.com/keeweb/keeweb"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/core": "^7.9.0",
|
"@babel/core": "^7.9.6",
|
||||||
"@babel/plugin-external-helpers": "^7.8.3",
|
"@babel/plugin-external-helpers": "^7.8.3",
|
||||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||||
"@babel/preset-env": "^7.9.5",
|
"@babel/preset-env": "^7.9.6",
|
||||||
"adm-zip": "^0.4.14",
|
"adm-zip": "^0.4.14",
|
||||||
"argon2-browser": "1.13.0",
|
"argon2-browser": "1.13.0",
|
||||||
"autoprefixer": "^9.7.6",
|
"autoprefixer": "^9.7.6",
|
||||||
|
@ -26,11 +26,11 @@
|
||||||
"bourbon": "^7.0.0",
|
"bourbon": "^7.0.0",
|
||||||
"chai": "^4.2.0",
|
"chai": "^4.2.0",
|
||||||
"cross-env": "^7.0.2",
|
"cross-env": "^7.0.2",
|
||||||
"dompurify": "^2.0.8",
|
"dompurify": "^2.0.10",
|
||||||
"electron": "^8.2.3",
|
"electron": "^8.2.5",
|
||||||
"electron-builder": "^22.5.1",
|
"electron-builder": "^22.6.0",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^6.8.0",
|
||||||
"eslint-config-prettier": "^6.10.1",
|
"eslint-config-prettier": "^6.11.0",
|
||||||
"eslint-config-standard": "^14.1.1",
|
"eslint-config-standard": "^14.1.1",
|
||||||
"eslint-plugin-import": "^2.20.2",
|
"eslint-plugin-import": "^2.20.2",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
@ -64,12 +64,12 @@
|
||||||
"kdbxweb": "1.6.0",
|
"kdbxweb": "1.6.0",
|
||||||
"load-grunt-tasks": "5.1.0",
|
"load-grunt-tasks": "5.1.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"marked": "^0.8.2",
|
"marked": "^1.0.0",
|
||||||
"mini-css-extract-plugin": "^0.9.0",
|
"mini-css-extract-plugin": "^0.9.0",
|
||||||
"mocha": "^7.1.1",
|
"mocha": "^7.1.2",
|
||||||
"morphdom": "^2.5.12",
|
"morphdom": "^2.6.0",
|
||||||
"node-sass": "^4.13.1",
|
"node-sass": "^4.14.0",
|
||||||
"node-stream-zip": "1.9.1",
|
"node-stream-zip": "1.10.1",
|
||||||
"normalize.css": "8.0.1",
|
"normalize.css": "8.0.1",
|
||||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||||
"pikaday": "1.8.0",
|
"pikaday": "1.8.0",
|
||||||
|
@ -84,16 +84,16 @@
|
||||||
"string-replace-webpack-plugin": "0.1.3",
|
"string-replace-webpack-plugin": "0.1.3",
|
||||||
"strip-sourcemap-loader": "0.0.1",
|
"strip-sourcemap-loader": "0.0.1",
|
||||||
"sumchecker": "^3.0.1",
|
"sumchecker": "^3.0.1",
|
||||||
"terser-webpack-plugin": "^2.3.5",
|
"terser-webpack-plugin": "^3.0.0",
|
||||||
"time-grunt": "2.0.0",
|
"time-grunt": "2.0.0",
|
||||||
"url-loader": "^4.1.0",
|
"url-loader": "^4.1.0",
|
||||||
"webpack": "^4.42.1",
|
"webpack": "^4.43.0",
|
||||||
"webpack-bundle-analyzer": "^3.7.0",
|
"webpack-bundle-analyzer": "^3.7.0",
|
||||||
"webpack-dev-server": "^3.10.3"
|
"webpack-dev-server": "^3.10.3"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"grunt-appdmg": "github:keeweb/grunt-appdmg#874ad83",
|
"grunt-appdmg": "github:keeweb/grunt-appdmg#874ad83",
|
||||||
"keytar": "^5.5.0"
|
"keytar": "^5.6.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "grunt",
|
"start": "grunt",
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
Release notes
|
Release notes
|
||||||
-------------
|
-------------
|
||||||
|
##### v1.14.2 (2020-05-04)
|
||||||
|
`-` distinct redirect URIs for storage providers
|
||||||
|
|
||||||
##### v1.14.1 (2020-05-02)
|
##### v1.14.1 (2020-05-02)
|
||||||
`-` fix #1478: fixed proxy issues with storage providers
|
`-` fix #1478: fixed proxy issues with storage providers
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user