From 3fb4d95fd790c785e2f230299bbedb428983dfc6 Mon Sep 17 00:00:00 2001 From: Brandon Date: Thu, 2 May 2024 10:16:45 -0700 Subject: [PATCH 01/63] Adding basic MFA in the form of TOTP --- package-lock.json | 30 + package.json | 3 +- .../widgets/type_widgets/content_widget.js | 134 +- .../options/multi_factor_authentication.js | 109 ++ src/routes/api/totp.ts | 24 + src/routes/routes.ts | 1577 ++++++++++++----- src/services/encryption/my_scrypt.ts | 39 +- .../encryption/password_encryption.ts | 50 +- src/services/encryption/totp_secret.ts | 110 ++ .../encryption/totp_secret_encryption.ts | 52 + src/services/hidden_subtree.ts | 834 +++++---- src/views/login.ejs | 134 +- 12 files changed, 2188 insertions(+), 908 deletions(-) create mode 100644 src/public/app/widgets/type_widgets/options/multi_factor_authentication.js create mode 100644 src/routes/api/totp.ts create mode 100644 src/services/encryption/totp_secret.ts create mode 100644 src/services/encryption/totp_secret_encryption.ts diff --git a/package-lock.json b/package-lock.json index 2dd4a639d1..037578fba5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -73,6 +73,7 @@ "semver": "7.6.0", "serve-favicon": "2.5.0", "session-file-store": "1.5.0", + "speakeasy": "^2.0.0", "split.js": "1.6.5", "stream-throttle": "0.1.3", "striptags": "3.2.0", @@ -2708,6 +2709,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "node_modules/base32.js": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.0.1.tgz", + "integrity": "sha512-EGHIRiegFa62/SsA1J+Xs2tIzludPdzM064N9wjbiEgHnGnJ1V0WEpA4pEwCYT5nDvZk3ubf0shqaCS7k6xeUQ==" + }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -11795,6 +11801,17 @@ "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, + "node_modules/speakeasy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/speakeasy/-/speakeasy-2.0.0.tgz", + "integrity": "sha512-lW2A2s5LKi8rwu77ewisuUOtlCydF/hmQSOJjpTqTj1gZLkNgTaYnyvfxy2WBr4T/h+9c4g8HIITfj83OkFQFw==", + "dependencies": { + "base32.js": "0.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, "node_modules/split.js": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz", @@ -15542,6 +15559,11 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, + "base32.js": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/base32.js/-/base32.js-0.0.1.tgz", + "integrity": "sha512-EGHIRiegFa62/SsA1J+Xs2tIzludPdzM064N9wjbiEgHnGnJ1V0WEpA4pEwCYT5nDvZk3ubf0shqaCS7k6xeUQ==" + }, "base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -22382,6 +22404,14 @@ "integrity": "sha512-oie3/+gKf7QtpitB0LYLETe+k8SifzsX4KixvpOsbI6S0kRiRQ5MKOio8eMSAKQ17N06+wdEOXRiId+zOxo0hA==", "dev": true }, + "speakeasy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/speakeasy/-/speakeasy-2.0.0.tgz", + "integrity": "sha512-lW2A2s5LKi8rwu77ewisuUOtlCydF/hmQSOJjpTqTj1gZLkNgTaYnyvfxy2WBr4T/h+9c4g8HIITfj83OkFQFw==", + "requires": { + "base32.js": "0.0.1" + } + }, "split.js": { "version": "1.6.5", "resolved": "https://registry.npmjs.org/split.js/-/split.js-1.6.5.tgz", diff --git a/package.json b/package.json index cbfcd7e325..fdbd270a66 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "semver": "7.6.0", "serve-favicon": "2.5.0", "session-file-store": "1.5.0", + "speakeasy": "^2.0.0", "split.js": "1.6.5", "stream-throttle": "0.1.3", "striptags": "3.2.0", @@ -155,4 +156,4 @@ "optionalDependencies": { "electron-installer-debian": "3.2.0" } -} \ No newline at end of file +} diff --git a/src/public/app/widgets/type_widgets/content_widget.js b/src/public/app/widgets/type_widgets/content_widget.js index fe7f105afb..f72e00fcfa 100644 --- a/src/public/app/widgets/type_widgets/content_widget.js +++ b/src/public/app/widgets/type_widgets/content_widget.js @@ -32,6 +32,7 @@ import DatabaseAnonymizationOptions from "./options/advanced/database_anonymizat import BackendLogWidget from "./content/backend_log.js"; import AttachmentErasureTimeoutOptions from "./options/other/attachment_erasure_timeout.js"; import RibbonOptions from "./options/appearance/ribbon.js"; +import MultiFactorAuthenticationOptions from "./options/multi_factor_authentication.js"; const TPL = `