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:
Bruno Bernardino 2021-12-20 15:01:25 +00:00
parent db18adf7fd
commit 50ae105b45
No known key found for this signature in database
GPG Key ID: D1B0A69ADD114ECE
67 changed files with 20160 additions and 26497 deletions

View File

@ -2,43 +2,43 @@ name: "Build And Publish Desktop Tauri Apps"
on: [workflow_dispatch]
jobs:
build_and_publish:
name: Build And Publish
build_and_publish:
name: Build And Publish
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-latest, windows-latest]
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: setup node
uses: actions/setup-node@v1
with:
node-version: 12
- name: install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: install tauri bundler
run: cargo install tauri-bundler --force
- name: install webkit2gtk (ubuntu only)
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y webkit2gtk-4.0
- name: install app dependencies and bootstrap packages
run: npm install
- uses: tauri-apps/tauri-action@v0
env:
PL_SERVER_URL: https://api.padloc.app
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: tauri-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version
releaseName: "Padloc (Tauri Edition) v__VERSION__"
body: "WARNING: The builds in this release are experimental. Use at your own risk!"
draft: true
prerelease: true
projectPath: packages/tauri
npmScript: build
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- name: setup node
uses: actions/setup-node@v1
with:
node-version: 12
- name: install Rust stable
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: install tauri bundler
run: cargo install tauri-bundler --force
- name: install webkit2gtk (ubuntu only)
if: matrix.platform == 'ubuntu-latest'
run: |
sudo apt-get update
sudo apt-get install -y webkit2gtk-4.0
- name: install app dependencies and bootstrap packages
run: npm install
- uses: tauri-apps/tauri-action@v0
env:
PL_SERVER_URL: https://api.padloc.app
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tagName: tauri-v__VERSION__ # the action automatically replaces \_\_VERSION\_\_ with the app version
releaseName: "Padloc (Tauri Edition) v__VERSION__"
body: "WARNING: The builds in this release are experimental. Use at your own risk!"
draft: true
prerelease: true
projectPath: packages/tauri
npmScript: build

View File

@ -3,18 +3,20 @@ name: Run Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 16.13.1
- name: Install dependencies
run: npm ci
- name: Run pwa test build
run: npm run pwa:build
- name: Test starting zero-config server
run: npm run server:start-dry
#- name: Run tests
# run: npm test
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 16.13.1
- name: Install dependencies
run: npm ci
- name: Run prettier check
run: npm run prettier:check
- name: Run pwa test build
run: npm run pwa:build
- name: Test starting zero-config server
run: npm run server:start-dry
#- name: Run tests
# run: npm test

View File

@ -1 +1,2 @@
app/src/core/*.js
package-lock.json

View File

@ -1,8 +1,6 @@
{
"lit-plugin.globalAttributes": [
"disabled"
],
"lit-plugin.globalAttributes": ["disabled"],
"files.associations": {
"*.svg": "html"
}
}
}

View File

@ -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]`.
Use `npm run prettier` to make "prettify" all files.
## Configuration
| Environment Variable | Default | Description |

View File

@ -7,4 +7,4 @@
"appId": "app.padloc",
"scheme": "padloc",
"author": "Martin Kleinschrodt <martin@maklesoft.com>"
}
}

View File

@ -1,4 +1,4 @@
module.exports = function(config) {
module.exports = function (config) {
config.set({
frameworks: ["mocha", "chai"],
files: ["test/tests.js"],
@ -9,6 +9,6 @@ module.exports = function(config) {
browsers: ["ChromeHeadless"],
autoWatch: false,
// singleRun: false, // Karma captures browsers, runs the tests and exits
concurrency: Infinity
concurrency: Infinity,
});
};

View File

@ -1,7 +1,5 @@
{
"packages": [
"packages/*"
],
"version": "4.0.0",
"exact": true
"packages": ["packages/*"],
"version": "4.0.0",
"exact": true
}

19
package-lock.json generated
View File

@ -11,6 +11,7 @@
"license": "GPL-3.0",
"devDependencies": {
"lerna": "4.0.0",
"prettier": "2.5.1",
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
@ -5658,6 +5659,18 @@
"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": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@ -12266,6 +12279,12 @@
"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": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",

View File

@ -1,40 +1,43 @@
{
"name": "padloc",
"private": true,
"version": "4.0.0",
"description": "A minimalist password manager",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"homepage": "https://padlock.io/",
"repository": {
"type": "git",
"url": "git+https://github.com/maklesoft/padlock.git"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"main": "main.js",
"devDependencies": {
"lerna": "4.0.0",
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
"scripts": {
"postinstall": "lerna bootstrap",
"bootstrap": "lerna bootstrap",
"pwa:build": "lerna run build --scope @padloc/pwa",
"pwa:start": "lerna run start --scope @padloc/pwa",
"server:start": "lerna run start --scope @padloc/server --stream",
"server:start-dry": "lerna run start-dry --stream --scope @padloc/server",
"electron:build": "cd packages/electron && npm run build && cd ../..",
"start": "npm run pwa:build && lerna run --scope '@padloc/{server,pwa}' --parallel start",
"dev": "lerna run --parallel --scope '@padloc/{server,pwa}' --parallel dev",
"tauri:dev": "lerna run --parallel --scope '@padloc/{server,tauri}' --parallel dev",
"repl": "cd packages/server && npm run repl && cd ../..",
"test": "lerna run test",
"locale:extract": "lerna run extract --scope '@padloc/locale'",
"add": "lerna add $1 --scope=@padloc/$scope",
"remove": "rm packages/$scope/package-lock.json && lerna exec \"npm uninstall $1\" --scope=@padloc/$scope"
}
"name": "padloc",
"private": true,
"version": "4.0.0",
"description": "A minimalist password manager",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"homepage": "https://padloc.app/",
"repository": {
"type": "git",
"url": "git+https://github.com/padloc/padloc.git"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"main": "main.js",
"devDependencies": {
"lerna": "4.0.0",
"prettier": "2.5.1",
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
"scripts": {
"postinstall": "lerna bootstrap",
"bootstrap": "lerna bootstrap",
"pwa:build": "lerna run build --scope @padloc/pwa",
"pwa:start": "lerna run start --scope @padloc/pwa",
"server:start": "lerna run start --scope @padloc/server --stream",
"server:start-dry": "lerna run start-dry --stream --scope @padloc/server",
"electron:build": "cd packages/electron && npm run build && cd ../..",
"start": "npm run pwa:build && lerna run --scope '@padloc/{server,pwa}' --parallel start",
"dev": "lerna run --parallel --scope '@padloc/{server,pwa}' --parallel dev",
"tauri:dev": "lerna run --parallel --scope '@padloc/{server,tauri}' --parallel dev",
"repl": "cd packages/server && npm run repl && cd ../..",
"test": "lerna run test",
"locale:extract": "lerna run extract --scope '@padloc/locale'",
"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 ."
}
}

View File

@ -1,64 +1,64 @@
{
"name": "@padloc/app",
"version": "4.0.0",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"private": true,
"files": [
"src",
"assets",
"types",
"tsconfig.json"
],
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/app"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"dependencies": {
"@padloc/core": "4.0.0",
"@padloc/locale": "4.0.0",
"@simplewebauthn/browser": "4.0.0",
"@simplewebauthn/typescript-types": "4.0.0",
"@types/dompurify": "2.3.1",
"@types/marked": "3.0.1",
"@types/papaparse": "5.2.5",
"@types/qrcode": "1.4.1",
"@types/ua-parser-js": "0.7.36",
"@types/workbox-precaching": "4.3.1",
"@types/workbox-sw": "4.3.1",
"@types/workbox-window": "4.3.3",
"@types/zxcvbn": "4.4.1",
"@webcomponents/webcomponentsjs": "2.5.0",
"autosize": "5.0.0",
"date-fns": "2.22.1",
"dompurify": "2.3.3",
"event-target-shim": "6.0.2",
"http-server": "0.12.3",
"jsqr": "1.4.0",
"jszip": "3.7.1",
"lit": "2.0.0-rc.2",
"localforage": "1.9.0",
"marked": "3.0.4",
"papaparse": "5.3.1",
"qrcode": "1.4.4",
"reflect-metadata": "0.1.13",
"typescript": "4.4.3",
"ua-parser-js": "0.7.28",
"workbox-precaching": "6.2.0",
"workbox-sw": "6.1.5",
"workbox-window": "6.1.5",
"zxcvbn": "4.4.2"
},
"devDependencies": {
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "8.4.0"
},
"description": "Padloc Web-Based UI package"
"name": "@padloc/app",
"version": "4.0.0",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"private": true,
"files": [
"src",
"assets",
"types",
"tsconfig.json"
],
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/app"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"dependencies": {
"@padloc/core": "4.0.0",
"@padloc/locale": "4.0.0",
"@simplewebauthn/browser": "4.0.0",
"@simplewebauthn/typescript-types": "4.0.0",
"@types/dompurify": "2.3.1",
"@types/marked": "3.0.1",
"@types/papaparse": "5.2.5",
"@types/qrcode": "1.4.1",
"@types/ua-parser-js": "0.7.36",
"@types/workbox-precaching": "4.3.1",
"@types/workbox-sw": "4.3.1",
"@types/workbox-window": "4.3.3",
"@types/zxcvbn": "4.4.1",
"@webcomponents/webcomponentsjs": "2.5.0",
"autosize": "5.0.0",
"date-fns": "2.22.1",
"dompurify": "2.3.3",
"event-target-shim": "6.0.2",
"http-server": "0.12.3",
"jsqr": "1.4.0",
"jszip": "3.7.1",
"lit": "2.0.0-rc.2",
"localforage": "1.9.0",
"marked": "3.0.4",
"papaparse": "5.3.1",
"qrcode": "1.4.4",
"reflect-metadata": "0.1.13",
"typescript": "4.4.3",
"ua-parser-js": "0.7.28",
"workbox-precaching": "6.2.0",
"workbox-sw": "6.1.5",
"workbox-window": "6.1.5",
"zxcvbn": "4.4.2"
},
"devDependencies": {
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "8.4.0"
},
"description": "Padloc Web-Based UI package"
}

View File

@ -45,7 +45,7 @@ export class Dialog<I, R> extends LitElement {
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);
this.open = true;

View File

@ -15,7 +15,7 @@ import { stringToBytes } from "@padloc/core/src/encoding";
@customElement("pl-import-dialog")
export class ImportDialog extends Dialog<File, void> {
@state()
private _rawData: null | string | ArrayBuffer = "";
private _file: File;
@state()
private _items: VaultItem[] = [];
@ -71,19 +71,10 @@ export class ImportDialog extends Dialog<File, void> {
await this.updateComplete;
const result = super.show();
const reader = new FileReader();
reader.onload = async () => {
this._rawData = reader.result;
this._formatSelect.value = (imp.guessFormat(file, this._rawData) || imp.CSV).value;
this._parseData();
this._vaultSelect.value = app.mainVault!;
};
if (imp.doesFileRequireReadingAsBinary(file)) {
reader.readAsArrayBuffer(file);
} else {
reader.readAsText(file);
}
this._file = file;
this._formatSelect.value = ((await imp.guessFormat(file)) || imp.CSV).value;
await this._parseData();
this._vaultSelect.value = app.mainVault!;
return result;
}
@ -100,7 +91,7 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
}
private async _parseData(): Promise<void> {
const rawStr = this._rawData;
const file = this._file;
switch (this._formatSelect.value) {
case imp.PADLOCK_LEGACY.value:
@ -111,7 +102,7 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
type: "password",
validate: async (pwd: string) => {
try {
this._items = await imp.asPadlockLegacy(rawStr as string, pwd);
this._items = await imp.asPadlockLegacy(file, pwd);
} catch (e) {
throw $l("Wrong Password");
}
@ -125,13 +116,13 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
}
break;
case imp.LASTPASS.value:
this._items = await imp.asLastPass(rawStr as string);
this._items = await imp.asLastPass(file);
break;
case imp.CSV.value:
this._items = await imp.asCSV(rawStr as string);
this._items = await imp.asCSV(file);
break;
case imp.ONEPUX.value:
this._items = await imp.as1Pux(rawStr);
this._items = await imp.as1Pux(file);
break;
case imp.PBES2.value:
this.open = false;
@ -141,7 +132,7 @@ Github,"work,coding",https://github.com,john.doe@gmail.com,129lskdf93`)
type: "password",
validate: async (pwd: string) => {
try {
this._items = await imp.asPBES2Container(rawStr as string, pwd);
this._items = await imp.asPBES2Container(file, pwd);
} catch (e) {
throw $l("Wrong Password");
}

View File

@ -173,9 +173,8 @@ export class Popover extends LitElement {
}
private _getAutoAlignment(): PopoverAlignment {
const preferred = (Array.isArray(this.preferAlignment)
? [...this.preferAlignment]
: [this.preferAlignment]
const preferred = (
Array.isArray(this.preferAlignment) ? [...this.preferAlignment] : [this.preferAlignment]
).reverse();
const alignments = [...ALIGNMENTS].sort((a, b) => preferred.indexOf(b) - preferred.indexOf(a));
return alignments.find((alignment) => this._isWithinBounds(this._getPosition(alignment))) || alignments[0];

View File

@ -65,7 +65,12 @@ export class SettingsTools extends StateMixin(LitElement) {
</pl-scroller>
</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()}
/>
`;
}
}

View File

@ -1,308 +1,283 @@
import { loadAsync } from 'jszip';
import { loadAsync } from "jszip";
export type OnePuxItemDetailsLoginField = {
value: string;
id: string;
name: string;
fieldType: 'A' | 'B' | 'C' | 'E' | 'I' | 'N' | 'P' | 'R' | 'S' | 'T' | 'U';
designation?: 'username' | 'password';
value: string;
id: string;
name: string;
fieldType: "A" | "B" | "C" | "E" | "I" | "N" | "P" | "R" | "S" | "T" | "U";
designation?: "username" | "password";
};
export type OnePuxItemDetailsSection = {
title: string;
name: string;
fields: [
{
title: string;
id: string;
value: {
concealed?: string;
reference?: string;
string?: string;
email?: string;
phone?: string;
url?: string;
totp?: string;
gender?: string;
creditCardType?: string;
creditCardNumber?: string;
monthYear?: number;
date?: number;
};
indexAtSource: number;
guarded: boolean;
multiline: boolean;
dontGenerate: boolean;
inputTraits: {
keyboard: string;
correction: string;
capitalization: string;
};
},
];
title: string;
name: string;
fields: [
{
title: string;
id: string;
value: {
concealed?: string;
reference?: string;
string?: string;
email?: string;
phone?: string;
url?: string;
totp?: string;
gender?: string;
creditCardType?: string;
creditCardNumber?: string;
monthYear?: number;
date?: number;
};
indexAtSource: number;
guarded: boolean;
multiline: boolean;
dontGenerate: boolean;
inputTraits: {
keyboard: string;
correction: string;
capitalization: string;
};
}
];
};
export type OnePuxItemDetailsPasswordHistory = {
value: string;
time: number;
value: string;
time: number;
};
export type OnePuxItemOverviewUrl = {
label: string;
url: string;
label: string;
url: string;
};
export type OnePuxItem = {
item?: {
uuid: string;
favIndex: number;
createdAt: number;
updatedAt: number;
trashed: boolean;
categoryUuid: string;
details: {
loginFields: OnePuxItemDetailsLoginField[];
notesPlain?: string;
sections: OnePuxItemDetailsSection[];
passwordHistory: OnePuxItemDetailsPasswordHistory[];
documentAttributes?: {
fileName: string;
documentId: string;
decryptedSize: number;
};
item?: {
uuid: string;
favIndex: number;
createdAt: number;
updatedAt: number;
trashed: boolean;
categoryUuid: string;
details: {
loginFields: OnePuxItemDetailsLoginField[];
notesPlain?: string;
sections: OnePuxItemDetailsSection[];
passwordHistory: OnePuxItemDetailsPasswordHistory[];
documentAttributes?: {
fileName: string;
documentId: string;
decryptedSize: number;
};
};
overview: {
subtitle: string;
urls?: OnePuxItemOverviewUrl[];
title: string;
url: string;
ps?: number;
pbe?: number;
pgrng?: boolean;
tags?: string[];
};
};
overview: {
subtitle: string;
urls?: OnePuxItemOverviewUrl[];
title: string;
url: string;
ps?: number;
pbe?: number;
pgrng?: boolean;
tags?: string[];
file?: {
attrs: {
uuid: string;
name: string;
type: string;
};
path: string;
};
};
file?: {
attrs: {
uuid: string;
name: string;
type: string;
};
path: string;
};
};
export type OnePuxVault = {
attrs: {
uuid: string;
desc: string;
avatar: string;
name: string;
type: 'P' | 'E' | 'U';
};
items: OnePuxItem[];
attrs: {
uuid: string;
desc: string;
avatar: string;
name: string;
type: "P" | "E" | "U";
};
items: OnePuxItem[];
};
export type OnePuxAccount = {
attrs: {
accountName: string;
name: string;
avatar: string;
email: string;
uuid: string;
domain: string;
};
vaults: OnePuxVault[];
attrs: {
accountName: string;
name: string;
avatar: string;
email: string;
uuid: string;
domain: string;
};
vaults: OnePuxVault[];
};
export type OnePuxData = {
accounts: OnePuxAccount[];
accounts: OnePuxAccount[];
};
export type OnePuxAttributes = {
version: number;
description: string;
createdAt: number;
version: number;
description: string;
createdAt: number;
};
export type OnePuxExport = {
attributes: OnePuxAttributes;
data: OnePuxData;
attributes: OnePuxAttributes;
data: OnePuxData;
};
export const parse1PuxFile = async (
fileContents: string | ArrayBuffer,
) => {
try {
const zip = await loadAsync(fileContents);
export async function parse1PuxFile(fileContents: ArrayBuffer): Promise<OnePuxExport> {
try {
const zip = await loadAsync(fileContents);
const attributesContent = await zip
.file('export.attributes')!
.async('string');
const attributes = JSON.parse(attributesContent);
const dataContent = await zip.file('export.data')!.async('string');
const data = JSON.parse(dataContent);
const attributesContent = await zip.file("export.attributes")!.async("string");
const attributes = JSON.parse(attributesContent);
const dataContent = await zip.file("export.data")!.async("string");
const data = JSON.parse(dataContent);
return {
attributes,
data,
} as OnePuxExport;
} catch (error) {
console.error('Failed to parse .1pux file');
throw error;
}
};
return {
attributes,
data,
} as OnePuxExport;
} catch (error) {
console.error("Failed to parse .1pux file");
throw error;
}
}
type RowData = {
name: string;
tags: string;
url: string;
username: string;
password: string;
notes: string;
extraFields: ExtraField[];
name: string;
tags: string;
url: string;
username: string;
password: string;
notes: string;
extraFields: ExtraField[];
};
type ExtraFieldType =
| 'username'
| 'password'
| 'url'
| 'email'
| 'date'
| 'month'
| 'credit'
| 'phone'
| 'totp'
| 'text';
| "username"
| "password"
| "url"
| "email"
| "date"
| "month"
| "credit"
| "phone"
| "totp"
| "text";
type ExtraField = { name: string; value: string; type: ExtraFieldType };
type ParseFieldTypeToExtraFieldType = (
field: OnePuxItemDetailsLoginField,
) => ExtraFieldType;
const parseFieldTypeToExtraFieldType: ParseFieldTypeToExtraFieldType = (
field,
) => {
if (field.designation === 'username') {
return 'username';
} 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),
});
function parseFieldTypeToExtraFieldType(field: OnePuxItemDetailsLoginField): ExtraFieldType {
if (field.designation === "username") {
return "username";
} else if (field.designation === "password") {
return "password";
} else if (field.fieldType === "E") {
return "email";
} else if (field.fieldType === "U") {
return "url";
}
});
return "text";
}
// Extract some more extraFields
item.details.sections.forEach((section) => {
section.fields.forEach((field) => {
let value = '';
let type: ExtraFieldType = 'text';
export function parseToRowData(item: OnePuxItem["item"], defaultTags?: string[]): RowData | undefined {
if (!item) {
return;
}
if (Object.prototype.hasOwnProperty.call(field.value, 'concealed')) {
value = field.value.concealed || '';
} else if (
Object.prototype.hasOwnProperty.call(field.value, 'reference')
) {
value = field.value.reference || '';
} else if (Object.prototype.hasOwnProperty.call(field.value, 'string')) {
value = field.value.string || '';
} 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);
}
const rowData: RowData = {
name: item.overview.title,
tags: [...(defaultTags || []), ...(item.overview.tags || [])].join(","),
url: item.overview.url || "",
username: "",
password: "",
notes: item.details.notesPlain || "",
extraFields: [],
};
rowData.extraFields.push({
name: field.title || field.id,
value,
type,
});
// 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 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;
}

View File

@ -7,7 +7,7 @@ const defaults = {
initialDelay: 0,
fullDuration: 1000,
clear: false,
direction: "normal"
direction: "normal",
};
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}`;
if (clear) {
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 = {}) {

View File

@ -5,8 +5,9 @@ import { VaultItem, Field, createVaultItem, FieldType } from "@padloc/core/src/i
import { Err, ErrorCode } from "@padloc/core/src/error";
import { uuid } from "@padloc/core/src/util";
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 {
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;
}
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 parsed = papa.parse(data);
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);
}
/**
* Checks if a given string represents a Padlock enrypted backup
*/
export function isPadlockV1(data: string): boolean {
export async function isPadlockV1(file: File): Promise<boolean> {
try {
const data = await readFileAsText(file);
return validateLegacyContainer(unmarshal(data));
} catch (e) {
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));
await container.unlock(password);
return importLegacyContainer(container);
@ -146,16 +147,18 @@ export async function importLegacyContainer(container: PBES2Container) {
return Promise.all(items);
}
export function isPBES2Container(data: string) {
export async function isPBES2Container(file: File) {
try {
const data = await readFileAsText(file);
new PBES2Container().fromRaw(unmarshal(data));
return true;
} catch (e) {
} catch (error) {
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));
await container.unlock(password);
@ -234,7 +237,8 @@ async function lpParseRow(row: string[]): Promise<VaultItem> {
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();
let items = papa
.parse(data)
@ -247,22 +251,26 @@ export async function asLastPass(data: string): Promise<VaultItem[]> {
return Promise.all(items);
}
/**
* Checks if a given string represents a LastPass CSV file
*/
export function isLastPass(data: string): boolean {
export async function isLastPass(file: File): Promise<boolean> {
try {
const data = await readFileAsText(file);
return data.split("\n")[0] === "url,username,password,extra,name,grouping,fav";
} catch (error) {
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) {
return;
}
const { parseToRowData } = await import("./1pux-parser");
const rowData = parseToRowData(item, [accountName, vaultName]);
if (!rowData) {
@ -270,10 +278,10 @@ async function parse1PuxItem(accountName: string, vaultName: string, item: OnePu
}
const itemName = rowData.name;
const tags = rowData.tags.split(',');
const tags = rowData.tags.split(",");
if (item.trashed) {
tags.push('trashed');
tags.push("trashed");
}
let fields: Field[] = [
@ -287,10 +295,10 @@ async function parse1PuxItem(accountName: string, vaultName: string, item: OnePu
}
for (const extraField of rowData.extraFields) {
if (extraField.type === 'totp') {
if (extraField.type === "totp") {
// Extract just the secret
try {
const secret = new URL(extraField.value).searchParams.get('secret');
const secret = new URL(extraField.value).searchParams.get("secret");
if (secret) {
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
}
} 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);
}
export async function as1Pux(data: null | string | ArrayBuffer): Promise<VaultItem[]> {
if (!data) {
throw new Err(ErrorCode.INVALID_1PUX);
}
export async function as1Pux(file: File): Promise<VaultItem[]> {
try {
const { parse1PuxFile } = await import("./1pux-parser");
const data = await readFileAsArrayBuffer(file);
const dataExport = await parse1PuxFile(data);
const items = [];
for (const account of dataExport.data.accounts) {
for (const vault of account.vaults) {
for (const vaultItem of vault.items) {
@ -331,7 +338,7 @@ export async function as1Pux(data: null | string | ArrayBuffer): Promise<VaultIt
return items;
} 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
*/
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 {
if (isPBES2Container(data as string)) {
return PBES2;
}
if (isPadlockV1(data as string)) {
return PADLOCK_LEGACY;
}
if (isLastPass(data as string)) {
return LASTPASS;
}
export async function guessFormat(file: File): Promise<ImportFormat> {
// Try to guess sync first (won't need parsing)
if (is1Pux(file)) {
return ONEPUX;
}
return CSV;
}
export function doesFileRequireReadingAsBinary(file: File): boolean {
if (is1Pux(file)) {
return true;
if (await isPBES2Container(file)) {
return PBES2;
}
if (await isPadlockV1(file)) {
return PADLOCK_LEGACY;
}
if (await isLastPass(file)) {
return LASTPASS;
}
return false;
return CSV;
}

View File

@ -1,7 +1,7 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes" />
<title>lit-element tests</title>
<link href="../node_modules/mocha/mocha.css" rel="stylesheet" />
<script src="../node_modules/mocha/mocha.js"></script>
@ -9,7 +9,7 @@
<script>
mocha.setup({
ui: "tdd",
timeout: 1000000
timeout: 1000000,
});
</script>
<script type="module" src="dist/crypto.js"></script>

View File

@ -1,5 +1,5 @@
interface Navigator {
Backbutton: any
Backbutton: any;
}
interface Window {

View File

@ -1,82 +1,82 @@
{
"name": "app.padloc",
"version": "4.0.0",
"displayName": "Padloc",
"private": true,
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"cordova": {
"platforms": [
"ios",
"android"
],
"plugins": {
"cordova-plugin-app-version": {},
"cordova-plugin-backbutton": {},
"ionic-plugin-keyboard": {},
"cordova-plugin-statusbar": {},
"cordova-clipboard": {},
"cordova-plugin-qrscanner": {},
"cordova-plugin-device": {},
"cordova-plugin-x-socialsharing": {
"ANDROID_SUPPORT_V4_VERSION": "24.1.1+",
"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."
},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-fingerprint-aio": {
"FACEID_USAGE_DESCRIPTION": " "
},
"cordova-plugin-privacyscreen": {},
"cordova-plugin-inappbrowser": {},
"cordova-plugin-androidx-adapter": {}
"name": "app.padloc",
"version": "4.0.0",
"displayName": "Padloc",
"private": true,
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"cordova": {
"platforms": [
"ios",
"android"
],
"plugins": {
"cordova-plugin-app-version": {},
"cordova-plugin-backbutton": {},
"ionic-plugin-keyboard": {},
"cordova-plugin-statusbar": {},
"cordova-clipboard": {},
"cordova-plugin-qrscanner": {},
"cordova-plugin-device": {},
"cordova-plugin-x-socialsharing": {
"ANDROID_SUPPORT_V4_VERSION": "24.1.1+",
"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."
},
"cordova-plugin-splashscreen": {},
"cordova-plugin-ionic-webview": {
"ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+"
},
"cordova-plugin-fingerprint-aio": {
"FACEID_USAGE_DESCRIPTION": " "
},
"cordova-plugin-privacyscreen": {},
"cordova-plugin-inappbrowser": {},
"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"
}
}

View File

@ -13,4 +13,3 @@
"include": ["src/**/*.ts", "../app/types/*.ts"],
"exclude": ["node_modules/**/*.ts"]
}

View File

@ -105,24 +105,7 @@ module.exports = {
.toBuffer();
const iosIconSizes = [
20,
29,
40,
50,
57,
58,
60,
72,
76,
80,
87,
100,
114,
120,
144,
152,
167,
180,
20, 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];

View File

@ -1,38 +1,38 @@
{
"name": "@padloc/core",
"version": "4.0.0",
"description": "padloc core module",
"main": "index.js",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPLv3",
"files": [
"src",
"vendor",
"tsconfig.json"
],
"dependencies": {
"@padloc/locale": "4.0.0",
"typescript": "4.4.3"
},
"devDependencies": {
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "8.4.0",
"ts-node": "10.0.0",
"typedoc": "0.22.4"
},
"scripts": {
"test": "cd test && mocha -r ts-node/register *.ts",
"docs": "typedoc --mode modules --out docs"
},
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/core"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
"name": "@padloc/core",
"version": "4.0.0",
"description": "padloc core module",
"main": "index.js",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPLv3",
"files": [
"src",
"vendor",
"tsconfig.json"
],
"dependencies": {
"@padloc/locale": "4.0.0",
"typescript": "4.4.3"
},
"devDependencies": {
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "8.4.0",
"ts-node": "10.0.0",
"typedoc": "0.22.4"
},
"scripts": {
"test": "cd test && mocha -r ts-node/register *.ts",
"docs": "typedoc --mode modules --out docs"
},
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/core"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
}

View File

@ -6,7 +6,7 @@ import { getCryptoProvider as getProvider } from "./platform";
import { Err, ErrorCode } from "./error";
import { RequestProgress } from "./transport";
function readFile(blob: File): Promise<Uint8Array> {
export async function readFileAsUint8Array(blob: File): Promise<Uint8Array> {
return new Promise((resolve, reject) => {
const reader = new FileReader();
@ -15,16 +15,33 @@ function readFile(blob: File): Promise<Uint8Array> {
resolve(result);
};
reader.onerror = e => {
reader.onerror = (error) => {
reader.abort();
reject(e);
reject(error);
};
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) => {
const reader = new FileReader();
@ -32,9 +49,9 @@ function readAsText(blob: File): Promise<string> {
resolve(reader.result as string);
};
reader.onerror = e => {
reader.onerror = (error) => {
reader.abort();
reject(e);
reject(error);
};
reader.readAsText(blob);
@ -49,7 +66,7 @@ function readFileAsDataURL(blob: File): Promise<string> {
resolve(reader.result as string);
};
reader.onerror = e => {
reader.onerror = (e) => {
reader.abort();
reject(e);
};
@ -89,7 +106,7 @@ export class Attachment extends SimpleContainer {
super();
Object.assign(this, {
_key: key,
...info
...info,
});
}
@ -100,7 +117,7 @@ export class Attachment extends SimpleContainer {
name: this.name,
type: this.type,
size: this.size,
key: this._key
key: this._key,
});
}
@ -113,11 +130,11 @@ export class Attachment extends SimpleContainer {
this.size = file.size;
this.name = file.name;
const data = await readFile(file);
const data = await readFileAsUint8Array(file);
this._key = await getProvider().generateKey({
algorithm: "AES",
keySize: this.encryptionParams.keySize
keySize: this.encryptionParams.keySize,
} as AESKeyParams);
await this.setData(data);
@ -141,7 +158,7 @@ export class Attachment extends SimpleContainer {
async toText(): Promise<string> {
const file = await this.toFile();
return readAsText(file);
return readFileAsText(file);
}
validate() {

View File

@ -7,7 +7,7 @@ export enum PlanType {
Premium,
Family,
Team,
Business
Business,
}
export class Plan extends Serializable {
@ -37,7 +37,7 @@ export enum SubscriptionStatus {
Trialing = "trialing",
Active = "active",
Inactive = "inactive",
Canceled = "canceled"
Canceled = "canceled",
}
export class Subscription extends Serializable {

View File

@ -41,10 +41,10 @@ export class Client extends API {
method,
typeof input === "undefined" ? [] : [input instanceof Serializable ? input.toRaw() : input],
progress
).then(res => {
).then((res) => {
return output
? 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)
: res.result;
}) as PromiseWithProgress<any>;
@ -85,7 +85,7 @@ export class Client extends API {
}
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) {
progress.error = err;
}

View File

@ -31,7 +31,7 @@ export class VaultItemCollection extends Serializable implements Iterable<VaultI
constructor(items: VaultItem[] = []) {
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` */
@ -91,8 +91,8 @@ export class VaultItemCollection extends Serializable implements Iterable<VaultI
protected _toRaw(version: string) {
return {
items: Array.from(this).map(item => item.toRaw(version)),
changes: [...this._changes]
items: Array.from(this).map((item) => item.toRaw(version)),
changes: [...this._changes],
};
}

View File

@ -65,15 +65,15 @@ export function parseLegacyContainer(raw: LegacyContainer): PBES2Container {
tagSize: raw.ts,
keySize: raw.keySize,
iv: raw.iv,
additionalData: raw.adata
additionalData: raw.adata,
},
keyParams: {
algorithm: "PBKDF2",
hash: "SHA-256",
keySize: raw.keySize,
iterations: raw.iter,
salt: raw.salt
salt: raw.salt,
},
encryptedData: raw.ct
encryptedData: raw.ct,
});
}

View File

@ -20,22 +20,22 @@ export const MIGRATIONS: Migration[] = [
up: ({ mainVault, orgs, ...rest }: any) => ({
mainVault: { id: mainVault },
orgs: orgs.map((org: any) => ({
id: org
id: org,
})),
...rest
...rest,
}),
down: ({ mainVault, orgs, ...rest }: any) => ({
mainVault: mainVault.id,
orgs: orgs.map((org: any) => org.id),
...rest
})
...rest,
}),
},
all: {
up: (raw: any, kind?: string) => ({ kind, ...raw }),
down: ({ kind, ...rest }) => rest
}
}
}
down: ({ kind, ...rest }) => rest,
},
},
},
];
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 {
return version
.split(".")
.map(part => part.padStart(3, "0"))
.map((part) => part.padStart(3, "0"))
.join();
}
@ -58,7 +58,7 @@ export function upgrade(kind: string, raw: any, version: string = LATEST_VERSION
}
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) {
@ -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 {
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) {

View File

@ -115,9 +115,7 @@ export interface Platform {
authenticatorIndex?: number;
}): Promise<StartAuthRequestResponse>;
completeAuthRequest(
req: StartAuthRequestResponse
): Promise<{
completeAuthRequest(req: StartAuthRequestResponse): Promise<{
token: string;
accountStatus: AccountStatus;
deviceTrusted: boolean;
@ -193,9 +191,7 @@ export class StubPlatform implements Platform {
throw new Error("Method not implemented.");
}
async completeAuthRequest(
_req: StartAuthRequestResponse
): Promise<{
async completeAuthRequest(_req: StartAuthRequestResponse): Promise<{
token: string;
accountStatus: AccountStatus;
deviceTrusted: boolean;
@ -293,9 +289,7 @@ export function startAuthRequest(opts: {
return platform.startAuthRequest(opts);
}
export function completeAuthRequest(
req: StartAuthRequestResponse
): Promise<{
export function completeAuthRequest(req: StartAuthRequestResponse): Promise<{
token: string;
accountStatus: AccountStatus;
deviceTrusted: boolean;

View File

@ -30,7 +30,7 @@ type Position = [number, number];
export const defaults: Options = {
height: 9,
width: 17,
symbols: [" ", ".", "o", "+", "=", "*", "B", "O", "X", "@", "%", "&", "#", "/", "^", "S", "E"]
symbols: [" ", ".", "o", "+", "=", "*", "B", "O", "X", "@", "%", "&", "#", "/", "^", "S", "E"],
};
// Converts a buffer to a binary moves array
@ -120,6 +120,6 @@ export function randomArt(fingerprint: Uint8Array, opts: Partial<Options> = {}):
width: options.width,
height: options.height,
values: vals,
symbols: vals.map(line => line.map(val => symbols[val]))
symbols: vals.map((line) => line.map((val) => symbols[val])),
};
}

View File

@ -75,7 +75,7 @@ const SJCLProvider = {
} catch (e) {
throw new Err(ErrorCode.ENCRYPTION_FAILED);
}
}
},
};
export default SJCLProvider;

View File

@ -29,12 +29,12 @@ export function appSpec(): Spec {
const user = {
email: "lengden@olga.com",
name: "Lengden Olga",
password: "correct battery horse staple"
password: "correct battery horse staple",
};
const otherUser = {
email: "max@mustermann.com",
name: "Max Mustermann",
password: "password"
password: "password",
};
let sharedVaultID = "";
// let otherVaultID = "";
@ -191,7 +191,7 @@ export function appSpec(): Spec {
test("Simulataneous Edit", async () => {
const [item1, item2] = await Promise.all([
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 })]);

View File

@ -7,7 +7,7 @@ import {
HMACKeyParams,
PBKDF2Params,
RSASigningParams,
RSAEncryptionParams
RSAEncryptionParams,
} from "../crypto";
import { Spec } from "./spec";
@ -26,7 +26,7 @@ const fixtures = {
plain: stringToBytes("Hello World!"),
encrypted: base64ToBytes(
"eAJDfWUdgL4Wl0UDsA0WsmHE29MNAnTvSjus3N0BP6foD0fFZBlrfmRbF-KjY_2zYhgaqn7E4pEKMB20tPDC-JYcAJO8PMWOR6PdLBsBCUTbdYy062iwFWgWfzSFV2LDy-G2t9HL2CbDoDAdsh1fNGIm81nY9sXbB0kKM4uNXKTdVl49Cwf30jiRRpABV_tSPmQjkHDVWOphVEY5ex0hhveRC6vfO1YZ21-CuoTa1gRq-ab21V-Pl5rfQ0RHsDgtvvSJ8_3ihzCkOTjd2Anj0GiKEsCeV0NaEgT-e5WyDj2zYNIsVOoMmB65UUkXX002Ycc2cGuoYw2uudZQSaAlqg"
)
),
},
aes: {
key: base64ToBytes("fe8Chv8F4je2wW3u67H6KFVtlRuH4VWBgN1FXPoOKAw"),
@ -34,8 +34,8 @@ const fixtures = {
iv: base64ToBytes("Tg9aODkCqoBQDktZAXLEhw"),
additionalData: base64ToBytes("dJvkr9MnycfsAHiqZStEOg"),
plain: stringToBytes("Hello World!"),
encrypted: base64ToBytes("A4ODqQsZrMQ4hXxV-RyYVDhdjTvk1MQ7MG8j_A")
}
encrypted: base64ToBytes("A4ODqQsZrMQ4hXxV-RyYVDhdjTvk1MQ7MG8j_A"),
},
};
export function cryptoProviderSpec(provider: CryptoProvider): Spec {
@ -59,7 +59,7 @@ export function cryptoProviderSpec(provider: CryptoProvider): Spec {
let err;
try {
await provider.hash(input, ({ algorithm: "BLAH" } as any) as HashParams);
await provider.hash(input, { algorithm: "BLAH" } as any as HashParams);
} catch (e) {
err = e;
}

View File

@ -13,7 +13,7 @@ import {
AESEncryptionParams,
RSAEncryptionParams,
HashParams,
RSASigningParams
RSASigningParams,
} from "./crypto";
import { concatBytes as concat, equalBytes as equal } from "./encoding";
import { Err, ErrorCode } from "./error";
@ -50,7 +50,7 @@ export class StubCryptoProvider implements CryptoProvider {
const key = await this.randomBytes(32);
return {
publicKey: key,
privateKey: key
privateKey: key,
};
}
}

View File

@ -172,10 +172,10 @@ export class BigInteger {
setBit(n: number): BigInteger;
// (public) this & ~(1<<n)
clearBit(n: number): BigInteger
clearBit(n: number): BigInteger;
// (public) this ^ (1<<n)
flipBit(n: number): BigInteger
flipBit(n: number): BigInteger;
// (protected) r = this + a
addTo(a: BigInteger, r: BigInteger): void;

View File

@ -1369,174 +1369,14 @@ function bnModInverse(m) {
}
var lowprimes = [
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,
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
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,
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];

View File

@ -1,2 +1 @@
export var sjcl: any
export var sjcl: any;

View File

@ -68,8 +68,8 @@ var sjcl = {
* Ciphertext is corrupt.
* @constructor
*/
corrupt: function(message) {
this.toString = function() {
corrupt: function (message) {
this.toString = function () {
return "CORRUPT: " + this.message;
};
this.message = message;
@ -79,8 +79,8 @@ var sjcl = {
* Invalid parameter.
* @constructor
*/
invalid: function(message) {
this.toString = function() {
invalid: function (message) {
this.toString = function () {
return "INVALID: " + this.message;
};
this.message = message;
@ -90,8 +90,8 @@ var sjcl = {
* Bug or missing feature in SJCL.
* @constructor
*/
bug: function(message) {
this.toString = function() {
bug: function (message) {
this.toString = function () {
return "BUG: " + this.message;
};
this.message = message;
@ -101,13 +101,13 @@ var sjcl = {
* Something isn't ready.
* @constructor
*/
notReady: function(message) {
this.toString = function() {
notReady: function (message) {
this.toString = function () {
return "NOT READY: " + this.message;
};
this.message = message;
}
}
},
},
};
/** @fileOverview Low-level AES implementation.
*
@ -133,7 +133,7 @@ var sjcl = {
* @constructor
* @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]) {
this._precompute();
}
@ -204,7 +204,7 @@ sjcl.cipher.aes.prototype = {
* @param {Array} data The plaintext.
* @return {Array} The ciphertext.
*/
encrypt: function(data) {
encrypt: function (data) {
return this._crypt(data, 0);
},
@ -213,7 +213,7 @@ sjcl.cipher.aes.prototype = {
* @param {Array} data The ciphertext.
* @return {Array} The plaintext.
*/
decrypt: function(data) {
decrypt: function (data) {
return this._crypt(data, 1);
},
@ -229,14 +229,17 @@ sjcl.cipher.aes.prototype = {
*
* @private
*/
_tables: [[[], [], [], [], []], [[], [], [], [], []]],
_tables: [
[[], [], [], [], []],
[[], [], [], [], []],
],
/**
* Expand the S-box tables.
*
* @private
*/
_precompute: function() {
_precompute: function () {
var encTable = this._tables[0],
decTable = this._tables[1],
sbox = encTable[4],
@ -290,7 +293,7 @@ sjcl.cipher.aes.prototype = {
* @return {Array} The four encrypted or decrypted words.
* @private
*/
_crypt: function(input, dir) {
_crypt: function (input, dir) {
if (input.length !== 4) {
throw new sjcl.exception.invalid("invalid aes block size");
}
@ -344,7 +347,7 @@ sjcl.cipher.aes.prototype = {
}
return out;
}
},
};
/** @fileOverview Arrays of bits, encoded as arrays of Numbers.
@ -387,7 +390,7 @@ sjcl.bitArray = {
* slice until the end of the array.
* @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);
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.
* @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
// seems to suppress a bug in the Chromium JIT.
var x,
@ -420,7 +423,7 @@ sjcl.bitArray = {
* @param {bitArray} a2 The second array.
* @return {bitArray} The concatenation of a1 and a2.
*/
concat: function(a1, a2) {
concat: function (a1, a2) {
if (a1.length === 0 || a2.length === 0) {
return a1.concat(a2);
}
@ -439,7 +442,7 @@ sjcl.bitArray = {
* @param {bitArray} a The array.
* @return {Number} The length of a, in bits.
*/
bitLength: function(a) {
bitLength: function (a) {
var l = a.length,
x;
if (l === 0) {
@ -455,7 +458,7 @@ sjcl.bitArray = {
* @param {Number} len The length to truncate to, in bits.
* @return {bitArray} A new array, truncated to len bits.
*/
clamp: function(a, len) {
clamp: function (a, len) {
if (a.length * 32 < len) {
return a;
}
@ -475,7 +478,7 @@ sjcl.bitArray = {
* @param {Number} [_end=0] Pass 1 if x has already been shifted to the high side.
* @return {Number} The partial word.
*/
partial: function(len, x, _end) {
partial: function (len, x, _end) {
if (len === 32) {
return x;
}
@ -487,7 +490,7 @@ sjcl.bitArray = {
* @param {Number} x 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;
},
@ -497,7 +500,7 @@ sjcl.bitArray = {
* @param {bitArray} b The second array.
* @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)) {
return false;
}
@ -516,7 +519,7 @@ sjcl.bitArray = {
* @param {bitArray} [out=[]] An array to prepend to the output.
* @private
*/
_shiftRight: function(a, shift, carry, out) {
_shiftRight: function (a, shift, carry, out) {
var i,
last2 = 0,
shift2;
@ -545,7 +548,7 @@ sjcl.bitArray = {
/** xor a block of 4 words together.
* @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]];
},
@ -554,7 +557,7 @@ sjcl.bitArray = {
* @param {sjcl.bitArray} a word array
* @return {sjcl.bitArray} byteswapped array
*/
byteswapM: function(a) {
byteswapM: function (a) {
var i,
v,
m = 0xff00;
@ -563,7 +566,7 @@ sjcl.bitArray = {
a[i] = (v >>> 24) | ((v >>> 8) & m) | ((v & m) << 8) | (v << 24);
}
return a;
}
},
};
/** @fileOverview Bit array codec implementations.
*
@ -578,7 +581,7 @@ sjcl.bitArray = {
*/
sjcl.codec.utf8String = {
/** Convert from a bitArray to a UTF-8 string. */
fromBits: function(arr) {
fromBits: function (arr) {
var out = "",
bl = sjcl.bitArray.bitLength(arr),
i,
@ -594,7 +597,7 @@ sjcl.codec.utf8String = {
},
/** Convert from a UTF-8 string to a bitArray. */
toBits: function(str) {
toBits: function (str) {
str = unescape(encodeURIComponent(str));
var out = [],
i,
@ -610,7 +613,7 @@ sjcl.codec.utf8String = {
out.push(sjcl.bitArray.partial(8 * (i & 3), tmp));
}
return out;
}
},
};
/** @fileOverview Bit array codec implementations.
*
@ -625,7 +628,7 @@ sjcl.codec.utf8String = {
*/
sjcl.codec.bytes = {
/** Convert from a bitArray to an array of bytes. */
fromBits: function(arr) {
fromBits: function (arr) {
var out = [],
bl = sjcl.bitArray.bitLength(arr),
i,
@ -640,7 +643,7 @@ sjcl.codec.bytes = {
return out;
},
/** Convert from an array of bytes to a bitArray. */
toBits: function(bytes) {
toBits: function (bytes) {
var out = [],
i,
tmp = 0;
@ -655,7 +658,7 @@ sjcl.codec.bytes = {
out.push(sjcl.bitArray.partial(8 * (i & 3), tmp));
}
return out;
}
},
};
/** @fileOverview CCM mode implementation.
*
@ -679,18 +682,18 @@ sjcl.mode.ccm = {
_progressListeners: [],
listenProgress: function(cb) {
listenProgress: function (cb) {
sjcl.mode.ccm._progressListeners.push(cb);
},
unListenProgress: function(cb) {
unListenProgress: function (cb) {
var index = sjcl.mode.ccm._progressListeners.indexOf(cb);
if (index > -1) {
sjcl.mode.ccm._progressListeners.splice(index, 1);
}
},
_callProgressListener: function(val) {
_callProgressListener: function (val) {
var p = sjcl.mode.ccm._progressListeners.slice(),
i;
@ -708,7 +711,7 @@ sjcl.mode.ccm = {
* @param {Number} [tlen=64] the desired tag length, in bits.
* @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,
out = plaintext.slice(0),
tag,
@ -747,7 +750,7 @@ sjcl.mode.ccm = {
* @param {Number} [tlen=64] tlen the desired tag length, in bits.
* @return {bitArray} The decrypted data.
*/
decrypt: function(prf, ciphertext, iv, adata, tlen) {
decrypt: function (prf, ciphertext, iv, adata, tlen) {
tlen = tlen || 64;
adata = adata || [];
var L,
@ -783,7 +786,7 @@ sjcl.mode.ccm = {
return out.data;
},
_macAdditionalData: function(prf, adata, iv, tlen, ol, L) {
_macAdditionalData: function (prf, adata, iv, tlen, ol, L) {
var mac,
tmp,
i,
@ -827,7 +830,7 @@ sjcl.mode.ccm = {
* @return {bitArray} The tag, but not yet encrypted.
* @private
*/
_computeTag: function(prf, plaintext, iv, adata, tlen, L) {
_computeTag: function (prf, plaintext, iv, adata, tlen, L) {
// compute B[0]
var mac,
i,
@ -868,7 +871,7 @@ sjcl.mode.ccm = {
* @return {Object} An object with data and tag, the en/decryption of data and tag values.
* @private
*/
_ctrMode: function(prf, data, iv, tag, tlen, L) {
_ctrMode: function (prf, data, iv, tag, tlen, L) {
var enc,
i,
w = sjcl.bitArray,
@ -906,7 +909,7 @@ sjcl.mode.ccm = {
data[i + 3] ^= enc[3];
}
return { tag: tag, data: w.clamp(data, bl) };
}
},
};
export { sjcl };

View File

@ -1,43 +1,43 @@
{
"name": "@padloc/electron",
"version": "4.0.0",
"description": "Electron Wrapper for Padloc app",
"main": "main.js",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"scripts": {
"build": "rm -rf app && webpack && node ./prepare-build.js && electron-builder --config build/build.json",
"start": "webpack && electron app/main.js"
},
"author": "MaKleSoft UG",
"license": "GPL-3.0",
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"electron-store": "8.0.0",
"electron-updater": "4.3.9"
},
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"css-loader": "5.2.6",
"electron": "14.1.1",
"electron-builder": "22.13.1",
"electron-notarize": "1.1.1",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.2",
"style-loader": "2.0.0",
"ts-loader": "9.2.5",
"webpack": "5.52.1",
"webpack-cli": "4.8.0",
"typescript": "4.4.3",
"raw-loader": "4.0.2",
"sharp": "0.29.1"
}
"name": "@padloc/electron",
"version": "4.0.0",
"description": "Electron Wrapper for Padloc app",
"main": "main.js",
"private": true,
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"scripts": {
"build": "rm -rf app && webpack && node ./prepare-build.js && electron-builder --config build/build.json",
"start": "webpack && electron app/main.js"
},
"author": "MaKleSoft UG",
"license": "GPL-3.0",
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"electron-store": "8.0.0",
"electron-updater": "4.3.9"
},
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"css-loader": "5.2.6",
"electron": "14.1.1",
"electron-builder": "22.13.1",
"electron-notarize": "1.1.1",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.2",
"style-loader": "2.0.0",
"ts-loader": "9.2.5",
"webpack": "5.52.1",
"webpack-cli": "4.8.0",
"typescript": "4.4.3",
"raw-loader": "4.0.2",
"sharp": "0.29.1"
}
}

View File

@ -3,7 +3,7 @@ const { execSync } = require("child_process");
const { tmpdir } = require("os");
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 pass = process.env.PL_WIN_SIGN_PASS;
const lib = path.resolve(__dirname, "crypto3PKCS.dylib");
@ -18,9 +18,7 @@ slotListIndex=0`
);
execSync(
`java -jar ${jsign} --keystore ${keystore} --storepass ${pass} --storetype PKCS11 -t http://time.certum.pl/ -a "${
opts.options.publisherName
}" "${opts.path}"`
`java -jar ${jsign} --keystore ${keystore} --storepass ${pass} --storetype PKCS11 -t http://time.certum.pl/ -a "${opts.options.publisherName}" "${opts.path}"`
);
unlinkSync(keystore);

View File

@ -1,3 +1,3 @@
{
"extends": "../app/tsconfig.json"
}
}

View File

@ -1,47 +1,47 @@
{
"name": "@padloc/extension",
"version": "4.0.0",
"description": "Padloc Progressive Web App",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"private": true,
"files": [
"src",
"assets",
"tsconfig.json"
],
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/pwa"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"@webcomponents/webcomponentsjs": "2.5.0",
"webextension-polyfill-ts": "0.25.0"
},
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"css-loader": "5.2.6",
"favicons-webpack-plugin": "5.0.2",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.1",
"http-server": "0.12.3",
"raw-loader": "4.0.2",
"sharp": "0.29.1",
"style-loader": "2.0.0",
"ts-loader": "9.2.2",
"ts-node": "10.0.0",
"typescript": "4.4.3",
"webpack": "5.38.1",
"webpack-cli": "4.7.0"
},
"scripts": {
"build": "webpack"
}
"name": "@padloc/extension",
"version": "4.0.0",
"description": "Padloc Progressive Web App",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"private": true,
"files": [
"src",
"assets",
"tsconfig.json"
],
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/pwa"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"@webcomponents/webcomponentsjs": "2.5.0",
"webextension-polyfill-ts": "0.25.0"
},
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"css-loader": "5.2.6",
"favicons-webpack-plugin": "5.0.2",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.1",
"http-server": "0.12.3",
"raw-loader": "4.0.2",
"sharp": "0.29.1",
"style-loader": "2.0.0",
"ts-loader": "9.2.2",
"ts-node": "10.0.0",
"typescript": "4.4.3",
"webpack": "5.38.1",
"webpack-cli": "4.7.0"
},
"scripts": {
"build": "webpack"
}
}

View File

@ -183,19 +183,19 @@ class ExtensionContent {
input.dispatchEvent(
new KeyboardEvent("keydown", {
bubbles: true,
key: ""
key: "",
})
);
input.dispatchEvent(
new KeyboardEvent("keyup", {
bubbles: true,
key: ""
key: "",
})
);
input.dispatchEvent(
new KeyboardEvent("keypress", {
bubbles: true,
key: ""
key: "",
})
);
input.dispatchEvent(new Event("input", { bubbles: true }));

View File

@ -4,22 +4,14 @@
"128": "icon.png"
},
"background": {
"scripts": [
"background.js"
],
"scripts": ["background.js"],
"persistent": true
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": "icon.png"
},
"permissions": [
"storage",
"unlimitedStorage",
"tabs",
"activeTab",
"contextMenus"
],
"permissions": ["storage", "unlimitedStorage", "tabs", "activeTab", "contextMenus"],
"commands": {
"_execute_browser_action": {
"suggested_key": {
@ -42,4 +34,4 @@
"description": "Open Previous Vault Item"
}
}
}
}

View File

@ -1,28 +1,28 @@
{
"name": "@padloc/locale",
"version": "4.0.0",
"description": "Package containing translations and wordlists for Padloc as well as various other localization tools",
"main": "src/index.js",
"files": [
"src",
"res"
],
"scripts": {
"extract": "ts-node src/extract.ts ../*/src/{**,.}/*.ts"
},
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPLv3",
"devDependencies": {
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/locale"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
"name": "@padloc/locale",
"version": "4.0.0",
"description": "Package containing translations and wordlists for Padloc as well as various other localization tools",
"main": "src/index.js",
"files": [
"src",
"res"
],
"scripts": {
"extract": "ts-node src/extract.ts ../*/src/{**,.}/*.ts"
},
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPLv3",
"devDependencies": {
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/locale"
},
"engines": {
"node": "16.13.1",
"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

View File

@ -235,5 +235,5 @@ export const countries = [
{ code: "EH", name: "Western Sahara" },
{ code: "YE", name: "Yemen" },
{ code: "ZM", name: "Zambia" },
{ code: "ZW", name: "Zimbabwe" }
{ code: "ZW", name: "Zimbabwe" },
];

View File

@ -54,7 +54,7 @@ function extract(files: ts.SourceFile[]) {
items.set(original, {
original,
translation: "",
sources: []
sources: [],
});
}
@ -63,7 +63,7 @@ function extract(files: ts.SourceFile[]) {
const source: ItemSource = {
file: file.fileName,
line,
character
character,
};
const comments =
@ -106,7 +106,7 @@ export function toYAML({ language, date, commit, items }: Translation) {
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()) {
const node = (doc.contents as any).items[i * 2];
@ -131,7 +131,7 @@ export function fromYAML(str: string, language: string): Translation {
language,
date: new Date(),
commit: "",
items
items,
};
}
@ -156,37 +156,35 @@ export function fromJSON(str: string, language: string) {
const items = JSON.parse(str).map(([original, translation]: [string, string]) => ({
original,
translation,
sources: []
sources: [],
}));
return {
language,
date: new Date(),
commit: "",
items
items,
};
}
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)
);
const commit = execSync("git rev-parse HEAD")
.toString()
.trim();
const commit = execSync("git rev-parse HEAD").toString().trim();
const items = extract(files);
return {
language,
commit,
date: new Date(),
items
items,
};
}
export function merge(curr: Translation, prev: Translation) {
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) {
item.translation = prev.items[prevItemIndex].translation;
prev.items.splice(prevItemIndex, 1);

View File

@ -2,9 +2,7 @@
"extends": "../../tsconfig.json",
"compilerOptions": {
"target": "es2017",
"lib": [
"esnext"
],
"lib": ["esnext"],
"module": "commonjs",
"declaration": false,
"baseUrl": "."

View File

@ -1,51 +1,51 @@
{
"name": "@padloc/pwa",
"version": "4.0.0",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"private": true,
"files": [
"src",
"assets",
"tsconfig.json"
],
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/pwa"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0"
},
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"css-loader": "5.2.6",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.1",
"http-server": "0.12.3",
"raw-loader": "4.0.2",
"sharp": "0.29.3",
"style-loader": "2.0.0",
"ts-loader": "9.2.2",
"ts-node": "10.0.0",
"typescript": "4.4.3",
"webpack": "5.52.0",
"webpack-cli": "4.8.0",
"webpack-dev-server": "4.2.1",
"webpack-pwa-manifest": "4.3.0",
"workbox-cli": "6.2.4",
"workbox-webpack-plugin": "6.4.2"
},
"description": "Padloc Progressive Web App",
"scripts": {
"build": "webpack",
"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}}?",
"build_and_start": "npm run build && npm start"
}
"name": "@padloc/pwa",
"version": "4.0.0",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPL-3.0",
"private": true,
"files": [
"src",
"assets",
"tsconfig.json"
],
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/pwa"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
},
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0"
},
"devDependencies": {
"clean-webpack-plugin": "3.0.0",
"css-loader": "5.2.6",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.1",
"http-server": "0.12.3",
"raw-loader": "4.0.2",
"sharp": "0.29.3",
"style-loader": "2.0.0",
"ts-loader": "9.2.2",
"ts-node": "10.0.0",
"typescript": "4.4.3",
"webpack": "5.52.0",
"webpack-cli": "4.8.0",
"webpack-dev-server": "4.2.1",
"webpack-pwa-manifest": "4.3.0",
"workbox-cli": "6.2.4",
"workbox-webpack-plugin": "6.4.2"
},
"description": "Padloc Progressive Web App",
"scripts": {
"build": "webpack",
"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}}?",
"build_and_start": "npm run build && npm start"
}
}

View File

@ -1,63 +1,63 @@
{
"name": "@padloc/server",
"version": "3.1.3",
"description": "Padloc server component",
"private": true,
"files": [
"src",
"tsconfig.json"
],
"main": "index.js",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPLv3",
"devDependencies": {
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "8.4.0",
"ts-node-dev": "1.1.6"
},
"dependencies": {
"@padloc/core": "4.0.0",
"@padloc/locale": "4.0.0",
"@aws-sdk/client-s3": "3.25.0",
"@aws-sdk/types": "3.25.0",
"@simplewebauthn/server": "4.0.0",
"@types/fs-extra": "9.0.11",
"@types/mixpanel": "2.14.3",
"@types/node": "15.6.1",
"@types/nodemailer": "6.4.2",
"@types/pg": "8.6.1",
"@types/stripe": "8.0.416",
"ansi-colors": "4.1.1",
"date-fns": "2.22.1",
"fs-extra": "10.0.0",
"geolite2-redist": "2.0.4",
"level": "7.0.0",
"maxmind": "4.3.2",
"mixpanel": "0.13.0",
"mongodb": "4.1.0",
"nodemailer": "6.6.1",
"pg": "8.7.1",
"stripe": "8.194.0",
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
"scripts": {
"start": "ts-node src/init.ts",
"start-dry": "ts-node src/init.ts --dryrun",
"repl": "ts-node src/init-repl-client.ts",
"dev": "ts-node-dev 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"
},
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/server"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
"name": "@padloc/server",
"version": "3.1.3",
"description": "Padloc server component",
"private": true,
"files": [
"src",
"tsconfig.json"
],
"main": "index.js",
"author": "Martin Kleinschrodt <martin@maklesoft.com>",
"license": "GPLv3",
"devDependencies": {
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"chai": "4.3.4",
"mocha": "8.4.0",
"ts-node-dev": "1.1.6"
},
"dependencies": {
"@padloc/core": "4.0.0",
"@padloc/locale": "4.0.0",
"@aws-sdk/client-s3": "3.25.0",
"@aws-sdk/types": "3.25.0",
"@simplewebauthn/server": "4.0.0",
"@types/fs-extra": "9.0.11",
"@types/mixpanel": "2.14.3",
"@types/node": "15.6.1",
"@types/nodemailer": "6.4.2",
"@types/pg": "8.6.1",
"@types/stripe": "8.0.416",
"ansi-colors": "4.1.1",
"date-fns": "2.22.1",
"fs-extra": "10.0.0",
"geolite2-redist": "2.0.4",
"level": "7.0.0",
"maxmind": "4.3.2",
"mixpanel": "0.13.0",
"mongodb": "4.1.0",
"nodemailer": "6.6.1",
"pg": "8.7.1",
"stripe": "8.194.0",
"ts-node": "10.0.0",
"typescript": "4.4.3"
},
"scripts": {
"start": "ts-node src/init.ts",
"start-dry": "ts-node src/init.ts --dryrun",
"repl": "ts-node src/init-repl-client.ts",
"dev": "ts-node-dev 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"
},
"repository": {
"type": "git",
"url": "https://github.com/padloc/padloc.git",
"directory": "packages/server"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
}

View File

@ -12,7 +12,7 @@ import {
createCipheriv,
createDecipheriv,
publicEncrypt,
privateDecrypt
privateDecrypt,
} from "crypto";
import {
CryptoProvider,
@ -29,7 +29,7 @@ import {
RSAEncryptionParams,
HashParams,
RSASigningParams,
PBKDF2Params
PBKDF2Params,
} from "@padloc/core/src/crypto";
import { Err, ErrorCode } from "@padloc/core/src/error";
import { equalCT } from "@padloc/core/src/encoding";
@ -80,12 +80,12 @@ export class NodeCryptoProvider implements CryptoProvider {
),
publicKeyEncoding: {
type: "spki",
format: "der"
format: "der",
},
privateKeyEncoding: {
type: "pkcs8",
format: "der"
}
format: "der",
},
} as any,
(err, publicKey: Buffer, privateKey: Buffer) => {
if (err) {
@ -93,7 +93,7 @@ export class NodeCryptoProvider implements CryptoProvider {
} else {
resolve({
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 authTagLength = params.tagSize / 8;
const cipher = createCipheriv(`${alg}-${params.keySize}-${mode}` as "aes-256-gcm", key, params.iv, {
authTagLength
authTagLength,
} as any);
cipher.setAAD(params.additionalData as Buffer);
try {
@ -223,7 +223,7 @@ export class NodeCryptoProvider implements CryptoProvider {
const tag = data.slice(tagPos);
const cipher = createDecipheriv(`${alg}-${params.keySize}-${mode}` as "aes-256-gcm", key, params.iv, {
authTagLength
authTagLength,
} as any);
cipher.setAAD(params.additionalData as Buffer);
cipher.setAuthTag(tag);
@ -242,7 +242,7 @@ export class NodeCryptoProvider implements CryptoProvider {
key: Buffer.from(publicKey),
format: "der",
type: "spki",
oaepHash: hashToNode(params.hash)
oaepHash: hashToNode(params.hash),
} as any,
key
);
@ -259,7 +259,7 @@ export class NodeCryptoProvider implements CryptoProvider {
key: Buffer.from(privateKey),
format: "der",
type: "pkcs8",
oaepHash: hashToNode(params.hash)
oaepHash: hashToNode(params.hash),
} as any,
key
);
@ -293,7 +293,7 @@ export class NodeCryptoProvider implements CryptoProvider {
format: "der",
dsaEncoding: "der",
saltLength: params.saltLength,
padding: constants.RSA_PKCS1_PSS_PADDING
padding: constants.RSA_PKCS1_PSS_PADDING,
});
return new Uint8Array(sig);
@ -309,7 +309,7 @@ export class NodeCryptoProvider implements CryptoProvider {
format: "der",
dsaEncoding: "der",
saltLength: params.saltLength,
padding: constants.RSA_PKCS1_PSS_PADDING
padding: constants.RSA_PKCS1_PSS_PADDING,
},
signature
);

View File

@ -21,10 +21,10 @@ export class NodeLegacyServer implements LegacyServer {
method: "GET",
headers: {
Authorization: `SkeletonKey ${email}:${this.config.key}`,
Accept: "application/vnd.padlock;version=1"
}
Accept: "application/vnd.padlock;version=1",
},
},
res => {
(res) => {
if (res.statusCode !== 200) {
resolve(null);
return;
@ -33,7 +33,7 @@ export class NodeLegacyServer implements LegacyServer {
let data = "";
res.setEncoding("utf8");
res.on("data", chunk => (data += chunk));
res.on("data", (chunk) => (data += chunk));
res.on("end", () => {
if (!data) {
resolve(null);
@ -65,10 +65,10 @@ export class NodeLegacyServer implements LegacyServer {
method: "POST",
headers: {
Authorization: `SkeletonKey ${email}:${this.config.key}`,
Accept: "application/vnd.padlock;version=1"
}
Accept: "application/vnd.padlock;version=1",
},
},
res => {
(res) => {
if (res.statusCode !== 200) {
reject("Received status code " + res.statusCode);
return;

View File

@ -34,7 +34,8 @@ export class DefaultAccountProvisioning
Pick<
AccountProvisioning,
"status" | "statusLabel" | "statusMessage" | "actionUrl" | "actionLabel" | "quota" | "disableFeatures"
> {
>
{
@ConfigParam()
status: ProvisioningStatus = ProvisioningStatus.Active;
@ -400,16 +401,8 @@ export class SimpleProvisioner implements Provisioner {
}
}
const {
accountId,
status,
statusLabel,
statusMessage,
actionUrl,
actionLabel,
scheduledUpdates,
metaData,
} = entry.toRaw();
const { accountId, status, statusLabel, statusMessage, actionUrl, actionLabel, scheduledUpdates, metaData } =
entry.toRaw();
httpRes.statusCode = 200;
httpRes.end(

View File

@ -1,36 +1,36 @@
{
"name": "@padloc/tauri",
"version": "4.0.0",
"description": "Tauri Wrapper for packaging native apps",
"main": "index.js",
"scripts": {
"tauri": "tauri",
"build": "tauri build",
"dev": "tauri dev"
},
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "3.0.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",
"typescript": "4.3.2",
"webpack": "5.38.1",
"webpack-cli": "4.7.0",
"webpack-dev-server": "3.11.2",
"@tauri-apps/cli": "1.0.0-beta.10"
},
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"@tauri-apps/api": "1.0.0-beta.8"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
"name": "@padloc/tauri",
"version": "4.0.0",
"description": "Tauri Wrapper for packaging native apps",
"main": "index.js",
"scripts": {
"tauri": "tauri",
"build": "tauri build",
"dev": "tauri dev"
},
"author": "",
"license": "ISC",
"devDependencies": {
"clean-webpack-plugin": "3.0.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",
"typescript": "4.3.2",
"webpack": "5.38.1",
"webpack-cli": "4.7.0",
"webpack-dev-server": "3.11.2",
"@tauri-apps/cli": "1.0.0-beta.10"
},
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"@tauri-apps/api": "1.0.0-beta.8"
},
"engines": {
"node": "16.13.1",
"npm": "8.2.0"
}
}

View File

@ -1,65 +1,61 @@
{
"package": {
"productName": "Padloc",
"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": ""
}
"package": {
"productName": "Padloc",
"version": "0.1.0"
},
"updater": {
"active": false
"build": {
"distDir": "../dist",
"devPath": "http://localhost:8080",
"beforeDevCommand": "webpack serve",
"beforeBuildCommand": "webpack"
},
"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'"
"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": {
"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'"
}
}
}
}
}

View File

@ -58,7 +58,6 @@
rotate linear 1.2s infinite;
}
</style>
</head>
<body>
<svg viewBox="0 0 100 100" class="spinner">

View File

@ -14,7 +14,6 @@ function createApp() {
await import("@padloc/app/src/elements/app");
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", createApp);
} else {