自行编译KeeWeb暴力解决坚果云提示Last-Modified
在Mac上用得最多的KeePass软件就是KeeWeb了,不出意外应该是KeePass的衍生软件里面颜值最高了吧,本身也是开源的。在前面的文章里面我就提到了在Mac上能支持KeePass的WebDAV软件屈指可数,KeeWeb已经很好了,唯独有点不好的就是他不支持坚果云,前面也说到了,Nextcloud+KeeWeb在Mac下实现无缝使用,如果你使用坚果云会出现:No Last-Modified header ,究其根本就是HTTP请求的头里面没有Last-Modified,最后的修改时间。
虽然替代方法有很多,比如你可以像我前面的文章那样,自建一个Nextcloud,你不但可以储存自己的kdbx文件,你还可以储存一些其他你自己的资料,但是这个位置我的问题就来了,因为我的服务器性能比较差,我建了一个Nextcloud,里面就放了一个kdbx文件其他的都没放,貌似有点奢侈,然后我就找到了更为廉价的解决方案,反正都是建立一个WebDAV就好了,何必要这么麻烦呢,我找到了phpEasyVCS,或者你可以看一下我的不完全汉化版,一个简单可靠的PHP搭建WebDAV方案,后来还有了Cloudreve,基于ThinkPHP框架的网盘搭建方案,都能提供WebDAV。
作为小型的私有云网盘,他们真的 都是非常优秀的,搭建的难度也非常之低,以后应该我也会写文章专门说,但是都不能避免我一个网盘只放了一个文件,并且连500KB都没有,确实还是有点奢侈。
后来想想还是想办法解决一下KeeWeb的请求头验证问题吧,本来也是开源程序,确实我们也是学习用途。
Building
他的桌面端当然是基于Chromium和Node.js,使用的Electron框架进行打包的,你可以上Electron的官网看看。
首先拉取一下项目的代码,https://github.com/keeweb/keeweb,你可以看官方的Building说明,里面是这样的:
curl https://raw.githubusercontent.com/keeweb/keeweb/develop/dev-env.sh | bash -
你如果因为网络问题可以手动执行:
#!/usr/bin/env bash
echo Cloning KeeWeb into $PWD/keeweb...
mkdir keeweb
git clone git@github.com:keeweb/favicon-proxy.git keeweb/favicon-proxy
git clone git@github.com:keeweb/kdbxweb.git keeweb/kdbxweb
git clone git@github.com:keeweb/keeweb.git -b develop keeweb/keeweb
git clone git@github.com:keeweb/beta.keeweb.info.git keeweb/keeweb-beta
git clone git@github.com:keeweb/keeweb-site.git -b gh-pages keeweb/keeweb-site
git clone git@github.com:keeweb/keeweb-plugins.git keeweb/keeweb-plugins
git clone git@github.com:keeweb/keeweb.git -b gh-pages --single-branch keeweb/keeweb-dist
mkdir keeweb/keys
echo kdbxweb/ > keeweb/.eslintignore
echo Done! KeeWeb is cloned into $PWD/keeweb
我们只需要keeweb/kdbxweb这个项目就行了。
完成后进入目录,使用npm install,安装项目所需的所有模块,在package.json中。
再安装JavaScript的构建工具Grunt,npm install grunt-cli,你可以在这个命令中加-g,全局安装。
如果你用的非Mac系统会提示Local Npm module "grunt-appdmg" not found. Is it installed?,有个grunt-appdmg模块未安装,在非Mac系统中安装不上,用--force跳过不管他。
如果你只是想用网页版,在上面的命令执行后,使用grunt dev,进行debug build,搭建了一个小型的HTTP服务器能够进行测试访问。
这时候运行在localhost:8085/tmp。
不过你这个时候如果从本机打开kdbx文件不会有问题,不过你要是使用WebDAV,会提示下面的问题。
跨域了,CORS,我用的是Nginx部署的,直接按照解决跨域的方法解决,直接从Nginx反向代理一个路径。并且重启Nginx。这只是一个临时的解决方案,你可以查看官网的Wiki,WebDAV Config
location /apis { #将域名+apis设置为坚果云的地址
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass https://dav.jianguoyun.com:443;
}
你也可以使用官方的配置:
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, PUT, OPTIONS, MOVE, DELETE, COPY, LOCK, UNLOCK' always;
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Accept-Charset,X-Accept,origin,accept,if-match,destination,overwrite' always;
add_header 'Access-Control-Expose-Headers' 'ETag' always;
add_header 'Access-Control-Max-Age' 1728000 always;
if ($request_method = 'OPTIONS') {
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, HEAD, POST, PUT, OPTIONS, MOVE, DELETE, COPY, LOCK, UNLOCK';
add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,X-Accept-Charset,X-Accept,origin,accept,if-match,destination,overwrite';
add_header 'Access-Control-Expose-Headers' 'ETag';
add_header 'Access-Control-Max-Age' 1728000;
return 204;
}
如果一切正常,再次使用就会提示No Last-Modified header 。
我们进入源程序的目录/源码目录/app/scripts/storage/storage-webdav.js,熟悉的东西就写在这里,200来行的位置:
提示就在这里,做了一个判断。getResponseHeader('Last-Modified');,你可以直接去掉这一堆,或者把最后修改时间Last-Modified换成data,我也没仔细研究这个位置,不过上述修改方法都能用。
再次编译测试应该就能使用了。
保存的时候配置里面有个上传一个临时文件并移动还是以 PUT 方式覆盖文件,选择用PUT方式吧。坚果云还是NextCloud都有版本控制了。
确认没问题了,就使用grunt desktop打包桌面端。遇到签名问题的话就--skip-sign跳过签名。
官方在这里有提示:
This works only in macOS as it builds dmg; requires wine.
dmg的打包只在Mac下,没必要安装wine打包Windows端的,毕竟Windows下还是KeePass更好用。
确认完成后,进入/源码目录/tmp/desktop/KeeWeb-darwin-x64/需要的KeeWeb.app就在里面了。
一切正常,就是这样。
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。