A few improvements, requested from the review:
- File reading is now happening later in the process; - File reading now reuses methods from `core/attachment`; - Errors thrown in the import now include an error message; - Adds prettier command to "prettify" all files; - Adds prettier command to check for files not conforming to prettier's config; - Makes CI run the prettier:check command; - Changes `export const method = () => {};` to `export function method() {}` in the `1pux-parser` file; - Other minor consistency changes/fixes/improvements; - Actually ran prettier on every file, and it had a lot of things to tweak.
This commit is contained in:
parent
db18adf7fd
commit
50ae105b45
|
@ -2,43 +2,43 @@ name: "Build And Publish Desktop Tauri Apps"
|
||||||
on: [workflow_dispatch]
|
on: [workflow_dispatch]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build_and_publish:
|
build_and_publish:
|
||||||
name: Build And Publish
|
name: Build And Publish
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
platform: [macos-latest, ubuntu-latest, windows-latest]
|
platform: [macos-latest, ubuntu-latest, windows-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.platform }}
|
runs-on: ${{ matrix.platform }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- name: setup node
|
- name: setup node
|
||||||
uses: actions/setup-node@v1
|
uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 12
|
||||||
- name: install Rust stable
|
- name: install Rust stable
|
||||||
uses: actions-rs/toolchain@v1
|
uses: actions-rs/toolchain@v1
|
||||||
with:
|
with:
|
||||||
toolchain: stable
|
toolchain: stable
|
||||||
- name: install tauri bundler
|
- name: install tauri bundler
|
||||||
run: cargo install tauri-bundler --force
|
run: cargo install tauri-bundler --force
|
||||||
- name: install webkit2gtk (ubuntu only)
|
- name: install webkit2gtk (ubuntu only)
|
||||||
if: matrix.platform == 'ubuntu-latest'
|
if: matrix.platform == 'ubuntu-latest'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install -y webkit2gtk-4.0
|
sudo apt-get install -y webkit2gtk-4.0
|
||||||
- name: install app dependencies and bootstrap packages
|
- name: install app dependencies and bootstrap packages
|
||||||
run: npm install
|
run: npm install
|
||||||
- uses: tauri-apps/tauri-action@v0
|
- uses: tauri-apps/tauri-action@v0
|
||||||
env:
|
env:
|
||||||
PL_SERVER_URL: https://api.padloc.app
|
PL_SERVER_URL: https://api.padloc.app
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
tagName: tauri-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version
|
tagName: tauri-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version
|
||||||
releaseName: "Padloc (Tauri Edition) v__VERSION__"
|
releaseName: "Padloc (Tauri Edition) v__VERSION__"
|
||||||
body: "WARNING: The builds in this release are experimental. Use at your own risk!"
|
body: "WARNING: The builds in this release are experimental. Use at your own risk!"
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: true
|
prerelease: true
|
||||||
projectPath: packages/tauri
|
projectPath: packages/tauri
|
||||||
npmScript: build
|
npmScript: build
|
||||||
|
|
|
@ -3,18 +3,20 @@ name: Run Tests
|
||||||
on: [push]
|
on: [push]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 16.13.1
|
node-version: 16.13.1
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
- name: Run pwa test build
|
- name: Run prettier check
|
||||||
run: npm run pwa:build
|
run: npm run prettier:check
|
||||||
- name: Test starting zero-config server
|
- name: Run pwa test build
|
||||||
run: npm run server:start-dry
|
run: npm run pwa:build
|
||||||
#- name: Run tests
|
- name: Test starting zero-config server
|
||||||
# run: npm test
|
run: npm run server:start-dry
|
||||||
|
#- name: Run tests
|
||||||
|
# run: npm test
|
||||||
|
|
|
@ -1 +1,2 @@
|
||||||
app/src/core/*.js
|
app/src/core/*.js
|
||||||
|
package-lock.json
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
{
|
{
|
||||||
"lit-plugin.globalAttributes": [
|
"lit-plugin.globalAttributes": ["disabled"],
|
||||||
"disabled"
|
|
||||||
],
|
|
||||||
"files.associations": {
|
"files.associations": {
|
||||||
"*.svg": "html"
|
"*.svg": "html"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ For more configuration options, see [Configuration](#configuration)
|
||||||
|
|
||||||
To add dependencies, you can use `scope=[scope-without-@padloc/] npm run add [package]` and to remove them, run `scope=[scope-without-@padloc/] npm run remove [package]`.
|
To add dependencies, you can use `scope=[scope-without-@padloc/] npm run add [package]` and to remove them, run `scope=[scope-without-@padloc/] npm run remove [package]`.
|
||||||
|
|
||||||
|
Use `npm run prettier` to make "prettify" all files.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
| Environment Variable | Default | Description |
|
| Environment Variable | Default | Description |
|
||||||
|
|
|
@ -7,4 +7,4 @@
|
||||||
"appId": "app.padloc",
|
"appId": "app.padloc",
|
||||||
"scheme": "padloc",
|
"scheme": "padloc",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>"
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
module.exports = function(config) {
|
module.exports = function (config) {
|
||||||
config.set({
|
config.set({
|
||||||
frameworks: ["mocha", "chai"],
|
frameworks: ["mocha", "chai"],
|
||||||
files: ["test/tests.js"],
|
files: ["test/tests.js"],
|
||||||
|
@ -9,6 +9,6 @@ module.exports = function(config) {
|
||||||
browsers: ["ChromeHeadless"],
|
browsers: ["ChromeHeadless"],
|
||||||
autoWatch: false,
|
autoWatch: false,
|
||||||
// singleRun: false, // Karma captures browsers, runs the tests and exits
|
// singleRun: false, // Karma captures browsers, runs the tests and exits
|
||||||
concurrency: Infinity
|
concurrency: Infinity,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
{
|
{
|
||||||
"packages": [
|
"packages": ["packages/*"],
|
||||||
"packages/*"
|
"version": "4.0.0",
|
||||||
],
|
"exact": true
|
||||||
"version": "4.0.0",
|
|
||||||
"exact": true
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"lerna": "4.0.0",
|
"lerna": "4.0.0",
|
||||||
|
"prettier": "2.5.1",
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typescript": "4.4.3"
|
"typescript": "4.4.3"
|
||||||
},
|
},
|
||||||
|
@ -5658,6 +5659,18 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin-prettier.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/process-nextick-args": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
@ -12266,6 +12279,12 @@
|
||||||
"find-up": "^4.0.0"
|
"find-up": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"process-nextick-args": {
|
"process-nextick-args": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||||
|
|
79
package.json
79
package.json
|
@ -1,40 +1,43 @@
|
||||||
{
|
{
|
||||||
"name": "padloc",
|
"name": "padloc",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"description": "A minimalist password manager",
|
"description": "A minimalist password manager",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"homepage": "https://padlock.io/",
|
"homepage": "https://padloc.app/",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/maklesoft/padlock.git"
|
"url": "git+https://github.com/padloc/padloc.git"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
},
|
},
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"lerna": "4.0.0",
|
"lerna": "4.0.0",
|
||||||
"ts-node": "10.0.0",
|
"prettier": "2.5.1",
|
||||||
"typescript": "4.4.3"
|
"ts-node": "10.0.0",
|
||||||
},
|
"typescript": "4.4.3"
|
||||||
"scripts": {
|
},
|
||||||
"postinstall": "lerna bootstrap",
|
"scripts": {
|
||||||
"bootstrap": "lerna bootstrap",
|
"postinstall": "lerna bootstrap",
|
||||||
"pwa:build": "lerna run build --scope @padloc/pwa",
|
"bootstrap": "lerna bootstrap",
|
||||||
"pwa:start": "lerna run start --scope @padloc/pwa",
|
"pwa:build": "lerna run build --scope @padloc/pwa",
|
||||||
"server:start": "lerna run start --scope @padloc/server --stream",
|
"pwa:start": "lerna run start --scope @padloc/pwa",
|
||||||
"server:start-dry": "lerna run start-dry --stream --scope @padloc/server",
|
"server:start": "lerna run start --scope @padloc/server --stream",
|
||||||
"electron:build": "cd packages/electron && npm run build && cd ../..",
|
"server:start-dry": "lerna run start-dry --stream --scope @padloc/server",
|
||||||
"start": "npm run pwa:build && lerna run --scope '@padloc/{server,pwa}' --parallel start",
|
"electron:build": "cd packages/electron && npm run build && cd ../..",
|
||||||
"dev": "lerna run --parallel --scope '@padloc/{server,pwa}' --parallel dev",
|
"start": "npm run pwa:build && lerna run --scope '@padloc/{server,pwa}' --parallel start",
|
||||||
"tauri:dev": "lerna run --parallel --scope '@padloc/{server,tauri}' --parallel dev",
|
"dev": "lerna run --parallel --scope '@padloc/{server,pwa}' --parallel dev",
|
||||||
"repl": "cd packages/server && npm run repl && cd ../..",
|
"tauri:dev": "lerna run --parallel --scope '@padloc/{server,tauri}' --parallel dev",
|
||||||
"test": "lerna run test",
|
"repl": "cd packages/server && npm run repl && cd ../..",
|
||||||
"locale:extract": "lerna run extract --scope '@padloc/locale'",
|
"test": "lerna run test",
|
||||||
"add": "lerna add $1 --scope=@padloc/$scope",
|
"locale:extract": "lerna run extract --scope '@padloc/locale'",
|
||||||
"remove": "rm packages/$scope/package-lock.json && lerna exec \"npm uninstall $1\" --scope=@padloc/$scope"
|
"add": "lerna add $1 --scope=@padloc/$scope",
|
||||||
}
|
"remove": "rm packages/$scope/package-lock.json && lerna exec \"npm uninstall $1\" --scope=@padloc/$scope",
|
||||||
|
"prettier": "prettier --write .",
|
||||||
|
"prettier:check": "prettier --check ."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,64 +1,64 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/app",
|
"name": "@padloc/app",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"assets",
|
"assets",
|
||||||
"types",
|
"types",
|
||||||
"tsconfig.json"
|
"tsconfig.json"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git",
|
"url": "https://github.com/padloc/padloc.git",
|
||||||
"directory": "packages/app"
|
"directory": "packages/app"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/core": "4.0.0",
|
"@padloc/core": "4.0.0",
|
||||||
"@padloc/locale": "4.0.0",
|
"@padloc/locale": "4.0.0",
|
||||||
"@simplewebauthn/browser": "4.0.0",
|
"@simplewebauthn/browser": "4.0.0",
|
||||||
"@simplewebauthn/typescript-types": "4.0.0",
|
"@simplewebauthn/typescript-types": "4.0.0",
|
||||||
"@types/dompurify": "2.3.1",
|
"@types/dompurify": "2.3.1",
|
||||||
"@types/marked": "3.0.1",
|
"@types/marked": "3.0.1",
|
||||||
"@types/papaparse": "5.2.5",
|
"@types/papaparse": "5.2.5",
|
||||||
"@types/qrcode": "1.4.1",
|
"@types/qrcode": "1.4.1",
|
||||||
"@types/ua-parser-js": "0.7.36",
|
"@types/ua-parser-js": "0.7.36",
|
||||||
"@types/workbox-precaching": "4.3.1",
|
"@types/workbox-precaching": "4.3.1",
|
||||||
"@types/workbox-sw": "4.3.1",
|
"@types/workbox-sw": "4.3.1",
|
||||||
"@types/workbox-window": "4.3.3",
|
"@types/workbox-window": "4.3.3",
|
||||||
"@types/zxcvbn": "4.4.1",
|
"@types/zxcvbn": "4.4.1",
|
||||||
"@webcomponents/webcomponentsjs": "2.5.0",
|
"@webcomponents/webcomponentsjs": "2.5.0",
|
||||||
"autosize": "5.0.0",
|
"autosize": "5.0.0",
|
||||||
"date-fns": "2.22.1",
|
"date-fns": "2.22.1",
|
||||||
"dompurify": "2.3.3",
|
"dompurify": "2.3.3",
|
||||||
"event-target-shim": "6.0.2",
|
"event-target-shim": "6.0.2",
|
||||||
"http-server": "0.12.3",
|
"http-server": "0.12.3",
|
||||||
"jsqr": "1.4.0",
|
"jsqr": "1.4.0",
|
||||||
"jszip": "3.7.1",
|
"jszip": "3.7.1",
|
||||||
"lit": "2.0.0-rc.2",
|
"lit": "2.0.0-rc.2",
|
||||||
"localforage": "1.9.0",
|
"localforage": "1.9.0",
|
||||||
"marked": "3.0.4",
|
"marked": "3.0.4",
|
||||||
"papaparse": "5.3.1",
|
"papaparse": "5.3.1",
|
||||||
"qrcode": "1.4.4",
|
"qrcode": "1.4.4",
|
||||||
"reflect-metadata": "0.1.13",
|
"reflect-metadata": "0.1.13",
|
||||||
"typescript": "4.4.3",
|
"typescript": "4.4.3",
|
||||||
"ua-parser-js": "0.7.28",
|
"ua-parser-js": "0.7.28",
|
||||||
"workbox-precaching": "6.2.0",
|
"workbox-precaching": "6.2.0",
|
||||||
"workbox-sw": "6.1.5",
|
"workbox-sw": "6.1.5",
|
||||||
"workbox-window": "6.1.5",
|
"workbox-window": "6.1.5",
|
||||||
"zxcvbn": "4.4.2"
|
"zxcvbn": "4.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "4.2.18",
|
"@types/chai": "4.2.18",
|
||||||
"@types/mocha": "8.2.2",
|
"@types/mocha": "8.2.2",
|
||||||
"chai": "4.3.4",
|
"chai": "4.3.4",
|
||||||
"mocha": "8.4.0"
|
"mocha": "8.4.0"
|
||||||
},
|
},
|
||||||
"description": "Padloc Web-Based UI package"
|
"description": "Padloc Web-Based UI package"
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ export class Dialog<I, R> extends LitElement {
|
||||||
Dialog.openDialogs.delete(this);
|
Dialog.openDialogs.delete(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
async show(_input: I = (undefined as any) as I) {
|
async show(_input: I = undefined as any as I) {
|
||||||
Dialog.openDialogs.add(this);
|
Dialog.openDialogs.add(this);
|
||||||
this.open = true;
|
this.open = true;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ import { stringToBytes } from "@padloc/core/src/encoding";
|
||||||
@customElement("pl-import-dialog")
|
@customElement("pl-import-dialog")
|
||||||
export class ImportDialog extends Dialog<File, void> {
|
export class ImportDialog extends Dialog<File, void> {
|
||||||
@state()
|
@state()
|
||||||
private _rawData: null | string | ArrayBuffer = "";
|
private _file: File;
|
||||||
|
|
||||||
@state()
|
@state()
|
||||||
private _items: VaultItem[] = [];
|
private _items: VaultItem[] = [];
|
||||||
|
@ -71,19 +71,10 @@ export class ImportDialog extends Dialog<File, void> {
|
||||||
await this.updateComplete;
|
await this.updateComplete;
|
||||||
const result = super.show();
|
const result = super.show();
|
||||||
|
|
||||||
const reader = new FileReader();
|
this._file = file;
|
||||||
reader.onload = async () => {
|
this._formatSelect.value = ((await imp.guessFormat(file)) || imp.CSV).value;
|
||||||
this._rawData = reader.result;
|
await this._parseData();
|
||||||
this._formatSelect.value = (imp.guessFormat(file, this._rawData) || imp.CSV).value;
|
this._vaultSelect.value = app.mainVault!;
|
||||||
this._parseData();
|
|
||||||
this._vaultSelect.value = app.mainVault!;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (imp.doesFileRequireReadingAsBinary(file)) {
|
|
||||||
reader.readAsArrayBuffer(file);
|
|
||||||
} else {
|
|
||||||
reader.readAsText(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +91,7 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _parseData(): Promise<void> {
|
private async _parseData(): Promise<void> {
|
||||||
const rawStr = this._rawData;
|
const file = this._file;
|
||||||
|
|
||||||
switch (this._formatSelect.value) {
|
switch (this._formatSelect.value) {
|
||||||
case imp.PADLOCK_LEGACY.value:
|
case imp.PADLOCK_LEGACY.value:
|
||||||
|
@ -111,7 +102,7 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
|
||||||
type: "password",
|
type: "password",
|
||||||
validate: async (pwd: string) => {
|
validate: async (pwd: string) => {
|
||||||
try {
|
try {
|
||||||
this._items = await imp.asPadlockLegacy(rawStr as string, pwd);
|
this._items = await imp.asPadlockLegacy(file, pwd);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw $l("Wrong Password");
|
throw $l("Wrong Password");
|
||||||
}
|
}
|
||||||
|
@ -125,13 +116,13 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case imp.LASTPASS.value:
|
case imp.LASTPASS.value:
|
||||||
this._items = await imp.asLastPass(rawStr as string);
|
this._items = await imp.asLastPass(file);
|
||||||
break;
|
break;
|
||||||
case imp.CSV.value:
|
case imp.CSV.value:
|
||||||
this._items = await imp.asCSV(rawStr as string);
|
this._items = await imp.asCSV(file);
|
||||||
break;
|
break;
|
||||||
case imp.ONEPUX.value:
|
case imp.ONEPUX.value:
|
||||||
this._items = await imp.as1Pux(rawStr);
|
this._items = await imp.as1Pux(file);
|
||||||
break;
|
break;
|
||||||
case imp.PBES2.value:
|
case imp.PBES2.value:
|
||||||
this.open = false;
|
this.open = false;
|
||||||
|
@ -141,7 +132,7 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
|
||||||
type: "password",
|
type: "password",
|
||||||
validate: async (pwd: string) => {
|
validate: async (pwd: string) => {
|
||||||
try {
|
try {
|
||||||
this._items = await imp.asPBES2Container(rawStr as string, pwd);
|
this._items = await imp.asPBES2Container(file, pwd);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw $l("Wrong Password");
|
throw $l("Wrong Password");
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,9 +173,8 @@ export class Popover extends LitElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _getAutoAlignment(): PopoverAlignment {
|
private _getAutoAlignment(): PopoverAlignment {
|
||||||
const preferred = (Array.isArray(this.preferAlignment)
|
const preferred = (
|
||||||
? [...this.preferAlignment]
|
Array.isArray(this.preferAlignment) ? [...this.preferAlignment] : [this.preferAlignment]
|
||||||
: [this.preferAlignment]
|
|
||||||
).reverse();
|
).reverse();
|
||||||
const alignments = [...ALIGNMENTS].sort((a, b) => preferred.indexOf(b) - preferred.indexOf(a));
|
const alignments = [...ALIGNMENTS].sort((a, b) => preferred.indexOf(b) - preferred.indexOf(a));
|
||||||
return alignments.find((alignment) => this._isWithinBounds(this._getPosition(alignment))) || alignments[0];
|
return alignments.find((alignment) => this._isWithinBounds(this._getPosition(alignment))) || alignments[0];
|
||||||
|
|
|
@ -65,7 +65,12 @@ export class SettingsTools extends StateMixin(LitElement) {
|
||||||
</pl-scroller>
|
</pl-scroller>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input type="file" accept="text/plain,.csv,.pls,.set,.pbes2,.1pux" hidden @change=${() => this._importFile()} />
|
<input
|
||||||
|
type="file"
|
||||||
|
accept="text/plain,.csv,.pls,.set,.pbes2,.1pux"
|
||||||
|
hidden
|
||||||
|
@change=${() => this._importFile()}
|
||||||
|
/>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,308 +1,283 @@
|
||||||
import { loadAsync } from 'jszip';
|
import { loadAsync } from "jszip";
|
||||||
|
|
||||||
export type OnePuxItemDetailsLoginField = {
|
export type OnePuxItemDetailsLoginField = {
|
||||||
value: string;
|
value: string;
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
fieldType: 'A' | 'B' | 'C' | 'E' | 'I' | 'N' | 'P' | 'R' | 'S' | 'T' | 'U';
|
fieldType: "A" | "B" | "C" | "E" | "I" | "N" | "P" | "R" | "S" | "T" | "U";
|
||||||
designation?: 'username' | 'password';
|
designation?: "username" | "password";
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxItemDetailsSection = {
|
export type OnePuxItemDetailsSection = {
|
||||||
title: string;
|
title: string;
|
||||||
name: string;
|
name: string;
|
||||||
fields: [
|
fields: [
|
||||||
{
|
{
|
||||||
title: string;
|
title: string;
|
||||||
id: string;
|
id: string;
|
||||||
value: {
|
value: {
|
||||||
concealed?: string;
|
concealed?: string;
|
||||||
reference?: string;
|
reference?: string;
|
||||||
string?: string;
|
string?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
phone?: string;
|
phone?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
totp?: string;
|
totp?: string;
|
||||||
gender?: string;
|
gender?: string;
|
||||||
creditCardType?: string;
|
creditCardType?: string;
|
||||||
creditCardNumber?: string;
|
creditCardNumber?: string;
|
||||||
monthYear?: number;
|
monthYear?: number;
|
||||||
date?: number;
|
date?: number;
|
||||||
};
|
};
|
||||||
indexAtSource: number;
|
indexAtSource: number;
|
||||||
guarded: boolean;
|
guarded: boolean;
|
||||||
multiline: boolean;
|
multiline: boolean;
|
||||||
dontGenerate: boolean;
|
dontGenerate: boolean;
|
||||||
inputTraits: {
|
inputTraits: {
|
||||||
keyboard: string;
|
keyboard: string;
|
||||||
correction: string;
|
correction: string;
|
||||||
capitalization: string;
|
capitalization: string;
|
||||||
};
|
};
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxItemDetailsPasswordHistory = {
|
export type OnePuxItemDetailsPasswordHistory = {
|
||||||
value: string;
|
value: string;
|
||||||
time: number;
|
time: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxItemOverviewUrl = {
|
export type OnePuxItemOverviewUrl = {
|
||||||
label: string;
|
label: string;
|
||||||
url: string;
|
url: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxItem = {
|
export type OnePuxItem = {
|
||||||
item?: {
|
item?: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
favIndex: number;
|
favIndex: number;
|
||||||
createdAt: number;
|
createdAt: number;
|
||||||
updatedAt: number;
|
updatedAt: number;
|
||||||
trashed: boolean;
|
trashed: boolean;
|
||||||
categoryUuid: string;
|
categoryUuid: string;
|
||||||
details: {
|
details: {
|
||||||
loginFields: OnePuxItemDetailsLoginField[];
|
loginFields: OnePuxItemDetailsLoginField[];
|
||||||
notesPlain?: string;
|
notesPlain?: string;
|
||||||
sections: OnePuxItemDetailsSection[];
|
sections: OnePuxItemDetailsSection[];
|
||||||
passwordHistory: OnePuxItemDetailsPasswordHistory[];
|
passwordHistory: OnePuxItemDetailsPasswordHistory[];
|
||||||
documentAttributes?: {
|
documentAttributes?: {
|
||||||
fileName: string;
|
fileName: string;
|
||||||
documentId: string;
|
documentId: string;
|
||||||
decryptedSize: number;
|
decryptedSize: number;
|
||||||
};
|
};
|
||||||
|
};
|
||||||
|
overview: {
|
||||||
|
subtitle: string;
|
||||||
|
urls?: OnePuxItemOverviewUrl[];
|
||||||
|
title: string;
|
||||||
|
url: string;
|
||||||
|
ps?: number;
|
||||||
|
pbe?: number;
|
||||||
|
pgrng?: boolean;
|
||||||
|
tags?: string[];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
overview: {
|
file?: {
|
||||||
subtitle: string;
|
attrs: {
|
||||||
urls?: OnePuxItemOverviewUrl[];
|
uuid: string;
|
||||||
title: string;
|
name: string;
|
||||||
url: string;
|
type: string;
|
||||||
ps?: number;
|
};
|
||||||
pbe?: number;
|
path: string;
|
||||||
pgrng?: boolean;
|
|
||||||
tags?: string[];
|
|
||||||
};
|
};
|
||||||
};
|
|
||||||
file?: {
|
|
||||||
attrs: {
|
|
||||||
uuid: string;
|
|
||||||
name: string;
|
|
||||||
type: string;
|
|
||||||
};
|
|
||||||
path: string;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxVault = {
|
export type OnePuxVault = {
|
||||||
attrs: {
|
attrs: {
|
||||||
uuid: string;
|
uuid: string;
|
||||||
desc: string;
|
desc: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
name: string;
|
name: string;
|
||||||
type: 'P' | 'E' | 'U';
|
type: "P" | "E" | "U";
|
||||||
};
|
};
|
||||||
items: OnePuxItem[];
|
items: OnePuxItem[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxAccount = {
|
export type OnePuxAccount = {
|
||||||
attrs: {
|
attrs: {
|
||||||
accountName: string;
|
accountName: string;
|
||||||
name: string;
|
name: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
email: string;
|
email: string;
|
||||||
uuid: string;
|
uuid: string;
|
||||||
domain: string;
|
domain: string;
|
||||||
};
|
};
|
||||||
vaults: OnePuxVault[];
|
vaults: OnePuxVault[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxData = {
|
export type OnePuxData = {
|
||||||
accounts: OnePuxAccount[];
|
accounts: OnePuxAccount[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxAttributes = {
|
export type OnePuxAttributes = {
|
||||||
version: number;
|
version: number;
|
||||||
description: string;
|
description: string;
|
||||||
createdAt: number;
|
createdAt: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type OnePuxExport = {
|
export type OnePuxExport = {
|
||||||
attributes: OnePuxAttributes;
|
attributes: OnePuxAttributes;
|
||||||
data: OnePuxData;
|
data: OnePuxData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const parse1PuxFile = async (
|
export async function parse1PuxFile(fileContents: ArrayBuffer): Promise<OnePuxExport> {
|
||||||
fileContents: string | ArrayBuffer,
|
try {
|
||||||
) => {
|
const zip = await loadAsync(fileContents);
|
||||||
try {
|
|
||||||
const zip = await loadAsync(fileContents);
|
|
||||||
|
|
||||||
const attributesContent = await zip
|
const attributesContent = await zip.file("export.attributes")!.async("string");
|
||||||
.file('export.attributes')!
|
const attributes = JSON.parse(attributesContent);
|
||||||
.async('string');
|
const dataContent = await zip.file("export.data")!.async("string");
|
||||||
const attributes = JSON.parse(attributesContent);
|
const data = JSON.parse(dataContent);
|
||||||
const dataContent = await zip.file('export.data')!.async('string');
|
|
||||||
const data = JSON.parse(dataContent);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
attributes,
|
attributes,
|
||||||
data,
|
data,
|
||||||
} as OnePuxExport;
|
} as OnePuxExport;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to parse .1pux file');
|
console.error("Failed to parse .1pux file");
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
type RowData = {
|
type RowData = {
|
||||||
name: string;
|
name: string;
|
||||||
tags: string;
|
tags: string;
|
||||||
url: string;
|
url: string;
|
||||||
username: string;
|
username: string;
|
||||||
password: string;
|
password: string;
|
||||||
notes: string;
|
notes: string;
|
||||||
extraFields: ExtraField[];
|
extraFields: ExtraField[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type ExtraFieldType =
|
type ExtraFieldType =
|
||||||
| 'username'
|
| "username"
|
||||||
| 'password'
|
| "password"
|
||||||
| 'url'
|
| "url"
|
||||||
| 'email'
|
| "email"
|
||||||
| 'date'
|
| "date"
|
||||||
| 'month'
|
| "month"
|
||||||
| 'credit'
|
| "credit"
|
||||||
| 'phone'
|
| "phone"
|
||||||
| 'totp'
|
| "totp"
|
||||||
| 'text';
|
| "text";
|
||||||
|
|
||||||
type ExtraField = { name: string; value: string; type: ExtraFieldType };
|
type ExtraField = { name: string; value: string; type: ExtraFieldType };
|
||||||
|
|
||||||
type ParseFieldTypeToExtraFieldType = (
|
function parseFieldTypeToExtraFieldType(field: OnePuxItemDetailsLoginField): ExtraFieldType {
|
||||||
field: OnePuxItemDetailsLoginField,
|
if (field.designation === "username") {
|
||||||
) => ExtraFieldType;
|
return "username";
|
||||||
|
} else if (field.designation === "password") {
|
||||||
const parseFieldTypeToExtraFieldType: ParseFieldTypeToExtraFieldType = (
|
return "password";
|
||||||
field,
|
} else if (field.fieldType === "E") {
|
||||||
) => {
|
return "email";
|
||||||
if (field.designation === 'username') {
|
} else if (field.fieldType === "U") {
|
||||||
return 'username';
|
return "url";
|
||||||
} else if (field.designation === 'password') {
|
|
||||||
return 'password';
|
|
||||||
} else if (field.fieldType === 'E') {
|
|
||||||
return 'email';
|
|
||||||
} else if (field.fieldType === 'U') {
|
|
||||||
return 'url';
|
|
||||||
}
|
|
||||||
return 'text';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const parseToRowData = (
|
|
||||||
item: OnePuxItem['item'],
|
|
||||||
defaultTags?: string[],
|
|
||||||
) => {
|
|
||||||
if (!item) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const rowData: RowData = {
|
|
||||||
name: item.overview.title,
|
|
||||||
tags: [...(defaultTags || []), ...(item.overview.tags || [])].join(','),
|
|
||||||
url: item.overview.url || '',
|
|
||||||
username: '',
|
|
||||||
password: '',
|
|
||||||
notes: item.details.notesPlain || '',
|
|
||||||
extraFields: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
// Skip documents
|
|
||||||
if (
|
|
||||||
item.details.documentAttributes &&
|
|
||||||
item.details.loginFields.length === 0
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Extract username, password, and some extraFields
|
|
||||||
item.details.loginFields.forEach((field) => {
|
|
||||||
if (field.designation === 'username') {
|
|
||||||
rowData.username = field.value;
|
|
||||||
} else if (field.designation === 'password') {
|
|
||||||
rowData.password = field.value;
|
|
||||||
} else if (
|
|
||||||
field.fieldType === 'I' ||
|
|
||||||
field.fieldType === 'C' ||
|
|
||||||
field.id.includes(';opid=__') ||
|
|
||||||
field.value === ''
|
|
||||||
) {
|
|
||||||
// Skip these noisy form-fields
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
rowData.extraFields.push({
|
|
||||||
name: field.name || field.id,
|
|
||||||
value: field.value,
|
|
||||||
type: parseFieldTypeToExtraFieldType(field),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
return "text";
|
||||||
|
}
|
||||||
|
|
||||||
// Extract some more extraFields
|
export function parseToRowData(item: OnePuxItem["item"], defaultTags?: string[]): RowData | undefined {
|
||||||
item.details.sections.forEach((section) => {
|
if (!item) {
|
||||||
section.fields.forEach((field) => {
|
return;
|
||||||
let value = '';
|
}
|
||||||
let type: ExtraFieldType = 'text';
|
|
||||||
|
|
||||||
if (Object.prototype.hasOwnProperty.call(field.value, 'concealed')) {
|
const rowData: RowData = {
|
||||||
value = field.value.concealed || '';
|
name: item.overview.title,
|
||||||
} else if (
|
tags: [...(defaultTags || []), ...(item.overview.tags || [])].join(","),
|
||||||
Object.prototype.hasOwnProperty.call(field.value, 'reference')
|
url: item.overview.url || "",
|
||||||
) {
|
username: "",
|
||||||
value = field.value.reference || '';
|
password: "",
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'string')) {
|
notes: item.details.notesPlain || "",
|
||||||
value = field.value.string || '';
|
extraFields: [],
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'email')) {
|
};
|
||||||
value = field.value.email || '';
|
|
||||||
type = 'email';
|
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'phone')) {
|
|
||||||
value = field.value.phone || '';
|
|
||||||
type = 'phone';
|
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'url')) {
|
|
||||||
value = field.value.url || '';
|
|
||||||
type = 'url';
|
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'totp')) {
|
|
||||||
value = field.value.totp || '';
|
|
||||||
type = 'totp';
|
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'gender')) {
|
|
||||||
value = field.value.gender || '';
|
|
||||||
} else if (
|
|
||||||
Object.prototype.hasOwnProperty.call(field.value, 'creditCardType')
|
|
||||||
) {
|
|
||||||
value = field.value.creditCardType || '';
|
|
||||||
} else if (
|
|
||||||
Object.prototype.hasOwnProperty.call(field.value, 'creditCardNumber')
|
|
||||||
) {
|
|
||||||
value = field.value.creditCardNumber || '';
|
|
||||||
type = 'credit';
|
|
||||||
} else if (
|
|
||||||
Object.prototype.hasOwnProperty.call(field.value, 'monthYear')
|
|
||||||
) {
|
|
||||||
value =
|
|
||||||
(field.value.monthYear && field.value.monthYear.toString()) || '';
|
|
||||||
type = 'month';
|
|
||||||
} else if (Object.prototype.hasOwnProperty.call(field.value, 'date')) {
|
|
||||||
value = (field.value.date && field.value.date.toString()) || '';
|
|
||||||
type = 'date';
|
|
||||||
} else {
|
|
||||||
// Default, so no data is lost when something new comes up
|
|
||||||
value = JSON.stringify(field.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
rowData.extraFields.push({
|
// Skip documents
|
||||||
name: field.title || field.id,
|
if (item.details.documentAttributes && item.details.loginFields.length === 0) {
|
||||||
value,
|
return;
|
||||||
type,
|
}
|
||||||
});
|
|
||||||
|
// Extract username, password, and some extraFields
|
||||||
|
item.details.loginFields.forEach((field) => {
|
||||||
|
if (field.designation === "username") {
|
||||||
|
rowData.username = field.value;
|
||||||
|
} else if (field.designation === "password") {
|
||||||
|
rowData.password = field.value;
|
||||||
|
} else if (
|
||||||
|
field.fieldType === "I" ||
|
||||||
|
field.fieldType === "C" ||
|
||||||
|
field.id.includes(";opid=__") ||
|
||||||
|
field.value === ""
|
||||||
|
) {
|
||||||
|
// Skip these noisy form-fields
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
rowData.extraFields.push({
|
||||||
|
name: field.name || field.id,
|
||||||
|
value: field.value,
|
||||||
|
type: parseFieldTypeToExtraFieldType(field),
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
|
|
||||||
return rowData;
|
// Extract some more extraFields
|
||||||
};
|
item.details.sections.forEach((section) => {
|
||||||
|
section.fields.forEach((field) => {
|
||||||
|
let value = "";
|
||||||
|
let type: ExtraFieldType = "text";
|
||||||
|
|
||||||
|
if (field.value.concealed) {
|
||||||
|
value = field.value.concealed || "";
|
||||||
|
} else if (field.value.reference) {
|
||||||
|
value = field.value.reference || "";
|
||||||
|
} else if (field.value.string) {
|
||||||
|
value = field.value.string || "";
|
||||||
|
} else if (field.value.email) {
|
||||||
|
value = field.value.email || "";
|
||||||
|
type = "email";
|
||||||
|
} else if (field.value.phone) {
|
||||||
|
value = field.value.phone || "";
|
||||||
|
type = "phone";
|
||||||
|
} else if (field.value.url) {
|
||||||
|
value = field.value.url || "";
|
||||||
|
type = "url";
|
||||||
|
} else if (field.value.totp) {
|
||||||
|
value = field.value.totp || "";
|
||||||
|
type = "totp";
|
||||||
|
} else if (field.value.gender) {
|
||||||
|
value = field.value.gender || "";
|
||||||
|
} else if (field.value.creditCardType) {
|
||||||
|
value = field.value.creditCardType || "";
|
||||||
|
} else if (field.value.creditCardNumber) {
|
||||||
|
value = field.value.creditCardNumber || "";
|
||||||
|
type = "credit";
|
||||||
|
} else if (field.value.monthYear) {
|
||||||
|
value = (field.value.monthYear && field.value.monthYear.toString()) || "";
|
||||||
|
type = "month";
|
||||||
|
} else if (field.value.date) {
|
||||||
|
value = (field.value.date && field.value.date.toString()) || "";
|
||||||
|
type = "date";
|
||||||
|
} else {
|
||||||
|
// Default, so no data is lost when something new comes up
|
||||||
|
value = JSON.stringify(field.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowData.extraFields.push({
|
||||||
|
name: field.title || field.id,
|
||||||
|
value,
|
||||||
|
type,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return rowData;
|
||||||
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ const defaults = {
|
||||||
initialDelay: 0,
|
initialDelay: 0,
|
||||||
fullDuration: 1000,
|
fullDuration: 1000,
|
||||||
clear: false,
|
clear: false,
|
||||||
direction: "normal"
|
direction: "normal",
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearAnimation = new Map<HTMLElement, number>();
|
const clearAnimation = new Map<HTMLElement, number>();
|
||||||
|
@ -20,10 +20,13 @@ export function animateElement(el: HTMLElement, opts = {}) {
|
||||||
el.style.animation = `${animation} ${direction} ${duration}ms ${easing} ${delay}ms ${fill}`;
|
el.style.animation = `${animation} ${direction} ${duration}ms ${easing} ${delay}ms ${fill}`;
|
||||||
if (clear) {
|
if (clear) {
|
||||||
const clearDelay = typeof clear === "number" ? clear : 0;
|
const clearDelay = typeof clear === "number" ? clear : 0;
|
||||||
clearAnimation.set(el, window.setTimeout(() => (el.style.animation = ""), delay + duration + clearDelay));
|
clearAnimation.set(
|
||||||
|
el,
|
||||||
|
window.setTimeout(() => (el.style.animation = ""), delay + duration + clearDelay)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Promise(resolve => setTimeout(resolve, delay + duration));
|
return new Promise((resolve) => setTimeout(resolve, delay + duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function animateCascade(nodes: Iterable<Node | Element>, opts = {}) {
|
export function animateCascade(nodes: Iterable<Node | Element>, opts = {}) {
|
||||||
|
|
|
@ -5,8 +5,9 @@ import { VaultItem, Field, createVaultItem, FieldType } from "@padloc/core/src/i
|
||||||
import { Err, ErrorCode } from "@padloc/core/src/error";
|
import { Err, ErrorCode } from "@padloc/core/src/error";
|
||||||
import { uuid } from "@padloc/core/src/util";
|
import { uuid } from "@padloc/core/src/util";
|
||||||
import { translate as $l } from "@padloc/locale/src/translate";
|
import { translate as $l } from "@padloc/locale/src/translate";
|
||||||
|
import { readFileAsText, readFileAsArrayBuffer } from "@padloc/core/src/attachment";
|
||||||
|
|
||||||
import { parse1PuxFile, parseToRowData, OnePuxItem } from "./1pux-parser";
|
import { OnePuxItem } from "./1pux-parser";
|
||||||
|
|
||||||
export interface ImportFormat {
|
export interface ImportFormat {
|
||||||
value: "csv" | "padlock-legacy" | "lastpass" | "padloc" | "1pux";
|
value: "csv" | "padlock-legacy" | "lastpass" | "padloc" | "1pux";
|
||||||
|
@ -101,27 +102,27 @@ export async function isCSV(data: string): Promise<Boolean> {
|
||||||
return papa.parse(data).errors.length === 0;
|
return papa.parse(data).errors.length === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function asCSV(data: string, nameColIndex?: number, tagsColIndex?: number): Promise<VaultItem[]> {
|
export async function asCSV(file: File, nameColIndex?: number, tagsColIndex?: number): Promise<VaultItem[]> {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
const papa = await loadPapa();
|
const papa = await loadPapa();
|
||||||
const parsed = papa.parse(data);
|
const parsed = papa.parse(data);
|
||||||
if (parsed.errors.length) {
|
if (parsed.errors.length) {
|
||||||
throw new Err(ErrorCode.INVALID_CSV);
|
throw new Err(ErrorCode.INVALID_CSV, "Failed to parse .csv file.");
|
||||||
}
|
}
|
||||||
return fromTable(parsed.data, nameColIndex, tagsColIndex);
|
return fromTable(parsed.data, nameColIndex, tagsColIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export async function isPadlockV1(file: File): Promise<boolean> {
|
||||||
* Checks if a given string represents a Padlock enrypted backup
|
|
||||||
*/
|
|
||||||
export function isPadlockV1(data: string): boolean {
|
|
||||||
try {
|
try {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
return validateLegacyContainer(unmarshal(data));
|
return validateLegacyContainer(unmarshal(data));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function asPadlockLegacy(data: string, password: string): Promise<VaultItem[]> {
|
export async function asPadlockLegacy(file: File, password: string): Promise<VaultItem[]> {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
const container = parseLegacyContainer(unmarshal(data));
|
const container = parseLegacyContainer(unmarshal(data));
|
||||||
await container.unlock(password);
|
await container.unlock(password);
|
||||||
return importLegacyContainer(container);
|
return importLegacyContainer(container);
|
||||||
|
@ -146,16 +147,18 @@ export async function importLegacyContainer(container: PBES2Container) {
|
||||||
return Promise.all(items);
|
return Promise.all(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isPBES2Container(data: string) {
|
export async function isPBES2Container(file: File) {
|
||||||
try {
|
try {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
new PBES2Container().fromRaw(unmarshal(data));
|
new PBES2Container().fromRaw(unmarshal(data));
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function asPBES2Container(data: string, password: string): Promise<VaultItem[]> {
|
export async function asPBES2Container(file: File, password: string): Promise<VaultItem[]> {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
const container = new PBES2Container().fromRaw(unmarshal(data));
|
const container = new PBES2Container().fromRaw(unmarshal(data));
|
||||||
await container.unlock(password);
|
await container.unlock(password);
|
||||||
|
|
||||||
|
@ -234,7 +237,8 @@ async function lpParseRow(row: string[]): Promise<VaultItem> {
|
||||||
return createVaultItem(row[nameIndex], fields, dir ? [dir] : []);
|
return createVaultItem(row[nameIndex], fields, dir ? [dir] : []);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function asLastPass(data: string): Promise<VaultItem[]> {
|
export async function asLastPass(file: File): Promise<VaultItem[]> {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
const papa = await loadPapa();
|
const papa = await loadPapa();
|
||||||
let items = papa
|
let items = papa
|
||||||
.parse(data)
|
.parse(data)
|
||||||
|
@ -247,22 +251,26 @@ export async function asLastPass(data: string): Promise<VaultItem[]> {
|
||||||
return Promise.all(items);
|
return Promise.all(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
export async function isLastPass(file: File): Promise<boolean> {
|
||||||
* Checks if a given string represents a LastPass CSV file
|
|
||||||
*/
|
|
||||||
export function isLastPass(data: string): boolean {
|
|
||||||
try {
|
try {
|
||||||
|
const data = await readFileAsText(file);
|
||||||
return data.split("\n")[0] === "url,username,password,extra,name,grouping,fav";
|
return data.split("\n")[0] === "url,username,password,extra,name,grouping,fav";
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function parse1PuxItem(accountName: string, vaultName: string, item: OnePuxItem['item']): Promise<VaultItem | undefined> {
|
async function parse1PuxItem(
|
||||||
|
accountName: string,
|
||||||
|
vaultName: string,
|
||||||
|
item: OnePuxItem["item"]
|
||||||
|
): Promise<VaultItem | undefined> {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { parseToRowData } = await import("./1pux-parser");
|
||||||
|
|
||||||
const rowData = parseToRowData(item, [accountName, vaultName]);
|
const rowData = parseToRowData(item, [accountName, vaultName]);
|
||||||
|
|
||||||
if (!rowData) {
|
if (!rowData) {
|
||||||
|
@ -270,10 +278,10 @@ async function parse1PuxItem(accountName: string, vaultName: string, item: OnePu
|
||||||
}
|
}
|
||||||
|
|
||||||
const itemName = rowData.name;
|
const itemName = rowData.name;
|
||||||
const tags = rowData.tags.split(',');
|
const tags = rowData.tags.split(",");
|
||||||
|
|
||||||
if (item.trashed) {
|
if (item.trashed) {
|
||||||
tags.push('trashed');
|
tags.push("trashed");
|
||||||
}
|
}
|
||||||
|
|
||||||
let fields: Field[] = [
|
let fields: Field[] = [
|
||||||
|
@ -287,10 +295,10 @@ async function parse1PuxItem(accountName: string, vaultName: string, item: OnePu
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const extraField of rowData.extraFields) {
|
for (const extraField of rowData.extraFields) {
|
||||||
if (extraField.type === 'totp') {
|
if (extraField.type === "totp") {
|
||||||
// Extract just the secret
|
// Extract just the secret
|
||||||
try {
|
try {
|
||||||
const secret = new URL(extraField.value).searchParams.get('secret');
|
const secret = new URL(extraField.value).searchParams.get("secret");
|
||||||
if (secret) {
|
if (secret) {
|
||||||
fields.push(new Field({ name: extraField.name, value: secret, type: FieldType.Totp }));
|
fields.push(new Field({ name: extraField.name, value: secret, type: FieldType.Totp }));
|
||||||
}
|
}
|
||||||
|
@ -298,24 +306,23 @@ async function parse1PuxItem(accountName: string, vaultName: string, item: OnePu
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fields.push(new Field({ name: extraField.name, value: extraField.value, type: extraField.type as FieldType }));
|
fields.push(
|
||||||
|
new Field({ name: extraField.name, value: extraField.value, type: extraField.type as FieldType })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return createVaultItem(itemName, fields, tags);
|
return createVaultItem(itemName, fields, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function as1Pux(data: null | string | ArrayBuffer): Promise<VaultItem[]> {
|
export async function as1Pux(file: File): Promise<VaultItem[]> {
|
||||||
if (!data) {
|
|
||||||
throw new Err(ErrorCode.INVALID_1PUX);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
const { parse1PuxFile } = await import("./1pux-parser");
|
||||||
|
const data = await readFileAsArrayBuffer(file);
|
||||||
const dataExport = await parse1PuxFile(data);
|
const dataExport = await parse1PuxFile(data);
|
||||||
|
|
||||||
const items = [];
|
const items = [];
|
||||||
|
|
||||||
for (const account of dataExport.data.accounts) {
|
for (const account of dataExport.data.accounts) {
|
||||||
for (const vault of account.vaults) {
|
for (const vault of account.vaults) {
|
||||||
for (const vaultItem of vault.items) {
|
for (const vaultItem of vault.items) {
|
||||||
|
@ -331,7 +338,7 @@ export async function as1Pux(data: null | string | ArrayBuffer): Promise<VaultIt
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new Err(ErrorCode.INVALID_1PUX);
|
throw new Err(ErrorCode.INVALID_1PUX, "Failed to parse .1pux file.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,30 +346,23 @@ export async function as1Pux(data: null | string | ArrayBuffer): Promise<VaultIt
|
||||||
* Checks if a given file name ends with .1pux to avoid trying to parse unnecessarily
|
* Checks if a given file name ends with .1pux to avoid trying to parse unnecessarily
|
||||||
*/
|
*/
|
||||||
export function is1Pux(file: File): boolean {
|
export function is1Pux(file: File): boolean {
|
||||||
return file.name.endsWith('.1pux');
|
return file.name.endsWith(".1pux");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function guessFormat(file: File, data: string | null | ArrayBuffer): ImportFormat {
|
export async function guessFormat(file: File): Promise<ImportFormat> {
|
||||||
if (isPBES2Container(data as string)) {
|
// Try to guess sync first (won't need parsing)
|
||||||
return PBES2;
|
|
||||||
}
|
|
||||||
if (isPadlockV1(data as string)) {
|
|
||||||
return PADLOCK_LEGACY;
|
|
||||||
}
|
|
||||||
if (isLastPass(data as string)) {
|
|
||||||
return LASTPASS;
|
|
||||||
}
|
|
||||||
if (is1Pux(file)) {
|
if (is1Pux(file)) {
|
||||||
return ONEPUX;
|
return ONEPUX;
|
||||||
}
|
}
|
||||||
|
if (await isPBES2Container(file)) {
|
||||||
return CSV;
|
return PBES2;
|
||||||
}
|
}
|
||||||
|
if (await isPadlockV1(file)) {
|
||||||
export function doesFileRequireReadingAsBinary(file: File): boolean {
|
return PADLOCK_LEGACY;
|
||||||
if (is1Pux(file)) {
|
}
|
||||||
return true;
|
if (await isLastPass(file)) {
|
||||||
|
return LASTPASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return CSV;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
|
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes" />
|
||||||
<title>lit-element tests</title>
|
<title>lit-element tests</title>
|
||||||
<link href="../node_modules/mocha/mocha.css" rel="stylesheet" />
|
<link href="../node_modules/mocha/mocha.css" rel="stylesheet" />
|
||||||
<script src="../node_modules/mocha/mocha.js"></script>
|
<script src="../node_modules/mocha/mocha.js"></script>
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
<script>
|
<script>
|
||||||
mocha.setup({
|
mocha.setup({
|
||||||
ui: "tdd",
|
ui: "tdd",
|
||||||
timeout: 1000000
|
timeout: 1000000,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<script type="module" src="dist/crypto.js"></script>
|
<script type="module" src="dist/crypto.js"></script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
interface Navigator {
|
interface Navigator {
|
||||||
Backbutton: any
|
Backbutton: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|
|
@ -1,82 +1,82 @@
|
||||||
{
|
{
|
||||||
"name": "app.padloc",
|
"name": "app.padloc",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"displayName": "Padloc",
|
"displayName": "Padloc",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
},
|
},
|
||||||
"cordova": {
|
"cordova": {
|
||||||
"platforms": [
|
"platforms": [
|
||||||
"ios",
|
"ios",
|
||||||
"android"
|
"android"
|
||||||
],
|
],
|
||||||
"plugins": {
|
"plugins": {
|
||||||
"cordova-plugin-app-version": {},
|
"cordova-plugin-app-version": {},
|
||||||
"cordova-plugin-backbutton": {},
|
"cordova-plugin-backbutton": {},
|
||||||
"ionic-plugin-keyboard": {},
|
"ionic-plugin-keyboard": {},
|
||||||
"cordova-plugin-statusbar": {},
|
"cordova-plugin-statusbar": {},
|
||||||
"cordova-clipboard": {},
|
"cordova-clipboard": {},
|
||||||
"cordova-plugin-qrscanner": {},
|
"cordova-plugin-qrscanner": {},
|
||||||
"cordova-plugin-device": {},
|
"cordova-plugin-device": {},
|
||||||
"cordova-plugin-x-socialsharing": {
|
"cordova-plugin-x-socialsharing": {
|
||||||
"ANDROID_SUPPORT_V4_VERSION": "24.1.1+",
|
"ANDROID_SUPPORT_V4_VERSION": "24.1.1+",
|
||||||
"PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION": "This app requires photo library access to function properly.",
|
"PHOTO_LIBRARY_ADD_USAGE_DESCRIPTION": "This app requires photo library access to function properly.",
|
||||||
"PHOTO_LIBRARY_USAGE_DESCRIPTION": "This app requires photo library access to function properly."
|
"PHOTO_LIBRARY_USAGE_DESCRIPTION": "This app requires photo library access to function properly."
|
||||||
},
|
},
|
||||||
"cordova-plugin-splashscreen": {},
|
"cordova-plugin-splashscreen": {},
|
||||||
"cordova-plugin-ionic-webview": {
|
"cordova-plugin-ionic-webview": {
|
||||||
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
|
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
|
||||||
},
|
},
|
||||||
"cordova-plugin-fingerprint-aio": {
|
"cordova-plugin-fingerprint-aio": {
|
||||||
"FACEID_USAGE_DESCRIPTION": " "
|
"FACEID_USAGE_DESCRIPTION": " "
|
||||||
},
|
},
|
||||||
"cordova-plugin-privacyscreen": {},
|
"cordova-plugin-privacyscreen": {},
|
||||||
"cordova-plugin-inappbrowser": {},
|
"cordova-plugin-inappbrowser": {},
|
||||||
"cordova-plugin-androidx-adapter": {}
|
"cordova-plugin-androidx-adapter": {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@padloc/app": "4.0.0",
|
||||||
|
"@padloc/core": "4.0.0",
|
||||||
|
"cordova-clipboard": "1.3.0",
|
||||||
|
"cordova-ios": "6.2.0",
|
||||||
|
"cordova-plugin-add-swift-support": "2.0.2",
|
||||||
|
"cordova-plugin-app-version": "~0.1.12",
|
||||||
|
"cordova-plugin-backbutton": "~0.3.0",
|
||||||
|
"cordova-plugin-device": "2.0.3",
|
||||||
|
"cordova-plugin-inappbrowser": "5.0.0",
|
||||||
|
"cordova-plugin-ionic-webview": "5.0.0",
|
||||||
|
"cordova-plugin-privacyscreen": "0.4.0",
|
||||||
|
"cordova-plugin-qrscanner": "3.0.1",
|
||||||
|
"cordova-plugin-splashscreen": "6.0.0",
|
||||||
|
"cordova-plugin-statusbar": "2.4.3",
|
||||||
|
"cordova-plugin-x-socialsharing": "6.0.3",
|
||||||
|
"cordova-plugin-androidx-adapter": "1.1.3",
|
||||||
|
"cordova-plugin-fingerprint-aio": "4.0.2",
|
||||||
|
"es6-promise-plugin": "4.2.2",
|
||||||
|
"ionic-plugin-keyboard": "~2.2.1",
|
||||||
|
"typescript": "4.4.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/cordova-plugin-qrscanner": "1.0.31",
|
||||||
|
"clean-webpack-plugin": "3.0.0",
|
||||||
|
"cordova": "10.0.0",
|
||||||
|
"cordova-android": "10.1.0",
|
||||||
|
"css-loader": "5.2.6",
|
||||||
|
"file-loader": "6.2.0",
|
||||||
|
"html-webpack-plugin": "5.3.1",
|
||||||
|
"style-loader": "2.0.0",
|
||||||
|
"ts-loader": "9.2.2",
|
||||||
|
"ts-node": "10.0.0",
|
||||||
|
"webpack": "5.38.1",
|
||||||
|
"webpack-cli": "4.7.0",
|
||||||
|
"sharp": "0.29.1",
|
||||||
|
"raw-loader": "4.0.2"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "webpack",
|
||||||
|
"start": "npm run build && cordova run"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@padloc/app": "4.0.0",
|
|
||||||
"@padloc/core": "4.0.0",
|
|
||||||
"cordova-clipboard": "1.3.0",
|
|
||||||
"cordova-ios": "6.2.0",
|
|
||||||
"cordova-plugin-add-swift-support": "2.0.2",
|
|
||||||
"cordova-plugin-app-version": "~0.1.12",
|
|
||||||
"cordova-plugin-backbutton": "~0.3.0",
|
|
||||||
"cordova-plugin-device": "2.0.3",
|
|
||||||
"cordova-plugin-inappbrowser": "5.0.0",
|
|
||||||
"cordova-plugin-ionic-webview": "5.0.0",
|
|
||||||
"cordova-plugin-privacyscreen": "0.4.0",
|
|
||||||
"cordova-plugin-qrscanner": "3.0.1",
|
|
||||||
"cordova-plugin-splashscreen": "6.0.0",
|
|
||||||
"cordova-plugin-statusbar": "2.4.3",
|
|
||||||
"cordova-plugin-x-socialsharing": "6.0.3",
|
|
||||||
"cordova-plugin-androidx-adapter": "1.1.3",
|
|
||||||
"cordova-plugin-fingerprint-aio": "4.0.2",
|
|
||||||
"es6-promise-plugin": "4.2.2",
|
|
||||||
"ionic-plugin-keyboard": "~2.2.1",
|
|
||||||
"typescript": "4.4.3"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/cordova-plugin-qrscanner": "1.0.31",
|
|
||||||
"clean-webpack-plugin": "3.0.0",
|
|
||||||
"cordova": "10.0.0",
|
|
||||||
"cordova-android": "10.1.0",
|
|
||||||
"css-loader": "5.2.6",
|
|
||||||
"file-loader": "6.2.0",
|
|
||||||
"html-webpack-plugin": "5.3.1",
|
|
||||||
"style-loader": "2.0.0",
|
|
||||||
"ts-loader": "9.2.2",
|
|
||||||
"ts-node": "10.0.0",
|
|
||||||
"webpack": "5.38.1",
|
|
||||||
"webpack-cli": "4.7.0",
|
|
||||||
"sharp": "0.29.1",
|
|
||||||
"raw-loader": "4.0.2"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"build": "webpack",
|
|
||||||
"start": "npm run build && cordova run"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,4 +13,3 @@
|
||||||
"include": ["src/**/*.ts", "../app/types/*.ts"],
|
"include": ["src/**/*.ts", "../app/types/*.ts"],
|
||||||
"exclude": ["node_modules/**/*.ts"]
|
"exclude": ["node_modules/**/*.ts"]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,24 +105,7 @@ module.exports = {
|
||||||
.toBuffer();
|
.toBuffer();
|
||||||
|
|
||||||
const iosIconSizes = [
|
const iosIconSizes = [
|
||||||
20,
|
20, 29, 40, 50, 57, 58, 60, 72, 76, 80, 87, 100, 114, 120, 144, 152, 167, 180,
|
||||||
29,
|
|
||||||
40,
|
|
||||||
50,
|
|
||||||
57,
|
|
||||||
58,
|
|
||||||
60,
|
|
||||||
72,
|
|
||||||
76,
|
|
||||||
80,
|
|
||||||
87,
|
|
||||||
100,
|
|
||||||
114,
|
|
||||||
120,
|
|
||||||
144,
|
|
||||||
152,
|
|
||||||
167,
|
|
||||||
180,
|
|
||||||
];
|
];
|
||||||
|
|
||||||
const androidIconSizes = [36, 48, 72, 96, 144, 192];
|
const androidIconSizes = [36, 48, 72, 96, 144, 192];
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/core",
|
"name": "@padloc/core",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"description": "padloc core module",
|
"description": "padloc core module",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPLv3",
|
"license": "GPLv3",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"vendor",
|
"vendor",
|
||||||
"tsconfig.json"
|
"tsconfig.json"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/locale": "4.0.0",
|
"@padloc/locale": "4.0.0",
|
||||||
"typescript": "4.4.3"
|
"typescript": "4.4.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "4.2.18",
|
"@types/chai": "4.2.18",
|
||||||
"@types/mocha": "8.2.2",
|
"@types/mocha": "8.2.2",
|
||||||
"chai": "4.3.4",
|
"chai": "4.3.4",
|
||||||
"mocha": "8.4.0",
|
"mocha": "8.4.0",
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typedoc": "0.22.4"
|
"typedoc": "0.22.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "cd test && mocha -r ts-node/register *.ts",
|
"test": "cd test && mocha -r ts-node/register *.ts",
|
||||||
"docs": "typedoc --mode modules --out docs"
|
"docs": "typedoc --mode modules --out docs"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git",
|
"url": "https://github.com/padloc/padloc.git",
|
||||||
"directory": "packages/core"
|
"directory": "packages/core"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { getCryptoProvider as getProvider } from "./platform";
|
||||||
import { Err, ErrorCode } from "./error";
|
import { Err, ErrorCode } from "./error";
|
||||||
import { RequestProgress } from "./transport";
|
import { RequestProgress } from "./transport";
|
||||||
|
|
||||||
function readFile(blob: File): Promise<Uint8Array> {
|
export async function readFileAsUint8Array(blob: File): Promise<Uint8Array> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
@ -15,16 +15,33 @@ function readFile(blob: File): Promise<Uint8Array> {
|
||||||
resolve(result);
|
resolve(result);
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.onerror = e => {
|
reader.onerror = (error) => {
|
||||||
reader.abort();
|
reader.abort();
|
||||||
reject(e);
|
reject(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.readAsArrayBuffer(blob);
|
reader.readAsArrayBuffer(blob);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function readAsText(blob: File): Promise<string> {
|
export async function readFileAsArrayBuffer(blob: File): Promise<ArrayBuffer> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
reader.onload = () => {
|
||||||
|
resolve(reader.result as ArrayBuffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.onerror = (error) => {
|
||||||
|
reader.abort();
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsArrayBuffer(blob);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function readFileAsText(blob: File): Promise<string> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
|
@ -32,9 +49,9 @@ function readAsText(blob: File): Promise<string> {
|
||||||
resolve(reader.result as string);
|
resolve(reader.result as string);
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.onerror = e => {
|
reader.onerror = (error) => {
|
||||||
reader.abort();
|
reader.abort();
|
||||||
reject(e);
|
reject(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.readAsText(blob);
|
reader.readAsText(blob);
|
||||||
|
@ -49,7 +66,7 @@ function readFileAsDataURL(blob: File): Promise<string> {
|
||||||
resolve(reader.result as string);
|
resolve(reader.result as string);
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.onerror = e => {
|
reader.onerror = (e) => {
|
||||||
reader.abort();
|
reader.abort();
|
||||||
reject(e);
|
reject(e);
|
||||||
};
|
};
|
||||||
|
@ -89,7 +106,7 @@ export class Attachment extends SimpleContainer {
|
||||||
super();
|
super();
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
_key: key,
|
_key: key,
|
||||||
...info
|
...info,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +117,7 @@ export class Attachment extends SimpleContainer {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
type: this.type,
|
type: this.type,
|
||||||
size: this.size,
|
size: this.size,
|
||||||
key: this._key
|
key: this._key,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,11 +130,11 @@ export class Attachment extends SimpleContainer {
|
||||||
this.size = file.size;
|
this.size = file.size;
|
||||||
this.name = file.name;
|
this.name = file.name;
|
||||||
|
|
||||||
const data = await readFile(file);
|
const data = await readFileAsUint8Array(file);
|
||||||
|
|
||||||
this._key = await getProvider().generateKey({
|
this._key = await getProvider().generateKey({
|
||||||
algorithm: "AES",
|
algorithm: "AES",
|
||||||
keySize: this.encryptionParams.keySize
|
keySize: this.encryptionParams.keySize,
|
||||||
} as AESKeyParams);
|
} as AESKeyParams);
|
||||||
|
|
||||||
await this.setData(data);
|
await this.setData(data);
|
||||||
|
@ -141,7 +158,7 @@ export class Attachment extends SimpleContainer {
|
||||||
|
|
||||||
async toText(): Promise<string> {
|
async toText(): Promise<string> {
|
||||||
const file = await this.toFile();
|
const file = await this.toFile();
|
||||||
return readAsText(file);
|
return readFileAsText(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
validate() {
|
validate() {
|
||||||
|
|
|
@ -7,7 +7,7 @@ export enum PlanType {
|
||||||
Premium,
|
Premium,
|
||||||
Family,
|
Family,
|
||||||
Team,
|
Team,
|
||||||
Business
|
Business,
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Plan extends Serializable {
|
export class Plan extends Serializable {
|
||||||
|
@ -37,7 +37,7 @@ export enum SubscriptionStatus {
|
||||||
Trialing = "trialing",
|
Trialing = "trialing",
|
||||||
Active = "active",
|
Active = "active",
|
||||||
Inactive = "inactive",
|
Inactive = "inactive",
|
||||||
Canceled = "canceled"
|
Canceled = "canceled",
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Subscription extends Serializable {
|
export class Subscription extends Serializable {
|
||||||
|
|
|
@ -41,10 +41,10 @@ export class Client extends API {
|
||||||
method,
|
method,
|
||||||
typeof input === "undefined" ? [] : [input instanceof Serializable ? input.toRaw() : input],
|
typeof input === "undefined" ? [] : [input instanceof Serializable ? input.toRaw() : input],
|
||||||
progress
|
progress
|
||||||
).then(res => {
|
).then((res) => {
|
||||||
return output
|
return output
|
||||||
? Array.isArray(res.result)
|
? Array.isArray(res.result)
|
||||||
? res.result.map(each => new output().fromRaw(each))
|
? res.result.map((each) => new output().fromRaw(each))
|
||||||
: new output().fromRaw(res.result)
|
: new output().fromRaw(res.result)
|
||||||
: res.result;
|
: res.result;
|
||||||
}) as PromiseWithProgress<any>;
|
}) as PromiseWithProgress<any>;
|
||||||
|
@ -85,7 +85,7 @@ export class Client extends API {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.error) {
|
if (res.error) {
|
||||||
const err = new Err((res.error.code as any) as ErrorCode, res.error.message);
|
const err = new Err(res.error.code as any as ErrorCode, res.error.message);
|
||||||
if (progress) {
|
if (progress) {
|
||||||
progress.error = err;
|
progress.error = err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ export class VaultItemCollection extends Serializable implements Iterable<VaultI
|
||||||
|
|
||||||
constructor(items: VaultItem[] = []) {
|
constructor(items: VaultItem[] = []) {
|
||||||
super();
|
super();
|
||||||
this._items = new Map(items.map(item => [item.id, item] as [string, VaultItem]));
|
this._items = new Map(items.map((item) => [item.id, item] as [string, VaultItem]));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get an item with a given `id` */
|
/** Get an item with a given `id` */
|
||||||
|
@ -91,8 +91,8 @@ export class VaultItemCollection extends Serializable implements Iterable<VaultI
|
||||||
|
|
||||||
protected _toRaw(version: string) {
|
protected _toRaw(version: string) {
|
||||||
return {
|
return {
|
||||||
items: Array.from(this).map(item => item.toRaw(version)),
|
items: Array.from(this).map((item) => item.toRaw(version)),
|
||||||
changes: [...this._changes]
|
changes: [...this._changes],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,15 +65,15 @@ export function parseLegacyContainer(raw: LegacyContainer): PBES2Container {
|
||||||
tagSize: raw.ts,
|
tagSize: raw.ts,
|
||||||
keySize: raw.keySize,
|
keySize: raw.keySize,
|
||||||
iv: raw.iv,
|
iv: raw.iv,
|
||||||
additionalData: raw.adata
|
additionalData: raw.adata,
|
||||||
},
|
},
|
||||||
keyParams: {
|
keyParams: {
|
||||||
algorithm: "PBKDF2",
|
algorithm: "PBKDF2",
|
||||||
hash: "SHA-256",
|
hash: "SHA-256",
|
||||||
keySize: raw.keySize,
|
keySize: raw.keySize,
|
||||||
iterations: raw.iter,
|
iterations: raw.iter,
|
||||||
salt: raw.salt
|
salt: raw.salt,
|
||||||
},
|
},
|
||||||
encryptedData: raw.ct
|
encryptedData: raw.ct,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,22 +20,22 @@ export const MIGRATIONS: Migration[] = [
|
||||||
up: ({ mainVault, orgs, ...rest }: any) => ({
|
up: ({ mainVault, orgs, ...rest }: any) => ({
|
||||||
mainVault: { id: mainVault },
|
mainVault: { id: mainVault },
|
||||||
orgs: orgs.map((org: any) => ({
|
orgs: orgs.map((org: any) => ({
|
||||||
id: org
|
id: org,
|
||||||
})),
|
})),
|
||||||
...rest
|
...rest,
|
||||||
}),
|
}),
|
||||||
down: ({ mainVault, orgs, ...rest }: any) => ({
|
down: ({ mainVault, orgs, ...rest }: any) => ({
|
||||||
mainVault: mainVault.id,
|
mainVault: mainVault.id,
|
||||||
orgs: orgs.map((org: any) => org.id),
|
orgs: orgs.map((org: any) => org.id),
|
||||||
...rest
|
...rest,
|
||||||
})
|
}),
|
||||||
},
|
},
|
||||||
all: {
|
all: {
|
||||||
up: (raw: any, kind?: string) => ({ kind, ...raw }),
|
up: (raw: any, kind?: string) => ({ kind, ...raw }),
|
||||||
down: ({ kind, ...rest }) => rest
|
down: ({ kind, ...rest }) => rest,
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
export const EARLIEST_VERSION = MIGRATIONS[0].from;
|
export const EARLIEST_VERSION = MIGRATIONS[0].from;
|
||||||
|
@ -44,7 +44,7 @@ export const LATEST_VERSION = MIGRATIONS[MIGRATIONS.length - 1].to;
|
||||||
function norm(version: string = EARLIEST_VERSION): string {
|
function norm(version: string = EARLIEST_VERSION): string {
|
||||||
return version
|
return version
|
||||||
.split(".")
|
.split(".")
|
||||||
.map(part => part.padStart(3, "0"))
|
.map((part) => part.padStart(3, "0"))
|
||||||
.join();
|
.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ export function upgrade(kind: string, raw: any, version: string = LATEST_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
const migration = MIGRATIONS.find(
|
const migration = MIGRATIONS.find(
|
||||||
m => norm(m.from) >= norm(raw.version || EARLIEST_VERSION) && norm(m.to) <= norm(version)
|
(m) => norm(m.from) >= norm(raw.version || EARLIEST_VERSION) && norm(m.to) <= norm(version)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (migration) {
|
if (migration) {
|
||||||
|
@ -76,7 +76,7 @@ export function upgrade(kind: string, raw: any, version: string = LATEST_VERSION
|
||||||
|
|
||||||
export function downgrade(kind: string, raw: any, version: string = LATEST_VERSION): any {
|
export function downgrade(kind: string, raw: any, version: string = LATEST_VERSION): any {
|
||||||
const migration = MIGRATIONS.reverse().find(
|
const migration = MIGRATIONS.reverse().find(
|
||||||
m => norm(m.to) <= norm(raw.version || LATEST_VERSION) && norm(m.from) >= norm(version)
|
(m) => norm(m.to) <= norm(raw.version || LATEST_VERSION) && norm(m.from) >= norm(version)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (migration) {
|
if (migration) {
|
||||||
|
|
|
@ -115,9 +115,7 @@ export interface Platform {
|
||||||
authenticatorIndex?: number;
|
authenticatorIndex?: number;
|
||||||
}): Promise<StartAuthRequestResponse>;
|
}): Promise<StartAuthRequestResponse>;
|
||||||
|
|
||||||
completeAuthRequest(
|
completeAuthRequest(req: StartAuthRequestResponse): Promise<{
|
||||||
req: StartAuthRequestResponse
|
|
||||||
): Promise<{
|
|
||||||
token: string;
|
token: string;
|
||||||
accountStatus: AccountStatus;
|
accountStatus: AccountStatus;
|
||||||
deviceTrusted: boolean;
|
deviceTrusted: boolean;
|
||||||
|
@ -193,9 +191,7 @@ export class StubPlatform implements Platform {
|
||||||
throw new Error("Method not implemented.");
|
throw new Error("Method not implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
async completeAuthRequest(
|
async completeAuthRequest(_req: StartAuthRequestResponse): Promise<{
|
||||||
_req: StartAuthRequestResponse
|
|
||||||
): Promise<{
|
|
||||||
token: string;
|
token: string;
|
||||||
accountStatus: AccountStatus;
|
accountStatus: AccountStatus;
|
||||||
deviceTrusted: boolean;
|
deviceTrusted: boolean;
|
||||||
|
@ -293,9 +289,7 @@ export function startAuthRequest(opts: {
|
||||||
return platform.startAuthRequest(opts);
|
return platform.startAuthRequest(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function completeAuthRequest(
|
export function completeAuthRequest(req: StartAuthRequestResponse): Promise<{
|
||||||
req: StartAuthRequestResponse
|
|
||||||
): Promise<{
|
|
||||||
token: string;
|
token: string;
|
||||||
accountStatus: AccountStatus;
|
accountStatus: AccountStatus;
|
||||||
deviceTrusted: boolean;
|
deviceTrusted: boolean;
|
||||||
|
|
|
@ -30,7 +30,7 @@ type Position = [number, number];
|
||||||
export const defaults: Options = {
|
export const defaults: Options = {
|
||||||
height: 9,
|
height: 9,
|
||||||
width: 17,
|
width: 17,
|
||||||
symbols: [" ", ".", "o", "+", "=", "*", "B", "O", "X", "@", "%", "&", "#", "/", "^", "S", "E"]
|
symbols: [" ", ".", "o", "+", "=", "*", "B", "O", "X", "@", "%", "&", "#", "/", "^", "S", "E"],
|
||||||
};
|
};
|
||||||
|
|
||||||
// Converts a buffer to a binary moves array
|
// Converts a buffer to a binary moves array
|
||||||
|
@ -120,6 +120,6 @@ export function randomArt(fingerprint: Uint8Array, opts: Partial<Options> = {}):
|
||||||
width: options.width,
|
width: options.width,
|
||||||
height: options.height,
|
height: options.height,
|
||||||
values: vals,
|
values: vals,
|
||||||
symbols: vals.map(line => line.map(val => symbols[val]))
|
symbols: vals.map((line) => line.map((val) => symbols[val])),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ const SJCLProvider = {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Err(ErrorCode.ENCRYPTION_FAILED);
|
throw new Err(ErrorCode.ENCRYPTION_FAILED);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default SJCLProvider;
|
export default SJCLProvider;
|
||||||
|
|
|
@ -29,12 +29,12 @@ export function appSpec(): Spec {
|
||||||
const user = {
|
const user = {
|
||||||
email: "lengden@olga.com",
|
email: "lengden@olga.com",
|
||||||
name: "Lengden Olga",
|
name: "Lengden Olga",
|
||||||
password: "correct battery horse staple"
|
password: "correct battery horse staple",
|
||||||
};
|
};
|
||||||
const otherUser = {
|
const otherUser = {
|
||||||
email: "max@mustermann.com",
|
email: "max@mustermann.com",
|
||||||
name: "Max Mustermann",
|
name: "Max Mustermann",
|
||||||
password: "password"
|
password: "password",
|
||||||
};
|
};
|
||||||
let sharedVaultID = "";
|
let sharedVaultID = "";
|
||||||
// let otherVaultID = "";
|
// let otherVaultID = "";
|
||||||
|
@ -191,7 +191,7 @@ export function appSpec(): Spec {
|
||||||
test("Simulataneous Edit", async () => {
|
test("Simulataneous Edit", async () => {
|
||||||
const [item1, item2] = await Promise.all([
|
const [item1, item2] = await Promise.all([
|
||||||
app.createItem("Added Item 1", { id: sharedVaultID }),
|
app.createItem("Added Item 1", { id: sharedVaultID }),
|
||||||
otherApp.createItem("Added Item 2", { id: sharedVaultID })
|
otherApp.createItem("Added Item 2", { id: sharedVaultID }),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await Promise.all([app.syncVault({ id: sharedVaultID }), otherApp.syncVault({ id: sharedVaultID })]);
|
await Promise.all([app.syncVault({ id: sharedVaultID }), otherApp.syncVault({ id: sharedVaultID })]);
|
||||||
|
|
|
@ -7,7 +7,7 @@ import {
|
||||||
HMACKeyParams,
|
HMACKeyParams,
|
||||||
PBKDF2Params,
|
PBKDF2Params,
|
||||||
RSASigningParams,
|
RSASigningParams,
|
||||||
RSAEncryptionParams
|
RSAEncryptionParams,
|
||||||
} from "../crypto";
|
} from "../crypto";
|
||||||
import { Spec } from "./spec";
|
import { Spec } from "./spec";
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ const fixtures = {
|
||||||
plain: stringToBytes("Hello World!"),
|
plain: stringToBytes("Hello World!"),
|
||||||
encrypted: base64ToBytes(
|
encrypted: base64ToBytes(
|
||||||
"eAJDfWUdgL4Wl0UDsA0WsmHE29MNAnTvSjus3N0BP6foD0fFZBlrfmRbF-KjY_2zYhgaqn7E4pEKMB20tPDC-JYcAJO8PMWOR6PdLBsBCUTbdYy062iwFWgWfzSFV2LDy-G2t9HL2CbDoDAdsh1fNGIm81nY9sXbB0kKM4uNXKTdVl49Cwf30jiRRpABV_tSPmQjkHDVWOphVEY5ex0hhveRC6vfO1YZ21-CuoTa1gRq-ab21V-Pl5rfQ0RHsDgtvvSJ8_3ihzCkOTjd2Anj0GiKEsCeV0NaEgT-e5WyDj2zYNIsVOoMmB65UUkXX002Ycc2cGuoYw2uudZQSaAlqg"
|
"eAJDfWUdgL4Wl0UDsA0WsmHE29MNAnTvSjus3N0BP6foD0fFZBlrfmRbF-KjY_2zYhgaqn7E4pEKMB20tPDC-JYcAJO8PMWOR6PdLBsBCUTbdYy062iwFWgWfzSFV2LDy-G2t9HL2CbDoDAdsh1fNGIm81nY9sXbB0kKM4uNXKTdVl49Cwf30jiRRpABV_tSPmQjkHDVWOphVEY5ex0hhveRC6vfO1YZ21-CuoTa1gRq-ab21V-Pl5rfQ0RHsDgtvvSJ8_3ihzCkOTjd2Anj0GiKEsCeV0NaEgT-e5WyDj2zYNIsVOoMmB65UUkXX002Ycc2cGuoYw2uudZQSaAlqg"
|
||||||
)
|
),
|
||||||
},
|
},
|
||||||
aes: {
|
aes: {
|
||||||
key: base64ToBytes("fe8Chv8F4je2wW3u67H6KFVtlRuH4VWBgN1FXPoOKAw"),
|
key: base64ToBytes("fe8Chv8F4je2wW3u67H6KFVtlRuH4VWBgN1FXPoOKAw"),
|
||||||
|
@ -34,8 +34,8 @@ const fixtures = {
|
||||||
iv: base64ToBytes("Tg9aODkCqoBQDktZAXLEhw"),
|
iv: base64ToBytes("Tg9aODkCqoBQDktZAXLEhw"),
|
||||||
additionalData: base64ToBytes("dJvkr9MnycfsAHiqZStEOg"),
|
additionalData: base64ToBytes("dJvkr9MnycfsAHiqZStEOg"),
|
||||||
plain: stringToBytes("Hello World!"),
|
plain: stringToBytes("Hello World!"),
|
||||||
encrypted: base64ToBytes("A4ODqQsZrMQ4hXxV-RyYVDhdjTvk1MQ7MG8j_A")
|
encrypted: base64ToBytes("A4ODqQsZrMQ4hXxV-RyYVDhdjTvk1MQ7MG8j_A"),
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export function cryptoProviderSpec(provider: CryptoProvider): Spec {
|
export function cryptoProviderSpec(provider: CryptoProvider): Spec {
|
||||||
|
@ -59,7 +59,7 @@ export function cryptoProviderSpec(provider: CryptoProvider): Spec {
|
||||||
|
|
||||||
let err;
|
let err;
|
||||||
try {
|
try {
|
||||||
await provider.hash(input, ({ algorithm: "BLAH" } as any) as HashParams);
|
await provider.hash(input, { algorithm: "BLAH" } as any as HashParams);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
err = e;
|
err = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ import {
|
||||||
AESEncryptionParams,
|
AESEncryptionParams,
|
||||||
RSAEncryptionParams,
|
RSAEncryptionParams,
|
||||||
HashParams,
|
HashParams,
|
||||||
RSASigningParams
|
RSASigningParams,
|
||||||
} from "./crypto";
|
} from "./crypto";
|
||||||
import { concatBytes as concat, equalBytes as equal } from "./encoding";
|
import { concatBytes as concat, equalBytes as equal } from "./encoding";
|
||||||
import { Err, ErrorCode } from "./error";
|
import { Err, ErrorCode } from "./error";
|
||||||
|
@ -50,7 +50,7 @@ export class StubCryptoProvider implements CryptoProvider {
|
||||||
const key = await this.randomBytes(32);
|
const key = await this.randomBytes(32);
|
||||||
return {
|
return {
|
||||||
publicKey: key,
|
publicKey: key,
|
||||||
privateKey: key
|
privateKey: key,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -172,10 +172,10 @@ export class BigInteger {
|
||||||
setBit(n: number): BigInteger;
|
setBit(n: number): BigInteger;
|
||||||
|
|
||||||
// (public) this & ~(1<<n)
|
// (public) this & ~(1<<n)
|
||||||
clearBit(n: number): BigInteger
|
clearBit(n: number): BigInteger;
|
||||||
|
|
||||||
// (public) this ^ (1<<n)
|
// (public) this ^ (1<<n)
|
||||||
flipBit(n: number): BigInteger
|
flipBit(n: number): BigInteger;
|
||||||
|
|
||||||
// (protected) r = this + a
|
// (protected) r = this + a
|
||||||
addTo(a: BigInteger, r: BigInteger): void;
|
addTo(a: BigInteger, r: BigInteger): void;
|
||||||
|
|
|
@ -1369,174 +1369,14 @@ function bnModInverse(m) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var lowprimes = [
|
var lowprimes = [
|
||||||
2,
|
2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109,
|
||||||
3,
|
113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239,
|
||||||
5,
|
241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
|
||||||
7,
|
383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521,
|
||||||
11,
|
523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
|
||||||
13,
|
673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827,
|
||||||
17,
|
829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991,
|
||||||
19,
|
997,
|
||||||
23,
|
|
||||||
29,
|
|
||||||
31,
|
|
||||||
37,
|
|
||||||
41,
|
|
||||||
43,
|
|
||||||
47,
|
|
||||||
53,
|
|
||||||
59,
|
|
||||||
61,
|
|
||||||
67,
|
|
||||||
71,
|
|
||||||
73,
|
|
||||||
79,
|
|
||||||
83,
|
|
||||||
89,
|
|
||||||
97,
|
|
||||||
101,
|
|
||||||
103,
|
|
||||||
107,
|
|
||||||
109,
|
|
||||||
113,
|
|
||||||
127,
|
|
||||||
131,
|
|
||||||
137,
|
|
||||||
139,
|
|
||||||
149,
|
|
||||||
151,
|
|
||||||
157,
|
|
||||||
163,
|
|
||||||
167,
|
|
||||||
173,
|
|
||||||
179,
|
|
||||||
181,
|
|
||||||
191,
|
|
||||||
193,
|
|
||||||
197,
|
|
||||||
199,
|
|
||||||
211,
|
|
||||||
223,
|
|
||||||
227,
|
|
||||||
229,
|
|
||||||
233,
|
|
||||||
239,
|
|
||||||
241,
|
|
||||||
251,
|
|
||||||
257,
|
|
||||||
263,
|
|
||||||
269,
|
|
||||||
271,
|
|
||||||
277,
|
|
||||||
281,
|
|
||||||
283,
|
|
||||||
293,
|
|
||||||
307,
|
|
||||||
311,
|
|
||||||
313,
|
|
||||||
317,
|
|
||||||
331,
|
|
||||||
337,
|
|
||||||
347,
|
|
||||||
349,
|
|
||||||
353,
|
|
||||||
359,
|
|
||||||
367,
|
|
||||||
373,
|
|
||||||
379,
|
|
||||||
383,
|
|
||||||
389,
|
|
||||||
397,
|
|
||||||
401,
|
|
||||||
409,
|
|
||||||
419,
|
|
||||||
421,
|
|
||||||
431,
|
|
||||||
433,
|
|
||||||
439,
|
|
||||||
443,
|
|
||||||
449,
|
|
||||||
457,
|
|
||||||
461,
|
|
||||||
463,
|
|
||||||
467,
|
|
||||||
479,
|
|
||||||
487,
|
|
||||||
491,
|
|
||||||
499,
|
|
||||||
503,
|
|
||||||
509,
|
|
||||||
521,
|
|
||||||
523,
|
|
||||||
541,
|
|
||||||
547,
|
|
||||||
557,
|
|
||||||
563,
|
|
||||||
569,
|
|
||||||
571,
|
|
||||||
577,
|
|
||||||
587,
|
|
||||||
593,
|
|
||||||
599,
|
|
||||||
601,
|
|
||||||
607,
|
|
||||||
613,
|
|
||||||
617,
|
|
||||||
619,
|
|
||||||
631,
|
|
||||||
641,
|
|
||||||
643,
|
|
||||||
647,
|
|
||||||
653,
|
|
||||||
659,
|
|
||||||
661,
|
|
||||||
673,
|
|
||||||
677,
|
|
||||||
683,
|
|
||||||
691,
|
|
||||||
701,
|
|
||||||
709,
|
|
||||||
719,
|
|
||||||
727,
|
|
||||||
733,
|
|
||||||
739,
|
|
||||||
743,
|
|
||||||
751,
|
|
||||||
757,
|
|
||||||
761,
|
|
||||||
769,
|
|
||||||
773,
|
|
||||||
787,
|
|
||||||
797,
|
|
||||||
809,
|
|
||||||
811,
|
|
||||||
821,
|
|
||||||
823,
|
|
||||||
827,
|
|
||||||
829,
|
|
||||||
839,
|
|
||||||
853,
|
|
||||||
857,
|
|
||||||
859,
|
|
||||||
863,
|
|
||||||
877,
|
|
||||||
881,
|
|
||||||
883,
|
|
||||||
887,
|
|
||||||
907,
|
|
||||||
911,
|
|
||||||
919,
|
|
||||||
929,
|
|
||||||
937,
|
|
||||||
941,
|
|
||||||
947,
|
|
||||||
953,
|
|
||||||
967,
|
|
||||||
971,
|
|
||||||
977,
|
|
||||||
983,
|
|
||||||
991,
|
|
||||||
997
|
|
||||||
];
|
];
|
||||||
var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
|
var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
export var sjcl: any
|
export var sjcl: any;
|
||||||
|
|
||||||
|
|
|
@ -68,8 +68,8 @@ var sjcl = {
|
||||||
* Ciphertext is corrupt.
|
* Ciphertext is corrupt.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
corrupt: function(message) {
|
corrupt: function (message) {
|
||||||
this.toString = function() {
|
this.toString = function () {
|
||||||
return "CORRUPT: " + this.message;
|
return "CORRUPT: " + this.message;
|
||||||
};
|
};
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
@ -79,8 +79,8 @@ var sjcl = {
|
||||||
* Invalid parameter.
|
* Invalid parameter.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
invalid: function(message) {
|
invalid: function (message) {
|
||||||
this.toString = function() {
|
this.toString = function () {
|
||||||
return "INVALID: " + this.message;
|
return "INVALID: " + this.message;
|
||||||
};
|
};
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
@ -90,8 +90,8 @@ var sjcl = {
|
||||||
* Bug or missing feature in SJCL.
|
* Bug or missing feature in SJCL.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
bug: function(message) {
|
bug: function (message) {
|
||||||
this.toString = function() {
|
this.toString = function () {
|
||||||
return "BUG: " + this.message;
|
return "BUG: " + this.message;
|
||||||
};
|
};
|
||||||
this.message = message;
|
this.message = message;
|
||||||
|
@ -101,13 +101,13 @@ var sjcl = {
|
||||||
* Something isn't ready.
|
* Something isn't ready.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
notReady: function(message) {
|
notReady: function (message) {
|
||||||
this.toString = function() {
|
this.toString = function () {
|
||||||
return "NOT READY: " + this.message;
|
return "NOT READY: " + this.message;
|
||||||
};
|
};
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
/** @fileOverview Low-level AES implementation.
|
/** @fileOverview Low-level AES implementation.
|
||||||
*
|
*
|
||||||
|
@ -133,7 +133,7 @@ var sjcl = {
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {Array} key The key as an array of 4, 6 or 8 words.
|
* @param {Array} key The key as an array of 4, 6 or 8 words.
|
||||||
*/
|
*/
|
||||||
sjcl.cipher.aes = function(key) {
|
sjcl.cipher.aes = function (key) {
|
||||||
if (!this._tables[0][0][0]) {
|
if (!this._tables[0][0][0]) {
|
||||||
this._precompute();
|
this._precompute();
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ sjcl.cipher.aes.prototype = {
|
||||||
* @param {Array} data The plaintext.
|
* @param {Array} data The plaintext.
|
||||||
* @return {Array} The ciphertext.
|
* @return {Array} The ciphertext.
|
||||||
*/
|
*/
|
||||||
encrypt: function(data) {
|
encrypt: function (data) {
|
||||||
return this._crypt(data, 0);
|
return this._crypt(data, 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -213,7 +213,7 @@ sjcl.cipher.aes.prototype = {
|
||||||
* @param {Array} data The ciphertext.
|
* @param {Array} data The ciphertext.
|
||||||
* @return {Array} The plaintext.
|
* @return {Array} The plaintext.
|
||||||
*/
|
*/
|
||||||
decrypt: function(data) {
|
decrypt: function (data) {
|
||||||
return this._crypt(data, 1);
|
return this._crypt(data, 1);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -229,14 +229,17 @@ sjcl.cipher.aes.prototype = {
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_tables: [[[], [], [], [], []], [[], [], [], [], []]],
|
_tables: [
|
||||||
|
[[], [], [], [], []],
|
||||||
|
[[], [], [], [], []],
|
||||||
|
],
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expand the S-box tables.
|
* Expand the S-box tables.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_precompute: function() {
|
_precompute: function () {
|
||||||
var encTable = this._tables[0],
|
var encTable = this._tables[0],
|
||||||
decTable = this._tables[1],
|
decTable = this._tables[1],
|
||||||
sbox = encTable[4],
|
sbox = encTable[4],
|
||||||
|
@ -290,7 +293,7 @@ sjcl.cipher.aes.prototype = {
|
||||||
* @return {Array} The four encrypted or decrypted words.
|
* @return {Array} The four encrypted or decrypted words.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_crypt: function(input, dir) {
|
_crypt: function (input, dir) {
|
||||||
if (input.length !== 4) {
|
if (input.length !== 4) {
|
||||||
throw new sjcl.exception.invalid("invalid aes block size");
|
throw new sjcl.exception.invalid("invalid aes block size");
|
||||||
}
|
}
|
||||||
|
@ -344,7 +347,7 @@ sjcl.cipher.aes.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @fileOverview Arrays of bits, encoded as arrays of Numbers.
|
/** @fileOverview Arrays of bits, encoded as arrays of Numbers.
|
||||||
|
@ -387,7 +390,7 @@ sjcl.bitArray = {
|
||||||
* slice until the end of the array.
|
* slice until the end of the array.
|
||||||
* @return {bitArray} The requested slice.
|
* @return {bitArray} The requested slice.
|
||||||
*/
|
*/
|
||||||
bitSlice: function(a, bstart, bend) {
|
bitSlice: function (a, bstart, bend) {
|
||||||
a = sjcl.bitArray._shiftRight(a.slice(bstart / 32), 32 - (bstart & 31)).slice(1);
|
a = sjcl.bitArray._shiftRight(a.slice(bstart / 32), 32 - (bstart & 31)).slice(1);
|
||||||
return bend === undefined ? a : sjcl.bitArray.clamp(a, bend - bstart);
|
return bend === undefined ? a : sjcl.bitArray.clamp(a, bend - bstart);
|
||||||
},
|
},
|
||||||
|
@ -399,7 +402,7 @@ sjcl.bitArray = {
|
||||||
* @param {Number} blength The length of the number to extract.
|
* @param {Number} blength The length of the number to extract.
|
||||||
* @return {Number} The requested slice.
|
* @return {Number} The requested slice.
|
||||||
*/
|
*/
|
||||||
extract: function(a, bstart, blength) {
|
extract: function (a, bstart, blength) {
|
||||||
// FIXME: this Math.floor is not necessary at all, but for some reason
|
// FIXME: this Math.floor is not necessary at all, but for some reason
|
||||||
// seems to suppress a bug in the Chromium JIT.
|
// seems to suppress a bug in the Chromium JIT.
|
||||||
var x,
|
var x,
|
||||||
|
@ -420,7 +423,7 @@ sjcl.bitArray = {
|
||||||
* @param {bitArray} a2 The second array.
|
* @param {bitArray} a2 The second array.
|
||||||
* @return {bitArray} The concatenation of a1 and a2.
|
* @return {bitArray} The concatenation of a1 and a2.
|
||||||
*/
|
*/
|
||||||
concat: function(a1, a2) {
|
concat: function (a1, a2) {
|
||||||
if (a1.length === 0 || a2.length === 0) {
|
if (a1.length === 0 || a2.length === 0) {
|
||||||
return a1.concat(a2);
|
return a1.concat(a2);
|
||||||
}
|
}
|
||||||
|
@ -439,7 +442,7 @@ sjcl.bitArray = {
|
||||||
* @param {bitArray} a The array.
|
* @param {bitArray} a The array.
|
||||||
* @return {Number} The length of a, in bits.
|
* @return {Number} The length of a, in bits.
|
||||||
*/
|
*/
|
||||||
bitLength: function(a) {
|
bitLength: function (a) {
|
||||||
var l = a.length,
|
var l = a.length,
|
||||||
x;
|
x;
|
||||||
if (l === 0) {
|
if (l === 0) {
|
||||||
|
@ -455,7 +458,7 @@ sjcl.bitArray = {
|
||||||
* @param {Number} len The length to truncate to, in bits.
|
* @param {Number} len The length to truncate to, in bits.
|
||||||
* @return {bitArray} A new array, truncated to len bits.
|
* @return {bitArray} A new array, truncated to len bits.
|
||||||
*/
|
*/
|
||||||
clamp: function(a, len) {
|
clamp: function (a, len) {
|
||||||
if (a.length * 32 < len) {
|
if (a.length * 32 < len) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
@ -475,7 +478,7 @@ sjcl.bitArray = {
|
||||||
* @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
|
* @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
|
||||||
* @return {Number} The partial word.
|
* @return {Number} The partial word.
|
||||||
*/
|
*/
|
||||||
partial: function(len, x, _end) {
|
partial: function (len, x, _end) {
|
||||||
if (len === 32) {
|
if (len === 32) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
@ -487,7 +490,7 @@ sjcl.bitArray = {
|
||||||
* @param {Number} x The partial word.
|
* @param {Number} x The partial word.
|
||||||
* @return {Number} The number of bits used by the partial word.
|
* @return {Number} The number of bits used by the partial word.
|
||||||
*/
|
*/
|
||||||
getPartial: function(x) {
|
getPartial: function (x) {
|
||||||
return Math.round(x / 0x10000000000) || 32;
|
return Math.round(x / 0x10000000000) || 32;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -497,7 +500,7 @@ sjcl.bitArray = {
|
||||||
* @param {bitArray} b The second array.
|
* @param {bitArray} b The second array.
|
||||||
* @return {boolean} true if a == b; false otherwise.
|
* @return {boolean} true if a == b; false otherwise.
|
||||||
*/
|
*/
|
||||||
equal: function(a, b) {
|
equal: function (a, b) {
|
||||||
if (sjcl.bitArray.bitLength(a) !== sjcl.bitArray.bitLength(b)) {
|
if (sjcl.bitArray.bitLength(a) !== sjcl.bitArray.bitLength(b)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -516,7 +519,7 @@ sjcl.bitArray = {
|
||||||
* @param {bitArray} [out=[]] An array to prepend to the output.
|
* @param {bitArray} [out=[]] An array to prepend to the output.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_shiftRight: function(a, shift, carry, out) {
|
_shiftRight: function (a, shift, carry, out) {
|
||||||
var i,
|
var i,
|
||||||
last2 = 0,
|
last2 = 0,
|
||||||
shift2;
|
shift2;
|
||||||
|
@ -545,7 +548,7 @@ sjcl.bitArray = {
|
||||||
/** xor a block of 4 words together.
|
/** xor a block of 4 words together.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_xor4: function(x, y) {
|
_xor4: function (x, y) {
|
||||||
return [x[0] ^ y[0], x[1] ^ y[1], x[2] ^ y[2], x[3] ^ y[3]];
|
return [x[0] ^ y[0], x[1] ^ y[1], x[2] ^ y[2], x[3] ^ y[3]];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -554,7 +557,7 @@ sjcl.bitArray = {
|
||||||
* @param {sjcl.bitArray} a word array
|
* @param {sjcl.bitArray} a word array
|
||||||
* @return {sjcl.bitArray} byteswapped array
|
* @return {sjcl.bitArray} byteswapped array
|
||||||
*/
|
*/
|
||||||
byteswapM: function(a) {
|
byteswapM: function (a) {
|
||||||
var i,
|
var i,
|
||||||
v,
|
v,
|
||||||
m = 0xff00;
|
m = 0xff00;
|
||||||
|
@ -563,7 +566,7 @@ sjcl.bitArray = {
|
||||||
a[i] = (v >>> 24) | ((v >>> 8) & m) | ((v & m) << 8) | (v << 24);
|
a[i] = (v >>> 24) | ((v >>> 8) & m) | ((v & m) << 8) | (v << 24);
|
||||||
}
|
}
|
||||||
return a;
|
return a;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
/** @fileOverview Bit array codec implementations.
|
/** @fileOverview Bit array codec implementations.
|
||||||
*
|
*
|
||||||
|
@ -578,7 +581,7 @@ sjcl.bitArray = {
|
||||||
*/
|
*/
|
||||||
sjcl.codec.utf8String = {
|
sjcl.codec.utf8String = {
|
||||||
/** Convert from a bitArray to a UTF-8 string. */
|
/** Convert from a bitArray to a UTF-8 string. */
|
||||||
fromBits: function(arr) {
|
fromBits: function (arr) {
|
||||||
var out = "",
|
var out = "",
|
||||||
bl = sjcl.bitArray.bitLength(arr),
|
bl = sjcl.bitArray.bitLength(arr),
|
||||||
i,
|
i,
|
||||||
|
@ -594,7 +597,7 @@ sjcl.codec.utf8String = {
|
||||||
},
|
},
|
||||||
|
|
||||||
/** Convert from a UTF-8 string to a bitArray. */
|
/** Convert from a UTF-8 string to a bitArray. */
|
||||||
toBits: function(str) {
|
toBits: function (str) {
|
||||||
str = unescape(encodeURIComponent(str));
|
str = unescape(encodeURIComponent(str));
|
||||||
var out = [],
|
var out = [],
|
||||||
i,
|
i,
|
||||||
|
@ -610,7 +613,7 @@ sjcl.codec.utf8String = {
|
||||||
out.push(sjcl.bitArray.partial(8 * (i & 3), tmp));
|
out.push(sjcl.bitArray.partial(8 * (i & 3), tmp));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
/** @fileOverview Bit array codec implementations.
|
/** @fileOverview Bit array codec implementations.
|
||||||
*
|
*
|
||||||
|
@ -625,7 +628,7 @@ sjcl.codec.utf8String = {
|
||||||
*/
|
*/
|
||||||
sjcl.codec.bytes = {
|
sjcl.codec.bytes = {
|
||||||
/** Convert from a bitArray to an array of bytes. */
|
/** Convert from a bitArray to an array of bytes. */
|
||||||
fromBits: function(arr) {
|
fromBits: function (arr) {
|
||||||
var out = [],
|
var out = [],
|
||||||
bl = sjcl.bitArray.bitLength(arr),
|
bl = sjcl.bitArray.bitLength(arr),
|
||||||
i,
|
i,
|
||||||
|
@ -640,7 +643,7 @@ sjcl.codec.bytes = {
|
||||||
return out;
|
return out;
|
||||||
},
|
},
|
||||||
/** Convert from an array of bytes to a bitArray. */
|
/** Convert from an array of bytes to a bitArray. */
|
||||||
toBits: function(bytes) {
|
toBits: function (bytes) {
|
||||||
var out = [],
|
var out = [],
|
||||||
i,
|
i,
|
||||||
tmp = 0;
|
tmp = 0;
|
||||||
|
@ -655,7 +658,7 @@ sjcl.codec.bytes = {
|
||||||
out.push(sjcl.bitArray.partial(8 * (i & 3), tmp));
|
out.push(sjcl.bitArray.partial(8 * (i & 3), tmp));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
/** @fileOverview CCM mode implementation.
|
/** @fileOverview CCM mode implementation.
|
||||||
*
|
*
|
||||||
|
@ -679,18 +682,18 @@ sjcl.mode.ccm = {
|
||||||
|
|
||||||
_progressListeners: [],
|
_progressListeners: [],
|
||||||
|
|
||||||
listenProgress: function(cb) {
|
listenProgress: function (cb) {
|
||||||
sjcl.mode.ccm._progressListeners.push(cb);
|
sjcl.mode.ccm._progressListeners.push(cb);
|
||||||
},
|
},
|
||||||
|
|
||||||
unListenProgress: function(cb) {
|
unListenProgress: function (cb) {
|
||||||
var index = sjcl.mode.ccm._progressListeners.indexOf(cb);
|
var index = sjcl.mode.ccm._progressListeners.indexOf(cb);
|
||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
sjcl.mode.ccm._progressListeners.splice(index, 1);
|
sjcl.mode.ccm._progressListeners.splice(index, 1);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_callProgressListener: function(val) {
|
_callProgressListener: function (val) {
|
||||||
var p = sjcl.mode.ccm._progressListeners.slice(),
|
var p = sjcl.mode.ccm._progressListeners.slice(),
|
||||||
i;
|
i;
|
||||||
|
|
||||||
|
@ -708,7 +711,7 @@ sjcl.mode.ccm = {
|
||||||
* @param {Number} [tlen=64] the desired tag length, in bits.
|
* @param {Number} [tlen=64] the desired tag length, in bits.
|
||||||
* @return {bitArray} The encrypted data, an array of bytes.
|
* @return {bitArray} The encrypted data, an array of bytes.
|
||||||
*/
|
*/
|
||||||
encrypt: function(prf, plaintext, iv, adata, tlen) {
|
encrypt: function (prf, plaintext, iv, adata, tlen) {
|
||||||
var L,
|
var L,
|
||||||
out = plaintext.slice(0),
|
out = plaintext.slice(0),
|
||||||
tag,
|
tag,
|
||||||
|
@ -747,7 +750,7 @@ sjcl.mode.ccm = {
|
||||||
* @param {Number} [tlen=64] tlen the desired tag length, in bits.
|
* @param {Number} [tlen=64] tlen the desired tag length, in bits.
|
||||||
* @return {bitArray} The decrypted data.
|
* @return {bitArray} The decrypted data.
|
||||||
*/
|
*/
|
||||||
decrypt: function(prf, ciphertext, iv, adata, tlen) {
|
decrypt: function (prf, ciphertext, iv, adata, tlen) {
|
||||||
tlen = tlen || 64;
|
tlen = tlen || 64;
|
||||||
adata = adata || [];
|
adata = adata || [];
|
||||||
var L,
|
var L,
|
||||||
|
@ -783,7 +786,7 @@ sjcl.mode.ccm = {
|
||||||
return out.data;
|
return out.data;
|
||||||
},
|
},
|
||||||
|
|
||||||
_macAdditionalData: function(prf, adata, iv, tlen, ol, L) {
|
_macAdditionalData: function (prf, adata, iv, tlen, ol, L) {
|
||||||
var mac,
|
var mac,
|
||||||
tmp,
|
tmp,
|
||||||
i,
|
i,
|
||||||
|
@ -827,7 +830,7 @@ sjcl.mode.ccm = {
|
||||||
* @return {bitArray} The tag, but not yet encrypted.
|
* @return {bitArray} The tag, but not yet encrypted.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_computeTag: function(prf, plaintext, iv, adata, tlen, L) {
|
_computeTag: function (prf, plaintext, iv, adata, tlen, L) {
|
||||||
// compute B[0]
|
// compute B[0]
|
||||||
var mac,
|
var mac,
|
||||||
i,
|
i,
|
||||||
|
@ -868,7 +871,7 @@ sjcl.mode.ccm = {
|
||||||
* @return {Object} An object with data and tag, the en/decryption of data and tag values.
|
* @return {Object} An object with data and tag, the en/decryption of data and tag values.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
_ctrMode: function(prf, data, iv, tag, tlen, L) {
|
_ctrMode: function (prf, data, iv, tag, tlen, L) {
|
||||||
var enc,
|
var enc,
|
||||||
i,
|
i,
|
||||||
w = sjcl.bitArray,
|
w = sjcl.bitArray,
|
||||||
|
@ -906,7 +909,7 @@ sjcl.mode.ccm = {
|
||||||
data[i + 3] ^= enc[3];
|
data[i + 3] ^= enc[3];
|
||||||
}
|
}
|
||||||
return { tag: tag, data: w.clamp(data, bl) };
|
return { tag: tag, data: w.clamp(data, bl) };
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export { sjcl };
|
export { sjcl };
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/electron",
|
"name": "@padloc/electron",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"description": "Electron Wrapper for Padloc app",
|
"description": "Electron Wrapper for Padloc app",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git"
|
"url": "https://github.com/padloc/padloc.git"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -rf app && webpack && node ./prepare-build.js && electron-builder --config build/build.json",
|
"build": "rm -rf app && webpack && node ./prepare-build.js && electron-builder --config build/build.json",
|
||||||
"start": "webpack && electron app/main.js"
|
"start": "webpack && electron app/main.js"
|
||||||
},
|
},
|
||||||
"author": "MaKleSoft UG",
|
"author": "MaKleSoft UG",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/app": "4.0.0",
|
"@padloc/app": "4.0.0",
|
||||||
"@padloc/core": "4.0.0",
|
"@padloc/core": "4.0.0",
|
||||||
"electron-store": "8.0.0",
|
"electron-store": "8.0.0",
|
||||||
"electron-updater": "4.3.9"
|
"electron-updater": "4.3.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"clean-webpack-plugin": "3.0.0",
|
"clean-webpack-plugin": "3.0.0",
|
||||||
"css-loader": "5.2.6",
|
"css-loader": "5.2.6",
|
||||||
"electron": "14.1.1",
|
"electron": "14.1.1",
|
||||||
"electron-builder": "22.13.1",
|
"electron-builder": "22.13.1",
|
||||||
"electron-notarize": "1.1.1",
|
"electron-notarize": "1.1.1",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"html-webpack-plugin": "5.3.2",
|
"html-webpack-plugin": "5.3.2",
|
||||||
"style-loader": "2.0.0",
|
"style-loader": "2.0.0",
|
||||||
"ts-loader": "9.2.5",
|
"ts-loader": "9.2.5",
|
||||||
"webpack": "5.52.1",
|
"webpack": "5.52.1",
|
||||||
"webpack-cli": "4.8.0",
|
"webpack-cli": "4.8.0",
|
||||||
"typescript": "4.4.3",
|
"typescript": "4.4.3",
|
||||||
"raw-loader": "4.0.2",
|
"raw-loader": "4.0.2",
|
||||||
"sharp": "0.29.1"
|
"sharp": "0.29.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ const { execSync } = require("child_process");
|
||||||
const { tmpdir } = require("os");
|
const { tmpdir } = require("os");
|
||||||
const { writeFileSync, unlinkSync } = require("fs");
|
const { writeFileSync, unlinkSync } = require("fs");
|
||||||
|
|
||||||
exports.default = async function(opts) {
|
exports.default = async function (opts) {
|
||||||
const jsign = path.resolve(__dirname, "jsign-2.1.jar");
|
const jsign = path.resolve(__dirname, "jsign-2.1.jar");
|
||||||
const pass = process.env.PL_WIN_SIGN_PASS;
|
const pass = process.env.PL_WIN_SIGN_PASS;
|
||||||
const lib = path.resolve(__dirname, "crypto3PKCS.dylib");
|
const lib = path.resolve(__dirname, "crypto3PKCS.dylib");
|
||||||
|
@ -18,9 +18,7 @@ slotListIndex=0`
|
||||||
);
|
);
|
||||||
|
|
||||||
execSync(
|
execSync(
|
||||||
`java -jar ${jsign} --keystore ${keystore} --storepass ${pass} --storetype PKCS11 -t http://time.certum.pl/ -a "${
|
`java -jar ${jsign} --keystore ${keystore} --storepass ${pass} --storetype PKCS11 -t http://time.certum.pl/ -a "${opts.options.publisherName}" "${opts.path}"`
|
||||||
opts.options.publisherName
|
|
||||||
}" "${opts.path}"`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
unlinkSync(keystore);
|
unlinkSync(keystore);
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
{
|
{
|
||||||
"extends": "../app/tsconfig.json"
|
"extends": "../app/tsconfig.json"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +1,47 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/extension",
|
"name": "@padloc/extension",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"description": "Padloc Progressive Web App",
|
"description": "Padloc Progressive Web App",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"assets",
|
"assets",
|
||||||
"tsconfig.json"
|
"tsconfig.json"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git",
|
"url": "https://github.com/padloc/padloc.git",
|
||||||
"directory": "packages/pwa"
|
"directory": "packages/pwa"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/app": "4.0.0",
|
"@padloc/app": "4.0.0",
|
||||||
"@padloc/core": "4.0.0",
|
"@padloc/core": "4.0.0",
|
||||||
"@webcomponents/webcomponentsjs": "2.5.0",
|
"@webcomponents/webcomponentsjs": "2.5.0",
|
||||||
"webextension-polyfill-ts": "0.25.0"
|
"webextension-polyfill-ts": "0.25.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"clean-webpack-plugin": "3.0.0",
|
"clean-webpack-plugin": "3.0.0",
|
||||||
"css-loader": "5.2.6",
|
"css-loader": "5.2.6",
|
||||||
"favicons-webpack-plugin": "5.0.2",
|
"favicons-webpack-plugin": "5.0.2",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"html-webpack-plugin": "5.3.1",
|
"html-webpack-plugin": "5.3.1",
|
||||||
"http-server": "0.12.3",
|
"http-server": "0.12.3",
|
||||||
"raw-loader": "4.0.2",
|
"raw-loader": "4.0.2",
|
||||||
"sharp": "0.29.1",
|
"sharp": "0.29.1",
|
||||||
"style-loader": "2.0.0",
|
"style-loader": "2.0.0",
|
||||||
"ts-loader": "9.2.2",
|
"ts-loader": "9.2.2",
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typescript": "4.4.3",
|
"typescript": "4.4.3",
|
||||||
"webpack": "5.38.1",
|
"webpack": "5.38.1",
|
||||||
"webpack-cli": "4.7.0"
|
"webpack-cli": "4.7.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack"
|
"build": "webpack"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,19 +183,19 @@ class ExtensionContent {
|
||||||
input.dispatchEvent(
|
input.dispatchEvent(
|
||||||
new KeyboardEvent("keydown", {
|
new KeyboardEvent("keydown", {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
key: ""
|
key: "",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
input.dispatchEvent(
|
input.dispatchEvent(
|
||||||
new KeyboardEvent("keyup", {
|
new KeyboardEvent("keyup", {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
key: ""
|
key: "",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
input.dispatchEvent(
|
input.dispatchEvent(
|
||||||
new KeyboardEvent("keypress", {
|
new KeyboardEvent("keypress", {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
key: ""
|
key: "",
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||||
|
|
|
@ -4,22 +4,14 @@
|
||||||
"128": "icon.png"
|
"128": "icon.png"
|
||||||
},
|
},
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": [
|
"scripts": ["background.js"],
|
||||||
"background.js"
|
|
||||||
],
|
|
||||||
"persistent": true
|
"persistent": true
|
||||||
},
|
},
|
||||||
"browser_action": {
|
"browser_action": {
|
||||||
"default_popup": "popup.html",
|
"default_popup": "popup.html",
|
||||||
"default_icon": "icon.png"
|
"default_icon": "icon.png"
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": ["storage", "unlimitedStorage", "tabs", "activeTab", "contextMenus"],
|
||||||
"storage",
|
|
||||||
"unlimitedStorage",
|
|
||||||
"tabs",
|
|
||||||
"activeTab",
|
|
||||||
"contextMenus"
|
|
||||||
],
|
|
||||||
"commands": {
|
"commands": {
|
||||||
"_execute_browser_action": {
|
"_execute_browser_action": {
|
||||||
"suggested_key": {
|
"suggested_key": {
|
||||||
|
@ -42,4 +34,4 @@
|
||||||
"description": "Open Previous Vault Item"
|
"description": "Open Previous Vault Item"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,28 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/locale",
|
"name": "@padloc/locale",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"description": "Package containing translations and wordlists for Padloc as well as various other localization tools",
|
"description": "Package containing translations and wordlists for Padloc as well as various other localization tools",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"res"
|
"res"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"extract": "ts-node src/extract.ts ../*/src/{**,.}/*.ts"
|
"extract": "ts-node src/extract.ts ../*/src/{**,.}/*.ts"
|
||||||
},
|
},
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPLv3",
|
"license": "GPLv3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typescript": "4.4.3"
|
"typescript": "4.4.3"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git",
|
"url": "https://github.com/padloc/padloc.git",
|
||||||
"directory": "packages/locale"
|
"directory": "packages/locale"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -235,5 +235,5 @@ export const countries = [
|
||||||
{ code: "EH", name: "Western Sahara" },
|
{ code: "EH", name: "Western Sahara" },
|
||||||
{ code: "YE", name: "Yemen" },
|
{ code: "YE", name: "Yemen" },
|
||||||
{ code: "ZM", name: "Zambia" },
|
{ code: "ZM", name: "Zambia" },
|
||||||
{ code: "ZW", name: "Zimbabwe" }
|
{ code: "ZW", name: "Zimbabwe" },
|
||||||
];
|
];
|
||||||
|
|
|
@ -54,7 +54,7 @@ function extract(files: ts.SourceFile[]) {
|
||||||
items.set(original, {
|
items.set(original, {
|
||||||
original,
|
original,
|
||||||
translation: "",
|
translation: "",
|
||||||
sources: []
|
sources: [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ function extract(files: ts.SourceFile[]) {
|
||||||
const source: ItemSource = {
|
const source: ItemSource = {
|
||||||
file: file.fileName,
|
file: file.fileName,
|
||||||
line,
|
line,
|
||||||
character
|
character,
|
||||||
};
|
};
|
||||||
|
|
||||||
const comments =
|
const comments =
|
||||||
|
@ -106,7 +106,7 @@ export function toYAML({ language, date, commit, items }: Translation) {
|
||||||
commit: ${commit}
|
commit: ${commit}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
doc.contents = YAML.createNode(items.flatMap(item => [item.original, item.translation])) as any;
|
doc.contents = YAML.createNode(items.flatMap((item) => [item.original, item.translation])) as any;
|
||||||
|
|
||||||
for (const [i, item] of items.entries()) {
|
for (const [i, item] of items.entries()) {
|
||||||
const node = (doc.contents as any).items[i * 2];
|
const node = (doc.contents as any).items[i * 2];
|
||||||
|
@ -131,7 +131,7 @@ export function fromYAML(str: string, language: string): Translation {
|
||||||
language,
|
language,
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
commit: "",
|
commit: "",
|
||||||
items
|
items,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,37 +156,35 @@ export function fromJSON(str: string, language: string) {
|
||||||
const items = JSON.parse(str).map(([original, translation]: [string, string]) => ({
|
const items = JSON.parse(str).map(([original, translation]: [string, string]) => ({
|
||||||
original,
|
original,
|
||||||
translation,
|
translation,
|
||||||
sources: []
|
sources: [],
|
||||||
}));
|
}));
|
||||||
return {
|
return {
|
||||||
language,
|
language,
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
commit: "",
|
commit: "",
|
||||||
items
|
items,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fromSource(fileNames: string[], language: string): Translation {
|
export function fromSource(fileNames: string[], language: string): Translation {
|
||||||
const files = fileNames.map(path =>
|
const files = fileNames.map((path) =>
|
||||||
ts.createSourceFile(path, readFileSync(resolve(path), "utf8"), ts.ScriptTarget.ES2017, false)
|
ts.createSourceFile(path, readFileSync(resolve(path), "utf8"), ts.ScriptTarget.ES2017, false)
|
||||||
);
|
);
|
||||||
|
|
||||||
const commit = execSync("git rev-parse HEAD")
|
const commit = execSync("git rev-parse HEAD").toString().trim();
|
||||||
.toString()
|
|
||||||
.trim();
|
|
||||||
const items = extract(files);
|
const items = extract(files);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
language,
|
language,
|
||||||
commit,
|
commit,
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
items
|
items,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function merge(curr: Translation, prev: Translation) {
|
export function merge(curr: Translation, prev: Translation) {
|
||||||
for (const item of curr.items) {
|
for (const item of curr.items) {
|
||||||
const prevItemIndex = prev.items.findIndex(i => i.original === item.original);
|
const prevItemIndex = prev.items.findIndex((i) => i.original === item.original);
|
||||||
if (prevItemIndex !== -1) {
|
if (prevItemIndex !== -1) {
|
||||||
item.translation = prev.items[prevItemIndex].translation;
|
item.translation = prev.items[prevItemIndex].translation;
|
||||||
prev.items.splice(prevItemIndex, 1);
|
prev.items.splice(prevItemIndex, 1);
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2017",
|
"target": "es2017",
|
||||||
"lib": [
|
"lib": ["esnext"],
|
||||||
"esnext"
|
|
||||||
],
|
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"declaration": false,
|
"declaration": false,
|
||||||
"baseUrl": "."
|
"baseUrl": "."
|
||||||
|
|
|
@ -1,51 +1,51 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/pwa",
|
"name": "@padloc/pwa",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"assets",
|
"assets",
|
||||||
"tsconfig.json"
|
"tsconfig.json"
|
||||||
],
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git",
|
"url": "https://github.com/padloc/padloc.git",
|
||||||
"directory": "packages/pwa"
|
"directory": "packages/pwa"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/app": "4.0.0",
|
"@padloc/app": "4.0.0",
|
||||||
"@padloc/core": "4.0.0"
|
"@padloc/core": "4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"clean-webpack-plugin": "3.0.0",
|
"clean-webpack-plugin": "3.0.0",
|
||||||
"css-loader": "5.2.6",
|
"css-loader": "5.2.6",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"html-webpack-plugin": "5.3.1",
|
"html-webpack-plugin": "5.3.1",
|
||||||
"http-server": "0.12.3",
|
"http-server": "0.12.3",
|
||||||
"raw-loader": "4.0.2",
|
"raw-loader": "4.0.2",
|
||||||
"sharp": "0.29.3",
|
"sharp": "0.29.3",
|
||||||
"style-loader": "2.0.0",
|
"style-loader": "2.0.0",
|
||||||
"ts-loader": "9.2.2",
|
"ts-loader": "9.2.2",
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typescript": "4.4.3",
|
"typescript": "4.4.3",
|
||||||
"webpack": "5.52.0",
|
"webpack": "5.52.0",
|
||||||
"webpack-cli": "4.8.0",
|
"webpack-cli": "4.8.0",
|
||||||
"webpack-dev-server": "4.2.1",
|
"webpack-dev-server": "4.2.1",
|
||||||
"webpack-pwa-manifest": "4.3.0",
|
"webpack-pwa-manifest": "4.3.0",
|
||||||
"workbox-cli": "6.2.4",
|
"workbox-cli": "6.2.4",
|
||||||
"workbox-webpack-plugin": "6.4.2"
|
"workbox-webpack-plugin": "6.4.2"
|
||||||
},
|
},
|
||||||
"description": "Padloc Progressive Web App",
|
"description": "Padloc Progressive Web App",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "webpack",
|
"build": "webpack",
|
||||||
"dev": "webpack serve",
|
"dev": "webpack serve",
|
||||||
"start": "http-server ${PL_PWA_DIR:-dist} -s -p ${PL_PWA_PORT:-8080} --proxy ${PL_PWA_URL:-http://0.0.0.0:${PL_PWA_PORT:-8080}}?",
|
"start": "http-server ${PL_PWA_DIR:-dist} -s -p ${PL_PWA_PORT:-8080} --proxy ${PL_PWA_URL:-http://0.0.0.0:${PL_PWA_PORT:-8080}}?",
|
||||||
"build_and_start": "npm run build && npm start"
|
"build_and_start": "npm run build && npm start"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,63 +1,63 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/server",
|
"name": "@padloc/server",
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"description": "Padloc server component",
|
"description": "Padloc server component",
|
||||||
"private": true,
|
"private": true,
|
||||||
"files": [
|
"files": [
|
||||||
"src",
|
"src",
|
||||||
"tsconfig.json"
|
"tsconfig.json"
|
||||||
],
|
],
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
|
||||||
"license": "GPLv3",
|
"license": "GPLv3",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/chai": "4.2.18",
|
"@types/chai": "4.2.18",
|
||||||
"@types/mocha": "8.2.2",
|
"@types/mocha": "8.2.2",
|
||||||
"chai": "4.3.4",
|
"chai": "4.3.4",
|
||||||
"mocha": "8.4.0",
|
"mocha": "8.4.0",
|
||||||
"ts-node-dev": "1.1.6"
|
"ts-node-dev": "1.1.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/core": "4.0.0",
|
"@padloc/core": "4.0.0",
|
||||||
"@padloc/locale": "4.0.0",
|
"@padloc/locale": "4.0.0",
|
||||||
"@aws-sdk/client-s3": "3.25.0",
|
"@aws-sdk/client-s3": "3.25.0",
|
||||||
"@aws-sdk/types": "3.25.0",
|
"@aws-sdk/types": "3.25.0",
|
||||||
"@simplewebauthn/server": "4.0.0",
|
"@simplewebauthn/server": "4.0.0",
|
||||||
"@types/fs-extra": "9.0.11",
|
"@types/fs-extra": "9.0.11",
|
||||||
"@types/mixpanel": "2.14.3",
|
"@types/mixpanel": "2.14.3",
|
||||||
"@types/node": "15.6.1",
|
"@types/node": "15.6.1",
|
||||||
"@types/nodemailer": "6.4.2",
|
"@types/nodemailer": "6.4.2",
|
||||||
"@types/pg": "8.6.1",
|
"@types/pg": "8.6.1",
|
||||||
"@types/stripe": "8.0.416",
|
"@types/stripe": "8.0.416",
|
||||||
"ansi-colors": "4.1.1",
|
"ansi-colors": "4.1.1",
|
||||||
"date-fns": "2.22.1",
|
"date-fns": "2.22.1",
|
||||||
"fs-extra": "10.0.0",
|
"fs-extra": "10.0.0",
|
||||||
"geolite2-redist": "2.0.4",
|
"geolite2-redist": "2.0.4",
|
||||||
"level": "7.0.0",
|
"level": "7.0.0",
|
||||||
"maxmind": "4.3.2",
|
"maxmind": "4.3.2",
|
||||||
"mixpanel": "0.13.0",
|
"mixpanel": "0.13.0",
|
||||||
"mongodb": "4.1.0",
|
"mongodb": "4.1.0",
|
||||||
"nodemailer": "6.6.1",
|
"nodemailer": "6.6.1",
|
||||||
"pg": "8.7.1",
|
"pg": "8.7.1",
|
||||||
"stripe": "8.194.0",
|
"stripe": "8.194.0",
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typescript": "4.4.3"
|
"typescript": "4.4.3"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "ts-node src/init.ts",
|
"start": "ts-node src/init.ts",
|
||||||
"start-dry": "ts-node src/init.ts --dryrun",
|
"start-dry": "ts-node src/init.ts --dryrun",
|
||||||
"repl": "ts-node src/init-repl-client.ts",
|
"repl": "ts-node src/init-repl-client.ts",
|
||||||
"dev": "ts-node-dev src/init.ts",
|
"dev": "ts-node-dev src/init.ts",
|
||||||
"dev-inspect": "node -r ts-node/register --inspect-brk --stack-trace-limit=1000 src/init.ts",
|
"dev-inspect": "node -r ts-node/register --inspect-brk --stack-trace-limit=1000 src/init.ts",
|
||||||
"test": "cd test && mocha -r ts-node/register *.ts --timeout 5000"
|
"test": "cd test && mocha -r ts-node/register *.ts --timeout 5000"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/padloc/padloc.git",
|
"url": "https://github.com/padloc/padloc.git",
|
||||||
"directory": "packages/server"
|
"directory": "packages/server"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
createCipheriv,
|
createCipheriv,
|
||||||
createDecipheriv,
|
createDecipheriv,
|
||||||
publicEncrypt,
|
publicEncrypt,
|
||||||
privateDecrypt
|
privateDecrypt,
|
||||||
} from "crypto";
|
} from "crypto";
|
||||||
import {
|
import {
|
||||||
CryptoProvider,
|
CryptoProvider,
|
||||||
|
@ -29,7 +29,7 @@ import {
|
||||||
RSAEncryptionParams,
|
RSAEncryptionParams,
|
||||||
HashParams,
|
HashParams,
|
||||||
RSASigningParams,
|
RSASigningParams,
|
||||||
PBKDF2Params
|
PBKDF2Params,
|
||||||
} from "@padloc/core/src/crypto";
|
} from "@padloc/core/src/crypto";
|
||||||
import { Err, ErrorCode } from "@padloc/core/src/error";
|
import { Err, ErrorCode } from "@padloc/core/src/error";
|
||||||
import { equalCT } from "@padloc/core/src/encoding";
|
import { equalCT } from "@padloc/core/src/encoding";
|
||||||
|
@ -80,12 +80,12 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
),
|
),
|
||||||
publicKeyEncoding: {
|
publicKeyEncoding: {
|
||||||
type: "spki",
|
type: "spki",
|
||||||
format: "der"
|
format: "der",
|
||||||
},
|
},
|
||||||
privateKeyEncoding: {
|
privateKeyEncoding: {
|
||||||
type: "pkcs8",
|
type: "pkcs8",
|
||||||
format: "der"
|
format: "der",
|
||||||
}
|
},
|
||||||
} as any,
|
} as any,
|
||||||
(err, publicKey: Buffer, privateKey: Buffer) => {
|
(err, publicKey: Buffer, privateKey: Buffer) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -93,7 +93,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
} else {
|
} else {
|
||||||
resolve({
|
resolve({
|
||||||
privateKey: new Uint8Array(privateKey),
|
privateKey: new Uint8Array(privateKey),
|
||||||
publicKey: new Uint8Array(publicKey)
|
publicKey: new Uint8Array(publicKey),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
const [alg, mode] = params.algorithm.toLowerCase().split("-");
|
const [alg, mode] = params.algorithm.toLowerCase().split("-");
|
||||||
const authTagLength = params.tagSize / 8;
|
const authTagLength = params.tagSize / 8;
|
||||||
const cipher = createCipheriv(`${alg}-${params.keySize}-${mode}` as "aes-256-gcm", key, params.iv, {
|
const cipher = createCipheriv(`${alg}-${params.keySize}-${mode}` as "aes-256-gcm", key, params.iv, {
|
||||||
authTagLength
|
authTagLength,
|
||||||
} as any);
|
} as any);
|
||||||
cipher.setAAD(params.additionalData as Buffer);
|
cipher.setAAD(params.additionalData as Buffer);
|
||||||
try {
|
try {
|
||||||
|
@ -223,7 +223,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
const tag = data.slice(tagPos);
|
const tag = data.slice(tagPos);
|
||||||
|
|
||||||
const cipher = createDecipheriv(`${alg}-${params.keySize}-${mode}` as "aes-256-gcm", key, params.iv, {
|
const cipher = createDecipheriv(`${alg}-${params.keySize}-${mode}` as "aes-256-gcm", key, params.iv, {
|
||||||
authTagLength
|
authTagLength,
|
||||||
} as any);
|
} as any);
|
||||||
cipher.setAAD(params.additionalData as Buffer);
|
cipher.setAAD(params.additionalData as Buffer);
|
||||||
cipher.setAuthTag(tag);
|
cipher.setAuthTag(tag);
|
||||||
|
@ -242,7 +242,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
key: Buffer.from(publicKey),
|
key: Buffer.from(publicKey),
|
||||||
format: "der",
|
format: "der",
|
||||||
type: "spki",
|
type: "spki",
|
||||||
oaepHash: hashToNode(params.hash)
|
oaepHash: hashToNode(params.hash),
|
||||||
} as any,
|
} as any,
|
||||||
key
|
key
|
||||||
);
|
);
|
||||||
|
@ -259,7 +259,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
key: Buffer.from(privateKey),
|
key: Buffer.from(privateKey),
|
||||||
format: "der",
|
format: "der",
|
||||||
type: "pkcs8",
|
type: "pkcs8",
|
||||||
oaepHash: hashToNode(params.hash)
|
oaepHash: hashToNode(params.hash),
|
||||||
} as any,
|
} as any,
|
||||||
key
|
key
|
||||||
);
|
);
|
||||||
|
@ -293,7 +293,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
format: "der",
|
format: "der",
|
||||||
dsaEncoding: "der",
|
dsaEncoding: "der",
|
||||||
saltLength: params.saltLength,
|
saltLength: params.saltLength,
|
||||||
padding: constants.RSA_PKCS1_PSS_PADDING
|
padding: constants.RSA_PKCS1_PSS_PADDING,
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Uint8Array(sig);
|
return new Uint8Array(sig);
|
||||||
|
@ -309,7 +309,7 @@ export class NodeCryptoProvider implements CryptoProvider {
|
||||||
format: "der",
|
format: "der",
|
||||||
dsaEncoding: "der",
|
dsaEncoding: "der",
|
||||||
saltLength: params.saltLength,
|
saltLength: params.saltLength,
|
||||||
padding: constants.RSA_PKCS1_PSS_PADDING
|
padding: constants.RSA_PKCS1_PSS_PADDING,
|
||||||
},
|
},
|
||||||
signature
|
signature
|
||||||
);
|
);
|
||||||
|
|
|
@ -21,10 +21,10 @@ export class NodeLegacyServer implements LegacyServer {
|
||||||
method: "GET",
|
method: "GET",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `SkeletonKey ${email}:${this.config.key}`,
|
Authorization: `SkeletonKey ${email}:${this.config.key}`,
|
||||||
Accept: "application/vnd.padlock;version=1"
|
Accept: "application/vnd.padlock;version=1",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
res => {
|
(res) => {
|
||||||
if (res.statusCode !== 200) {
|
if (res.statusCode !== 200) {
|
||||||
resolve(null);
|
resolve(null);
|
||||||
return;
|
return;
|
||||||
|
@ -33,7 +33,7 @@ export class NodeLegacyServer implements LegacyServer {
|
||||||
let data = "";
|
let data = "";
|
||||||
|
|
||||||
res.setEncoding("utf8");
|
res.setEncoding("utf8");
|
||||||
res.on("data", chunk => (data += chunk));
|
res.on("data", (chunk) => (data += chunk));
|
||||||
res.on("end", () => {
|
res.on("end", () => {
|
||||||
if (!data) {
|
if (!data) {
|
||||||
resolve(null);
|
resolve(null);
|
||||||
|
@ -65,10 +65,10 @@ export class NodeLegacyServer implements LegacyServer {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `SkeletonKey ${email}:${this.config.key}`,
|
Authorization: `SkeletonKey ${email}:${this.config.key}`,
|
||||||
Accept: "application/vnd.padlock;version=1"
|
Accept: "application/vnd.padlock;version=1",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
res => {
|
(res) => {
|
||||||
if (res.statusCode !== 200) {
|
if (res.statusCode !== 200) {
|
||||||
reject("Received status code " + res.statusCode);
|
reject("Received status code " + res.statusCode);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -34,7 +34,8 @@ export class DefaultAccountProvisioning
|
||||||
Pick<
|
Pick<
|
||||||
AccountProvisioning,
|
AccountProvisioning,
|
||||||
"status" | "statusLabel" | "statusMessage" | "actionUrl" | "actionLabel" | "quota" | "disableFeatures"
|
"status" | "statusLabel" | "statusMessage" | "actionUrl" | "actionLabel" | "quota" | "disableFeatures"
|
||||||
> {
|
>
|
||||||
|
{
|
||||||
@ConfigParam()
|
@ConfigParam()
|
||||||
status: ProvisioningStatus = ProvisioningStatus.Active;
|
status: ProvisioningStatus = ProvisioningStatus.Active;
|
||||||
|
|
||||||
|
@ -400,16 +401,8 @@ export class SimpleProvisioner implements Provisioner {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const { accountId, status, statusLabel, statusMessage, actionUrl, actionLabel, scheduledUpdates, metaData } =
|
||||||
accountId,
|
entry.toRaw();
|
||||||
status,
|
|
||||||
statusLabel,
|
|
||||||
statusMessage,
|
|
||||||
actionUrl,
|
|
||||||
actionLabel,
|
|
||||||
scheduledUpdates,
|
|
||||||
metaData,
|
|
||||||
} = entry.toRaw();
|
|
||||||
|
|
||||||
httpRes.statusCode = 200;
|
httpRes.statusCode = 200;
|
||||||
httpRes.end(
|
httpRes.end(
|
||||||
|
|
|
@ -1,36 +1,36 @@
|
||||||
{
|
{
|
||||||
"name": "@padloc/tauri",
|
"name": "@padloc/tauri",
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"description": "Tauri Wrapper for packaging native apps",
|
"description": "Tauri Wrapper for packaging native apps",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"tauri": "tauri",
|
"tauri": "tauri",
|
||||||
"build": "tauri build",
|
"build": "tauri build",
|
||||||
"dev": "tauri dev"
|
"dev": "tauri dev"
|
||||||
},
|
},
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"clean-webpack-plugin": "3.0.0",
|
"clean-webpack-plugin": "3.0.0",
|
||||||
"css-loader": "5.2.6",
|
"css-loader": "5.2.6",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"html-webpack-plugin": "5.3.1",
|
"html-webpack-plugin": "5.3.1",
|
||||||
"style-loader": "2.0.0",
|
"style-loader": "2.0.0",
|
||||||
"ts-loader": "9.2.2",
|
"ts-loader": "9.2.2",
|
||||||
"ts-node": "10.0.0",
|
"ts-node": "10.0.0",
|
||||||
"typescript": "4.3.2",
|
"typescript": "4.3.2",
|
||||||
"webpack": "5.38.1",
|
"webpack": "5.38.1",
|
||||||
"webpack-cli": "4.7.0",
|
"webpack-cli": "4.7.0",
|
||||||
"webpack-dev-server": "3.11.2",
|
"webpack-dev-server": "3.11.2",
|
||||||
"@tauri-apps/cli": "1.0.0-beta.10"
|
"@tauri-apps/cli": "1.0.0-beta.10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@padloc/app": "4.0.0",
|
"@padloc/app": "4.0.0",
|
||||||
"@padloc/core": "4.0.0",
|
"@padloc/core": "4.0.0",
|
||||||
"@tauri-apps/api": "1.0.0-beta.8"
|
"@tauri-apps/api": "1.0.0-beta.8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "16.13.1",
|
"node": "16.13.1",
|
||||||
"npm": "8.2.0"
|
"npm": "8.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,65 +1,61 @@
|
||||||
{
|
{
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "Padloc",
|
"productName": "Padloc",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
},
|
|
||||||
"build": {
|
|
||||||
"distDir": "../dist",
|
|
||||||
"devPath": "http://localhost:8080",
|
|
||||||
"beforeDevCommand": "webpack serve",
|
|
||||||
"beforeBuildCommand": "webpack"
|
|
||||||
},
|
|
||||||
"tauri": {
|
|
||||||
"bundle": {
|
|
||||||
"active": true,
|
|
||||||
"targets": "all",
|
|
||||||
"identifier": "app.padloc",
|
|
||||||
"icon": [
|
|
||||||
"icons/icon.png",
|
|
||||||
"icons/icon.icns",
|
|
||||||
"icons/icon.ico"
|
|
||||||
],
|
|
||||||
"resources": [],
|
|
||||||
"externalBin": [],
|
|
||||||
"copyright": "",
|
|
||||||
"category": "DeveloperTool",
|
|
||||||
"shortDescription": "",
|
|
||||||
"longDescription": "",
|
|
||||||
"deb": {
|
|
||||||
"depends": [],
|
|
||||||
"useBootstrapper": false
|
|
||||||
},
|
|
||||||
"macOS": {
|
|
||||||
"frameworks": [],
|
|
||||||
"minimumSystemVersion": "",
|
|
||||||
"useBootstrapper": false,
|
|
||||||
"exceptionDomain": "",
|
|
||||||
"signingIdentity": null,
|
|
||||||
"entitlements": null
|
|
||||||
},
|
|
||||||
"windows": {
|
|
||||||
"certificateThumbprint": null,
|
|
||||||
"digestAlgorithm": "sha256",
|
|
||||||
"timestampUrl": ""
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"updater": {
|
"build": {
|
||||||
"active": false
|
"distDir": "../dist",
|
||||||
|
"devPath": "http://localhost:8080",
|
||||||
|
"beforeDevCommand": "webpack serve",
|
||||||
|
"beforeBuildCommand": "webpack"
|
||||||
},
|
},
|
||||||
"allowlist": {
|
"tauri": {
|
||||||
"all": true
|
"bundle": {
|
||||||
},
|
"active": true,
|
||||||
"windows": [
|
"targets": "all",
|
||||||
{
|
"identifier": "app.padloc",
|
||||||
"title": "Padloc",
|
"icon": ["icons/icon.png", "icons/icon.icns", "icons/icon.ico"],
|
||||||
"width": 1024,
|
"resources": [],
|
||||||
"height": 768,
|
"externalBin": [],
|
||||||
"resizable": true,
|
"copyright": "",
|
||||||
"fullscreen": false
|
"category": "DeveloperTool",
|
||||||
}
|
"shortDescription": "",
|
||||||
],
|
"longDescription": "",
|
||||||
"security": {
|
"deb": {
|
||||||
"csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
|
"depends": [],
|
||||||
|
"useBootstrapper": false
|
||||||
|
},
|
||||||
|
"macOS": {
|
||||||
|
"frameworks": [],
|
||||||
|
"minimumSystemVersion": "",
|
||||||
|
"useBootstrapper": false,
|
||||||
|
"exceptionDomain": "",
|
||||||
|
"signingIdentity": null,
|
||||||
|
"entitlements": null
|
||||||
|
},
|
||||||
|
"windows": {
|
||||||
|
"certificateThumbprint": null,
|
||||||
|
"digestAlgorithm": "sha256",
|
||||||
|
"timestampUrl": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"updater": {
|
||||||
|
"active": false
|
||||||
|
},
|
||||||
|
"allowlist": {
|
||||||
|
"all": true
|
||||||
|
},
|
||||||
|
"windows": [
|
||||||
|
{
|
||||||
|
"title": "Padloc",
|
||||||
|
"width": 1024,
|
||||||
|
"height": 768,
|
||||||
|
"resizable": true,
|
||||||
|
"fullscreen": false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"security": {
|
||||||
|
"csp": "default-src blob: data: filesystem: ws: http: https: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -58,7 +58,6 @@
|
||||||
rotate linear 1.2s infinite;
|
rotate linear 1.2s infinite;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<svg viewBox="0 0 100 100" class="spinner">
|
<svg viewBox="0 0 100 100" class="spinner">
|
||||||
|
|
|
@ -14,7 +14,6 @@ function createApp() {
|
||||||
|
|
||||||
await import("@padloc/app/src/elements/app");
|
await import("@padloc/app/src/elements/app");
|
||||||
|
|
||||||
|
|
||||||
if (document.readyState === "loading") {
|
if (document.readyState === "loading") {
|
||||||
document.addEventListener("DOMContentLoaded", createApp);
|
document.addEventListener("DOMContentLoaded", createApp);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue