Compare commits

...

24 Commits
v4.0.0 ... main

Author SHA1 Message Date
Coluzzi Andrea 16b50df550
Italian Translations v4 (#524)
* IT translations: fix old PR comments

* IT translations: WIP v4 tokens

* IT translations: WIP v4 tokens

* IT translations: added v4 tokens
2022-08-03 07:18:36 +01:00
Martin Kleinschrodt 16b1a1a1e0
Merge pull request #522 from padloc/chore/update-translation-files
Update translation files with latest strings
2022-08-02 10:51:18 +02:00
Martin Kleinschrodt f639d24341 Exclude translations and word lists from prettier checks 2022-08-02 10:19:13 +02:00
Martin Kleinschrodt 00a282c632 Update translation files with latest strings 2022-08-02 10:14:52 +02:00
Martin Kleinschrodt 08b8ce4511
Merge pull request #520 from coluzziandrea/feature/italian-translations
Italian translations
2022-08-02 10:07:13 +02:00
Martin Kleinschrodt 12b027b37c
Merge pull request #521 from padloc/chore/update-simplewebauthn
Update SimpeWebAuthn dependency to latest
2022-08-02 08:22:16 +02:00
Martin Kleinschrodt e0834e72cb Update SimpeWebAuthn dependency to latest 2022-08-02 08:11:40 +02:00
Andrea Coluzzi 22fbde7502 Added italian translations 2022-08-02 00:43:36 +02:00
Martin Kleinschrodt f2b7846072
Merge pull request #515 from padloc/feature/better-error-reports-2
Provide better information in error reports. Also added postgres logger
2022-07-29 18:23:20 +02:00
Martin Kleinschrodt e2d8dc21ce Actually, using time stamps as an id prefix is probably a better idea 2022-07-29 18:06:33 +02:00
Martin Kleinschrodt 3736fac4c5 Forgot to generate id for log events 2022-07-29 17:58:49 +02:00
Martin Kleinschrodt cc092fae03 Implement postgres logger 2022-07-29 17:30:53 +02:00
Martin Kleinschrodt a7c58f693d Fix type error 2022-07-29 17:15:20 +02:00
Martin Kleinschrodt 9640a66f09 Apparently prettier doesn't like <pre></pre> inside <p></p> 2022-07-29 16:49:40 +02:00
Martin Kleinschrodt 01dd5eaf2a Provide better information in error reports by printing the stack trace and message of the original error instead of the Err wrapper 2022-07-29 16:36:32 +02:00
Martin Kleinschrodt 7afd5582eb
Merge pull request #511 from padloc/feature/disable-mfa
Add flag to completely disable multi-factor authentication for a given account
2022-07-28 10:33:19 +02:00
Martin Kleinschrodt 7e7d6c770c Add flag to completely disable multi-factor authentication for a given account 2022-07-28 09:45:15 +02:00
Bruno Bernardino 908b855948
Merge pull request #508 from padloc/fix/publish-snap-on-release
Fix publishing snap in GitHub release
2022-07-27 10:38:38 +01:00
Bruno Bernardino 23a18a2736
Make the publish specific to snap, as it's the only one that needs to be overridden, really. 2022-07-27 10:20:23 +01:00
Bruno Bernardino e26d31027b
Fix publishing snap in GitHub release
This should allow the built snap to be uploaded to the GH release. It was built in https://github.com/padloc/padloc/runs/7500288391?check_suite_focus=true but never published.

The public snap listing is now available in https://snapcraft.io/padloc with the amd64 version.
2022-07-27 10:10:23 +01:00
Bruno Bernardino 8256497216
Merge pull request #506 from padloc/feature/better-error-reports
More helpful error reports via email
2022-07-26 12:09:15 +01:00
Martin Kleinschrodt ed593318aa Send more helpful error reports 2022-07-26 12:43:14 +02:00
Martin Kleinschrodt b1f094e930 Disable billing page for platforms excluded from billing 2022-07-26 12:43:00 +02:00
Martin Kleinschrodt 2ea970b261
Allow selectively disabling all billing functionality on certain platforms (#505)
* Allow selectively disabling all billing functionality on certain platforms

* Remove check for org metadata param in customer

* Fix linter complaint
2022-07-26 10:41:30 +01:00
39 changed files with 25428 additions and 13558 deletions

View File

@ -13,3 +13,4 @@ packages/pwa/dist/**/*
package-lock.json
cypress/fixtures/**/*
.flatpak-builder/**/*
packages/locale/res/**/*

View File

@ -1,7 +0,0 @@
<p>The following error occurred at {{ time }}:</p>
<p>
Code: {{ code }} <br />
Message: {{ message }} <br />
Event ID: {{ eventId }}`
</p>

View File

@ -1,5 +0,0 @@
The following error occurred at {{ time }}:
Code: {{ code }}
Message: {{ message }}
Event ID: {{ eventId }}`

3
assets/email/plain.html Normal file
View File

@ -0,0 +1,3 @@
<pre>
{{ message }}
</pre>

1
assets/email/plain.txt Normal file
View File

@ -0,0 +1 @@
{{ message }}

View File

@ -184,6 +184,22 @@
# PL_LOGGING_MONGODB_MAX_SIZE=""
# PL_LOGGING_MONGODB_MAX_DOCUMENTS=""
# -----------------------------------------------------------------------------
# POSTGRES
#
# Use postgresql as log storage: https://www.npmjs.com/package/pg
# -----------------------------------------------------------------------------
# PL_LOGGING_BACKEND=postgres
# PL_LOGGING_POSTGRES_HOST=localhost
# PL_LOGGING_POSTGRES_PORT=5432
# PL_LOGGING_POSTGRES_DATABASE=padloc
# PL_LOGGING_POSTGRES_USER=padloc
# PL_LOGGING_POSTGRES_PASSWORD=""
# PL_LOGGING_POSTGRES_TLS=false
# PL_LOGGING_POSTGRES_TLS_CAFILE=""
# PL_LOGGING_POSTGRES_TLS_REJECT_UNAUTHORIZED=true
# -----------------------------------------------------------------------------
# MIXPANEL
#

File diff suppressed because it is too large Load Diff

View File

@ -22,8 +22,8 @@
"dependencies": {
"@padloc/core": "4.0.0",
"@padloc/locale": "4.0.0",
"@simplewebauthn/browser": "4.0.0",
"@simplewebauthn/typescript-types": "4.0.0",
"@simplewebauthn/browser": "5.4.0",
"@simplewebauthn/typescript-types": "5.4.0",
"@tiptap/core": "2.0.0-beta.182",
"@tiptap/starter-kit": "2.0.0-beta.191",
"@types/autosize": "4.0.1",

View File

@ -3,6 +3,7 @@ import { html, css, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import { Dialog } from "./dialog";
import "./button";
import "./icon";
const defaultButtonLabel = $l("OK");
@ -20,6 +21,7 @@ export interface AlertOptions {
maxWidth?: string;
width?: string;
hideOnDocumentVisibilityChange?: boolean;
zIndex?: number;
}
@customElement("pl-alert-dialog")
@ -119,6 +121,7 @@ export class AlertDialog extends Dialog<AlertOptions, number> {
maxWidth,
width,
hideOnDocumentVisibilityChange = false,
zIndex = 10,
}: AlertOptions = {}): Promise<number> {
this.message = message;
this.dialogTitle = title;
@ -137,6 +140,7 @@ export class AlertDialog extends Dialog<AlertOptions, number> {
await this.updateComplete;
this.style.zIndex = zIndex.toString();
this._inner.style.setProperty("--pl-dialog-max-width", maxWidth || "inherit");
this._inner.style.setProperty("--pl-dialog-width", width || "inherit");

View File

@ -95,6 +95,7 @@ export class WebPlatform extends StubPlatform implements Platform {
browser.name && browser.name !== "Electron"
? $l("{0} on {1}", browser.name, platform)
: $l("{0} Device", platform),
runtime: "web",
});
}

View File

@ -39,6 +39,7 @@ async function alertMessage(message: string | RichContent, action?: { label: str
type: !action ? "choice" : "info",
title,
hideOnDocumentVisibilityChange: true,
zIndex: 20,
}
);
if (action && choice === 0) {

View File

@ -8,7 +8,6 @@
"name": "@padloc/cordova",
"version": "4.0.0",
"dependencies": {
"cordova-android": "10.1.0",
"cordova-clipboard": "1.3.0",
"cordova-ios": "6.2.0",
"cordova-plugin-add-swift-support": "2.0.2",
@ -32,6 +31,7 @@
"@types/cordova-plugin-qrscanner": "1.0.31",
"clean-webpack-plugin": "3.0.0",
"cordova": "11.0.0",
"cordova-android": "^10.1.2",
"css-loader": "5.2.6",
"dotenv": "10.0.0",
"file-loader": "6.2.0",
@ -756,6 +756,7 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.7.0.tgz",
"integrity": "sha512-TCy4b8Dk8YS6A23ZPfhSKqK66JHFq0D8avGYiwvYpjno6HrrcI0DRgHx9+jtkvWYmrsE2vQWgbHJhvGGhhOb0g==",
"dev": true,
"dependencies": {
"semver": "^5.7.1"
}
@ -764,6 +765,7 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true,
"bin": {
"semver": "bin/semver"
}
@ -1852,9 +1854,10 @@
}
},
"node_modules/cordova-android": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-10.1.0.tgz",
"integrity": "sha512-nkVh8VMDWoDmvWaQav/sF3Q7N9ZpRRNBJduDhjCOMwYUF/6q2526i/Jb/wJLdXmetBNh+THkGolcTBi9i+1UzA==",
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-10.1.2.tgz",
"integrity": "sha512-F28+NvgKO4ZhKFkqctCOh62mhVoNyUuRQh/F/nqp+Sti4ODv2rUa6UeW18khhdYTjlDeihHQsPqxvB7mI6fVYA==",
"dev": true,
"dependencies": {
"android-versions": "^1.7.0",
"cordova-common": "^4.0.2",
@ -1873,9 +1876,10 @@
}
},
"node_modules/cordova-android/node_modules/fs-extra": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@ -2963,6 +2967,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
@ -3360,6 +3365,7 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"dev": true,
"engines": {
"node": ">=10"
},
@ -3757,6 +3763,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true,
"engines": {
"node": ">=10.17.0"
}
@ -4312,6 +4319,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -4341,6 +4349,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
"engines": {
"node": ">=8"
},
@ -4752,7 +4761,8 @@
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"node_modules/merge2": {
"version": "1.4.1",
@ -4820,6 +4830,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -5225,6 +5236,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
"dependencies": {
"path-key": "^3.0.0"
},
@ -5321,6 +5333,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"dependencies": {
"mimic-fn": "^2.1.0"
},
@ -5908,7 +5921,8 @@
"node_modules/properties-parser": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.3.1.tgz",
"integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=",
"integrity": "sha512-AkSQxQAviJ89x4FIxOyHGfO3uund0gvYo7lfD0E+Gp7gFQKrTNgtoYQklu8EhrfHVZUzTwKGZx2r/KDSfnljcA==",
"dev": true,
"dependencies": {
"string.prototype.codepointat": "^0.2.0"
},
@ -6713,7 +6727,8 @@
"node_modules/signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"dev": true
},
"node_modules/simctl": {
"version": "2.0.3",
@ -7041,7 +7056,8 @@
"node_modules/string.prototype.codepointat": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
"dev": true
},
"node_modules/stringify-package": {
"version": "1.0.1",
@ -7073,6 +7089,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
"engines": {
"node": ">=6"
}
@ -7594,6 +7611,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
"dev": true,
"engines": {
"node": ">=8"
}
@ -8849,6 +8867,7 @@
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/android-versions/-/android-versions-1.7.0.tgz",
"integrity": "sha512-TCy4b8Dk8YS6A23ZPfhSKqK66JHFq0D8avGYiwvYpjno6HrrcI0DRgHx9+jtkvWYmrsE2vQWgbHJhvGGhhOb0g==",
"dev": true,
"requires": {
"semver": "^5.7.1"
},
@ -8856,7 +8875,8 @@
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
}
}
},
@ -9697,9 +9717,10 @@
}
},
"cordova-android": {
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-10.1.0.tgz",
"integrity": "sha512-nkVh8VMDWoDmvWaQav/sF3Q7N9ZpRRNBJduDhjCOMwYUF/6q2526i/Jb/wJLdXmetBNh+THkGolcTBi9i+1UzA==",
"version": "10.1.2",
"resolved": "https://registry.npmjs.org/cordova-android/-/cordova-android-10.1.2.tgz",
"integrity": "sha512-F28+NvgKO4ZhKFkqctCOh62mhVoNyUuRQh/F/nqp+Sti4ODv2rUa6UeW18khhdYTjlDeihHQsPqxvB7mI6fVYA==",
"dev": true,
"requires": {
"android-versions": "^1.7.0",
"cordova-common": "^4.0.2",
@ -9715,9 +9736,10 @@
},
"dependencies": {
"fs-extra": {
"version": "10.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz",
"integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
"version": "10.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@ -10525,6 +10547,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dev": true,
"requires": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
@ -10837,7 +10860,8 @@
"get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"dev": true
},
"getpass": {
"version": "0.1.7",
@ -11132,7 +11156,8 @@
"human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true
},
"humanize-ms": {
"version": "1.2.1",
@ -11541,7 +11566,8 @@
"is-path-inside": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ=="
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
"dev": true
},
"is-plain-object": {
"version": "2.0.4",
@ -11563,7 +11589,8 @@
"is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true
},
"is-typedarray": {
"version": "1.0.0",
@ -11892,7 +11919,8 @@
"merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"dev": true
},
"merge2": {
"version": "1.4.1",
@ -11938,7 +11966,8 @@
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"mimic-response": {
"version": "1.0.1",
@ -12254,6 +12283,7 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
"requires": {
"path-key": "^3.0.0"
}
@ -12329,6 +12359,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dev": true,
"requires": {
"mimic-fn": "^2.1.0"
}
@ -12760,7 +12791,8 @@
"properties-parser": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.3.1.tgz",
"integrity": "sha1-ExbpU5/7/ZOEXjabIRAiq9R4dxo=",
"integrity": "sha512-AkSQxQAviJ89x4FIxOyHGfO3uund0gvYo7lfD0E+Gp7gFQKrTNgtoYQklu8EhrfHVZUzTwKGZx2r/KDSfnljcA==",
"dev": true,
"requires": {
"string.prototype.codepointat": "^0.2.0"
}
@ -13374,7 +13406,8 @@
"signal-exit": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
"integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
"dev": true
},
"simctl": {
"version": "2.0.3",
@ -13617,7 +13650,8 @@
"string.prototype.codepointat": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz",
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg=="
"integrity": "sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==",
"dev": true
},
"stringify-package": {
"version": "1.0.1",
@ -13642,7 +13676,8 @@
"strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true
},
"strip-json-comments": {
"version": "2.0.1",
@ -14006,7 +14041,8 @@
"untildify": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw=="
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
"dev": true
},
"update-notifier": {
"version": "5.1.0",

View File

@ -40,7 +40,6 @@
"dependencies": {
"@padloc/app": "4.0.0",
"@padloc/core": "4.0.0",
"cordova-android": "10.1.0",
"cordova-clipboard": "1.3.0",
"cordova-ios": "6.2.0",
"cordova-plugin-add-swift-support": "2.0.2",
@ -64,6 +63,7 @@
"@types/cordova-plugin-qrscanner": "1.0.31",
"clean-webpack-plugin": "3.0.0",
"cordova": "11.0.0",
"cordova-android": "10.1.2",
"css-loader": "5.2.6",
"dotenv": "10.0.0",
"file-loader": "6.2.0",

View File

@ -49,6 +49,7 @@ export class CordovaPlatform extends WebPlatform implements Platform {
platform,
osVersion,
description: appleDeviceNames[model] || model,
runtime: "cordova",
});
}

View File

@ -231,6 +231,9 @@ export class Auth extends Serializable implements Storable {
@AsSerializable(PBES2Container)
legacyData?: PBES2Container;
/** Completely disables mfa for a given account. Only use for testing! */
disableMFA = false;
constructor(public email: string = "") {
super();
}

View File

@ -99,8 +99,10 @@ export class Err extends Error {
}
toString() {
return `Time: ${this.time.toISOString()}\nError Code: ${this.code}:\nError Message: ${
this.message
}\nStack Trace:\n${this.originalError ? this.originalError.stack : this.stack}`;
return `Time: ${this.time.toISOString()}
Error Code: ${this.code}
Error Message: ${this.message}
Stack Trace:\n${this.originalError ? this.originalError.stack : this.stack}
`;
}
}

View File

@ -60,8 +60,8 @@ export class JoinOrgInviteCompletedMessage extends Message<{ orgName: string; op
}
}
export class ErrorMessage extends Message<{ code: string; message: string; time: string; eventId: string }> {
template = "error";
export class PlainMessage extends Message<{ message: string }> {
template = "plain";
get title() {
return "Padloc Error Notification";

View File

@ -47,6 +47,8 @@ export class DeviceInfo extends Serializable {
description: string = $l("Unknown Device");
runtime: string = "";
constructor(props?: Partial<DeviceInfo>) {
super();
props && Object.assign(this, props);

View File

@ -3,6 +3,7 @@ import { Config, ConfigParam } from "./config";
import { AsSerializable, Serializable } from "./encoding";
import { Err, ErrorCode } from "./error";
import { Org, OrgID, OrgInfo } from "./org";
import { Session } from "./session";
import { Storable, Storage } from "./storage";
import { getIdFromEmail } from "./util";
@ -215,7 +216,7 @@ export class Provisioning extends Serializable {
}
export interface Provisioner {
getProvisioning(params: { email: string; accountId?: AccountID }): Promise<Provisioning>;
getProvisioning(params: { email: string; accountId?: AccountID }, session?: Session): Promise<Provisioning>;
accountDeleted(params: { email: string; accountId?: AccountID }): Promise<void>;
orgDeleted(params: OrgInfo): Promise<void>;
orgOwnerChanged(

View File

@ -44,7 +44,7 @@ import { Org, OrgID, OrgMember, OrgMemberStatus, OrgRole, ScimSettings } from ".
import { Invite } from "./invite";
import {
ConfirmMembershipInviteMessage,
ErrorMessage,
PlainMessage,
JoinOrgInviteAcceptedMessage,
JoinOrgInviteCompletedMessage,
JoinOrgInviteMessage,
@ -199,13 +199,11 @@ export class Controller extends API {
// Get account associated with this session
const account = await this.storage.get(Account, session.account);
const auth = await this._getAuth(account.email);
const provisioning = await this.provisioner.getProvisioning(auth);
// Store account and session on context
ctx.session = session;
ctx.account = account;
ctx.auth = auth;
ctx.provisioning = provisioning;
ctx.location = req.location;
// Update session info
@ -221,6 +219,8 @@ export class Controller extends API {
auth.sessions.push(session.info);
}
ctx.provisioning = await this.provisioner.getProvisioning(auth, session);
await Promise.all([this.storage.save(session), this.storage.save(account), this.storage.save(auth)]);
}
@ -355,7 +355,8 @@ export class Controller extends API {
auth.authRequests.push(request);
const deviceTrusted =
this.context.device && auth.trustedDevices.some(({ id }) => id === this.context.device!.id);
auth.disableMFA ||
(this.context.device && auth.trustedDevices.some(({ id }) => id === this.context.device!.id));
const response = new StartAuthRequestResponse({
id: request.id,
@ -2077,8 +2078,6 @@ export class Server {
}
private async _handleError(error: Error, req: Request, res: Response, context: Context) {
console.error(error);
const e =
error instanceof Err
? error
@ -2095,6 +2094,8 @@ export class Server {
};
if (e.report) {
console.error(error);
const evt = this.log("error", context, {
error: e.toRaw(),
request: {
@ -2107,11 +2108,12 @@ export class Server {
try {
await this.messenger.send(
this.config.reportErrors,
new ErrorMessage({
time: e.time.toISOString(),
code: e.code,
message: e.message,
eventId: evt.id,
new PlainMessage({
message: `The following error occured at ${e.time.toISOString()}:\n\nEndpoint: ${
req.method
}\nDevice Info:\n${
req.device && JSON.stringify(req.device?.toRaw(), null, 4)
}\n${e.toString()}${evt?.id ? `Event ID: ${evt.id}` : ""}`,
})
);
} catch (e) {}

View File

@ -21,6 +21,18 @@ export async function uuid(): Promise<string> {
].join("-");
}
/**
* Generates a random UUID v4
* NOT CRYPTOGRAPHICALLY SAFE!
*/
export function unsafeUUID(): string {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0,
v = c == "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
/** Caracters, by category */
export const chars = {
numbers: "0123456789",

View File

@ -62,6 +62,7 @@ async function main() {
snap: {
confinement: "strict",
plugs: ["desktop", "home", "browser-support", "network", "opengl", "x11", "wayland", "unity7"],
publish: ["github"],
},
afterSign: "scripts/notarize.js",
};

View File

@ -1,4 +1,10 @@
import { Platform } from "@padloc/core/src/platform";
import { WebPlatform } from "@padloc/app/src/lib/platform";
export class ElectronPlatform extends WebPlatform implements Platform {}
export class ElectronPlatform extends WebPlatform implements Platform {
async getDeviceInfo() {
const device = await super.getDeviceInfo();
device.runtime = "electron";
return device;
}
}

View File

@ -12,6 +12,7 @@ export class ExtensionPlatform extends WebPlatform {
async getDeviceInfo() {
const info = await super.getDeviceInfo();
info.description = `${info.browser} extension on ${info.platform}`;
info.runtime = "extension";
return info;
}
}

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

@ -24,7 +24,7 @@
"@aws-sdk/types": "3.25.0",
"@padloc/core": "4.0.0",
"@padloc/locale": "4.0.0",
"@simplewebauthn/server": "4.0.0",
"@simplewebauthn/server": "5.4.0",
"@types/fs-extra": "9.0.11",
"@types/mixpanel": "2.14.3",
"@types/node": "15.6.1",

View File

@ -82,7 +82,7 @@ export class LoggingConfig extends Config {
}
@ConfigParam()
backend: "void" | "mongodb" | "mixpanel" = "void";
backend: "void" | "mongodb" | "postgres" | "mixpanel" = "void";
@ConfigParam()
secondaryBackend?: "mongodb" | "mixpanel";
@ -90,6 +90,9 @@ export class LoggingConfig extends Config {
@ConfigParam(MongoDBStorageConfig)
mongodb?: MongoDBStorageConfig;
@ConfigParam(PostgresConfig)
postgres?: PostgresConfig;
@ConfigParam(MixpanelConfig)
mixpanel?: MixpanelConfig;
}

View File

@ -11,7 +11,7 @@ import { AuthServer, AuthType } from "@padloc/core/src/auth";
import { WebAuthnConfig, WebAuthnServer } from "./auth/webauthn";
import { SMTPSender } from "./email/smtp";
import { MongoDBStorage } from "./storage/mongodb";
import { ConsoleMessenger, ErrorMessage } from "@padloc/core/src/messenger";
import { ConsoleMessenger, PlainMessage } from "@padloc/core/src/messenger";
import { FSAttachmentStorage, FSAttachmentStorageConfig } from "./attachments/fs";
import {
AttachmentStorageConfig,
@ -33,11 +33,11 @@ import { resolve, join } from "path";
import { MongoDBLogger } from "./logging/mongodb";
import { MixpanelLogger } from "./logging/mixpanel";
import { PostgresStorage } from "./storage/postgres";
import { ErrorCode } from "@padloc/core/src/error";
import { stripPropertiesRecursive } from "@padloc/core/src/util";
import { DirectoryProvisioner } from "./provisioning/directory";
import { ScimServer, ScimServerConfig } from "./scim";
import { DirectoryProvider, DirectorySync } from "@padloc/core/src/directory";
import { PostgresLogger } from "./logging/postgres";
const rootDir = resolve(__dirname, "../../..");
const assetsDir = resolve(rootDir, process.env.PL_ASSETS_DIR || "assets");
@ -75,7 +75,7 @@ async function initDataStorage(config: DataStorageConfig) {
}
}
async function initLogger({ backend, secondaryBackend, mongodb, mixpanel }: LoggingConfig) {
async function initLogger({ backend, secondaryBackend, mongodb, postgres, mixpanel }: LoggingConfig) {
let primaryLogger: Logger;
switch (backend) {
@ -83,9 +83,15 @@ async function initLogger({ backend, secondaryBackend, mongodb, mixpanel }: Logg
if (!mongodb) {
throw "PL_LOGGING_BACKEND was set to 'mongodb', but no related configuration was found!";
}
const storage = new MongoDBStorage(mongodb);
await storage.init();
primaryLogger = new MongoDBLogger(storage);
const mongoStorage = new MongoDBStorage(mongodb);
await mongoStorage.init();
primaryLogger = new MongoDBLogger(mongoStorage);
break;
case "postgres":
if (!postgres) {
throw "PL_LOGGING_BACKEND was set to 'postgres', but no related configuration was found!";
}
primaryLogger = new PostgresLogger(new PostgresStorage(postgres));
break;
case "void":
primaryLogger = new VoidLogger();
@ -302,11 +308,10 @@ async function init(config: PadlocConfig) {
try {
await emailSender.send(
config.server.reportErrors,
new ErrorMessage({
code: ErrorCode.UNKNOWN_ERROR,
message: `${err.message}\n${err.stack}`,
time: new Date().toISOString(),
eventId: "",
new PlainMessage({
message: `An uncaught exception occured at ${new Date().toISOString()}:\n${err.message}\n${
err.stack
}`,
})
);
} catch (e) {}

View File

@ -0,0 +1,17 @@
import { Logger, LogEvent } from "@padloc/core/src/logging";
import { PostgresStorage } from "../storage/postgres";
export class PostgresLogger implements Logger {
constructor(private _storage: PostgresStorage) {}
log(type: string, data?: any) {
const event = new LogEvent(type, data);
event.id = `${event.time.toISOString()}_${Math.floor(Math.random() * 1e6)}`;
(async () => {
try {
this._storage.save(event);
} catch (e) {}
})();
return event;
}
}

View File

@ -3,4 +3,10 @@ import { NodeCryptoProvider } from "../crypto/node";
export class NodePlatform extends StubPlatform implements Platform {
crypto = new NodeCryptoProvider();
async getDeviceInfo() {
const info = await super.getDeviceInfo();
info.runtime = "node";
return info;
}
}

View File

@ -23,6 +23,7 @@ import { base64ToBytes, bytesToBase64, stringToBytes } from "@padloc/core/src/en
import { HMACKeyParams, HMACParams } from "@padloc/core/src/crypto";
import { URLSearchParams } from "url";
import { Account } from "@padloc/core/src/account";
import { Session } from "@padloc/core/src/session";
export class StripeProvisionerConfig extends BasicProvisionerConfig {
@ConfigParam("string", true)
@ -48,6 +49,9 @@ export class StripeProvisionerConfig extends BasicProvisionerConfig {
@ConfigParam("number")
forceSyncAfter: number = 24 * 60 * 60;
@ConfigParam("string[]")
disableBillingOn = ["ios", "android"];
}
enum Tier {
@ -218,8 +222,8 @@ export class StripeProvisioner extends BasicProvisioner {
}
}
async getProvisioning(opts: { email: string; accountId?: string | undefined }) {
const provisioning = await super.getProvisioning(opts);
async getProvisioning(opts: { email: string; accountId?: string | undefined }, session?: Session) {
let provisioning = await super.getProvisioning(opts);
if (
provisioning.account.accountId &&
(!provisioning.account.metaData?.customer ||
@ -228,7 +232,35 @@ export class StripeProvisioner extends BasicProvisioner {
) {
await this._syncBilling(provisioning);
}
return super.getProvisioning(opts);
provisioning = await super.getProvisioning(opts);
const platform = session?.device?.platform?.toLowerCase() || "";
const runtime = session?.device?.runtime;
if (runtime === "cordova" && this.config.disableBillingOn.includes(platform)) {
provisioning.account.billingPage = undefined;
for (const feature of Object.values(provisioning.account.features)) {
if (feature.disabled) {
feature.message = {
type: "html",
content: html`
<div style="max-width: 20em">
<div class="large text-centering semibold">
<i class="fa-ban"></i> Feature Not Available
</div>
<div class="top-margined">
This feature is not available on this platform yet. Please use the
<a href="https://web.padloc.app">web app</a> instead!
</div>
</div>
`,
};
feature.actionUrl = "https://web.padloc.app";
feature.actionLabel = "Open Web App";
}
}
}
return provisioning;
}
async orgOwnerChanged(
@ -328,9 +360,7 @@ export class StripeProvisioner extends BasicProvisioner {
email,
expand: ["data.subscriptions", "data.tax_ids"],
});
customer = existingCustomers.data.find(
(c) => !c.metadata.org && (!c.metadata.account || c.metadata.account === accountId)
);
customer = existingCustomers.data.find((c) => !c.metadata.account || c.metadata.account === accountId);
}
// Create a new customer

View File

@ -1,7 +1,10 @@
import { Platform } from "@padloc/core/src/platform";
import { WebPlatform } from "@padloc/app/src/lib/platform";
// import { MemoryStorage } from "@padloc/core/src/storage";
export class TauriPlatform extends WebPlatform implements Platform {
// storage = new MemoryStorage();
async getDeviceInfo() {
const device = await super.getDeviceInfo();
device.runtime = "tauri";
return device;
}
}