mirror of https://github.com/keeweb/keeweb
Merge branch 'master' into usb
# Conflicts: # app/scripts/app.js # package.json # release-notes.mdpull/1513/head
commit
aa5a9fc6d2
20
Gruntfile.js
20
Gruntfile.js
|
@ -61,14 +61,11 @@ module.exports = function(grunt) {
|
|||
dest: 'tmp/index.html',
|
||||
nonull: true
|
||||
},
|
||||
'html-dist': {
|
||||
src: 'tmp/app.html',
|
||||
dest: 'dist/index.html',
|
||||
nonull: true
|
||||
},
|
||||
'404-dist': {
|
||||
src: 'app/404.html',
|
||||
dest: 'dist/404.html',
|
||||
'content-dist': {
|
||||
cwd: 'app/content/',
|
||||
src: '**',
|
||||
dest: 'dist/',
|
||||
expand: true,
|
||||
nonull: true
|
||||
},
|
||||
favicon: {
|
||||
|
@ -194,7 +191,7 @@ module.exports = function(grunt) {
|
|||
},
|
||||
app: {
|
||||
src: 'tmp/app.html',
|
||||
dest: 'tmp/app.html'
|
||||
dest: 'dist/index.html'
|
||||
}
|
||||
},
|
||||
htmlmin: {
|
||||
|
@ -270,7 +267,10 @@ module.exports = function(grunt) {
|
|||
sha: 'dev'
|
||||
}),
|
||||
publicPath: '/',
|
||||
contentBase: path.resolve(__dirname, 'tmp'),
|
||||
contentBase: [
|
||||
path.resolve(__dirname, 'tmp'),
|
||||
path.resolve(__dirname, 'app/content')
|
||||
],
|
||||
progress: false
|
||||
},
|
||||
js: {
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -6,7 +6,6 @@ import { ExportApi } from 'comp/app/export-api';
|
|||
import { SingleInstanceChecker } from 'comp/app/single-instance-checker';
|
||||
import { Updater } from 'comp/app/updater';
|
||||
import { UsbListener } from 'comp/app/usb-listener';
|
||||
import { AuthReceiver } from 'comp/browser/auth-receiver';
|
||||
import { FeatureTester } from 'comp/browser/feature-tester';
|
||||
import { FocusDetector } from 'comp/browser/focus-detector';
|
||||
import { IdleTracker } from 'comp/browser/idle-tracker';
|
||||
|
@ -34,11 +33,6 @@ const ready = (Launcher && Launcher.ready) || $;
|
|||
ready(() => {
|
||||
StartProfiler.milestone('document ready');
|
||||
|
||||
if (AuthReceiver.receive()) {
|
||||
return;
|
||||
}
|
||||
StartProfiler.milestone('checking auth');
|
||||
|
||||
const appModel = new AppModel();
|
||||
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) {
|
||||
redirectUrl = Links.WebApp;
|
||||
}
|
||||
redirectUrl = redirectUrl.split('?')[0];
|
||||
return redirectUrl;
|
||||
return new URL(`oauth-result/${this.name}.html`, redirectUrl).href;
|
||||
}
|
||||
|
||||
_oauthAuthorize(callback) {
|
||||
|
@ -284,7 +283,7 @@ class StorageBase {
|
|||
|
||||
let listener;
|
||||
if (Features.isDesktop) {
|
||||
listener = StorageOAuthListener.listen();
|
||||
listener = StorageOAuthListener.listen(this.name);
|
||||
session.redirectUri = listener.redirectUri;
|
||||
} else {
|
||||
session.redirectUri = this._getOauthRedirectUrl();
|
||||
|
@ -334,15 +333,27 @@ class StorageBase {
|
|||
if (e.origin !== location.origin) {
|
||||
return;
|
||||
}
|
||||
if (e.data && e.data.error) {
|
||||
this.logger.error('OAuth error', e.data.error, e.data.error_description);
|
||||
callback('OAuth: ' + e.data.error);
|
||||
} else if (e.data && e.data.code) {
|
||||
if (!e.data || !e.data.storage || !e.data.search) {
|
||||
this.logger.debug('Skipped empty OAuth message', e.data);
|
||||
return;
|
||||
}
|
||||
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);
|
||||
window.removeEventListener('message', windowMessage);
|
||||
this._oauthCodeReceived(e.data, session, callback);
|
||||
this._oauthCodeReceived(data, session, callback);
|
||||
} else {
|
||||
this.logger.debug('Skipped OAuth message', e.data);
|
||||
this.logger.debug('Skipped OAuth message', data);
|
||||
}
|
||||
};
|
||||
Events.on('popup-closed', popupClosed);
|
||||
|
|
|
@ -9,7 +9,7 @@ const logger = new Logger('storage-oauth-listener');
|
|||
const StorageOAuthListener = {
|
||||
server: null,
|
||||
|
||||
listen() {
|
||||
listen(storageName) {
|
||||
if (this.server) {
|
||||
this.stop();
|
||||
}
|
||||
|
@ -20,12 +20,17 @@ const StorageOAuthListener = {
|
|||
});
|
||||
|
||||
const http = Launcher.req('http');
|
||||
let resultHandled = false;
|
||||
const server = http.createServer((req, resp) => {
|
||||
resp.writeHead(200, 'OK', {
|
||||
'Content-Type': 'text/plain; charset=UTF-8'
|
||||
});
|
||||
resp.end(Locale.appBrowserAuthComplete);
|
||||
this.handleResult(req.url, listener);
|
||||
if (!resultHandled) {
|
||||
this.stop();
|
||||
this.handleResult(req.url, listener);
|
||||
resultHandled = true;
|
||||
}
|
||||
});
|
||||
|
||||
const port = DefaultPort;
|
||||
|
@ -43,7 +48,7 @@ const StorageOAuthListener = {
|
|||
listener.emit('ready');
|
||||
});
|
||||
|
||||
listener.redirectUri = `http://localhost:${port}/oauth-result`;
|
||||
listener.redirectUri = `http://localhost:${port}/oauth-result/${storageName}.html`;
|
||||
return listener;
|
||||
},
|
||||
|
||||
|
@ -55,9 +60,12 @@ const StorageOAuthListener = {
|
|||
},
|
||||
|
||||
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');
|
||||
this.stop();
|
||||
url = new URL(url, 'http://localhost');
|
||||
const state = url.searchParams.get('state');
|
||||
const code = url.searchParams.get('code');
|
||||
listener.emit('result', { state, code });
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "KeeWeb",
|
||||
"version": "1.14.1",
|
||||
"version": "1.14.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "KeeWeb",
|
||||
"version": "1.14.1",
|
||||
"version": "1.14.2",
|
||||
"description": "Free cross-platform password manager compatible with KeePass",
|
||||
"main": "main.js",
|
||||
"homepage": "https://keeweb.info",
|
||||
|
|
|
@ -12,8 +12,7 @@ module.exports = function(grunt) {
|
|||
'inline',
|
||||
'htmlmin',
|
||||
'csp-hashes',
|
||||
'copy:html-dist',
|
||||
'copy:404-dist',
|
||||
'copy:content-dist',
|
||||
'string-replace:service-worker',
|
||||
'string-replace:manifest',
|
||||
'copy:dist-icons',
|
||||
|
|
File diff suppressed because it is too large
Load Diff
30
package.json
30
package.json
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "keeweb",
|
||||
"version": "1.14.1",
|
||||
"version": "1.14.2",
|
||||
"description": "Free cross-platform password manager compatible with KeePass",
|
||||
"main": "Gruntfile.js",
|
||||
"private": true,
|
||||
|
@ -10,10 +10,10 @@
|
|||
"url": "https://github.com/keeweb/keeweb"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.9.0",
|
||||
"@babel/core": "^7.9.6",
|
||||
"@babel/plugin-external-helpers": "^7.8.3",
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/preset-env": "^7.9.5",
|
||||
"@babel/preset-env": "^7.9.6",
|
||||
"@keeweb/keeweb-native-modules": "https://github.com/keeweb/keeweb-native-modules/releases/download/0.1.6/keeweb-native-modules.tgz",
|
||||
"adm-zip": "^0.4.14",
|
||||
"argon2-browser": "1.13.0",
|
||||
|
@ -27,11 +27,11 @@
|
|||
"bourbon": "^7.0.0",
|
||||
"chai": "^4.2.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"dompurify": "^2.0.8",
|
||||
"electron": "^8.2.3",
|
||||
"electron-builder": "^22.5.1",
|
||||
"dompurify": "^2.0.10",
|
||||
"electron": "^8.2.5",
|
||||
"electron-builder": "^22.6.0",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-prettier": "^6.10.1",
|
||||
"eslint-config-prettier": "^6.11.0",
|
||||
"eslint-config-standard": "^14.1.1",
|
||||
"eslint-plugin-import": "^2.20.2",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
|
@ -65,12 +65,12 @@
|
|||
"kdbxweb": "1.6.0",
|
||||
"load-grunt-tasks": "5.1.0",
|
||||
"lodash": "^4.17.15",
|
||||
"marked": "^0.8.2",
|
||||
"marked": "^1.0.0",
|
||||
"mini-css-extract-plugin": "^0.9.0",
|
||||
"mocha": "^7.1.1",
|
||||
"morphdom": "^2.5.12",
|
||||
"node-sass": "^4.13.1",
|
||||
"node-stream-zip": "1.9.1",
|
||||
"mocha": "^7.1.2",
|
||||
"morphdom": "^2.6.0",
|
||||
"node-sass": "^4.14.0",
|
||||
"node-stream-zip": "1.10.1",
|
||||
"normalize.css": "8.0.1",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.3",
|
||||
"pikaday": "1.8.0",
|
||||
|
@ -85,16 +85,16 @@
|
|||
"string-replace-webpack-plugin": "0.1.3",
|
||||
"strip-sourcemap-loader": "0.0.1",
|
||||
"sumchecker": "^3.0.1",
|
||||
"terser-webpack-plugin": "^2.3.5",
|
||||
"terser-webpack-plugin": "^3.0.0",
|
||||
"time-grunt": "2.0.0",
|
||||
"url-loader": "^4.1.0",
|
||||
"webpack": "^4.42.1",
|
||||
"webpack": "^4.43.0",
|
||||
"webpack-bundle-analyzer": "^3.7.0",
|
||||
"webpack-dev-server": "^3.10.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"grunt-appdmg": "github:keeweb/grunt-appdmg#874ad83",
|
||||
"keytar": "^5.5.0"
|
||||
"keytar": "^5.6.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "grunt",
|
||||
|
|
|
@ -8,6 +8,9 @@ Release notes
|
|||
`+` #1350: clearing master password after auto lock period
|
||||
`-` fix #1463: copying the original url instead of adding https:
|
||||
|
||||
##### v1.14.2 (2020-05-04)
|
||||
`-` distinct redirect URIs for storage providers
|
||||
|
||||
##### v1.14.1 (2020-05-02)
|
||||
`-` fix #1478: fixed proxy issues with storage providers
|
||||
|
||||
|
|
Loading…
Reference in New Issue