From c74da18e234103f3b84f6f6044a4c99005d7db7d Mon Sep 17 00:00:00 2001 From: chesspro13 Date: Sat, 7 Sep 2024 13:18:47 -0700 Subject: [PATCH] OAuth working --- db/schema.sql | 2 + .../options/multi_factor_authentication.js | 36 ++++++++-------- src/routes/routes.ts | 1 + src/services/encryption/open_id_encryption.ts | 9 ++-- src/services/open_id.ts | 41 +++++++++++++++---- 5 files changed, 61 insertions(+), 28 deletions(-) diff --git a/db/schema.sql b/db/schema.sql index d47c595d8..2f6a18ef1 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -129,6 +129,8 @@ CREATE TABLE IF NOT EXISTS "attachments" CREATE TABLE IF NOT EXISTS "user_data" ( tmpID INT, + username TEXT, + email TEXT, userIDEcnryptedDataKey TEXT, userIDVerificationHash TEXT, salt TEXT, diff --git a/src/public/app/widgets/type_widgets/options/multi_factor_authentication.js b/src/public/app/widgets/type_widgets/options/multi_factor_authentication.js index 99cd42ac9..ceac5d2e3 100644 --- a/src/public/app/widgets/type_widgets/options/multi_factor_authentication.js +++ b/src/public/app/widgets/type_widgets/options/multi_factor_authentication.js @@ -26,10 +26,9 @@ const TPL = `
- Token status: Needs login! User status: No user saved! + User Account: User Email:
- - +

@@ -104,10 +103,10 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget { ".generate-recovery-code" ); this.$oAuthEnabledCheckbox = this.$widget.find(".oauth-enabled-checkbox"); - this.$saveUserButton = this.$widget.find(".save-user-button"); + this.$clearSavedUserButton = this.$widget.find(".clear-saved-user-button"); this.$oauthLoginButton = this.$widget.find(".oauth-login-button"); - this.$tokenStatus = this.$widget.find(".token-status"); - this.$userStatus = this.$widget.find(".user-status"); + this.$UserAccountName = this.$widget.find(".user-account-name"); + this.$UserAccountEmail = this.$widget.find(".user-account-email"); this.$envEnabledTOTP = this.$widget.find(".env-totp-enabled"); this.$envEnabledOAuth = this.$widget.find(".env-oauth-enabled"); @@ -122,9 +121,10 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget { // this.updateSecret(); // }); - this.$oAuthEnabledCheckbox.on("change", async () => { - this.updateOAuthStatus(); - }); + // Depricated. Will use .env to control. + // this.$oAuthEnabledCheckbox.on("change", async () => { + // this.updateOAuthStatus(); + // }); this.$generateRecoveryCodeButton.on("click", async () => { this.setRecoveryKeys(); @@ -134,11 +134,10 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget { this.generateKey(); }); - this.$saveUserButton.on("click", (async) => { + this.$clearSavedUserButton.on("click", (async) => { server - .get("oauth/authenticate") + .get("oauth/clearUser") .then((result) => { - console.log(result.message); toastService.showMessage(result.message); }) .catch((result) => { @@ -213,10 +212,10 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget { optionsLoaded(options) { // TODO: Rework the logic since I've changed how OAuth works - // server.get("oauth/status").then((result) => { - // if (result.enabled) { + server.get("oauth/status").then((result) => { + if (result.enabled) { // if (result.success) - // this.$oAuthEnabledCheckbox.prop("checked", result.message); + this.$oAuthEnabledCheckbox.prop("checked", result.enabled); // this.$oauthLoginButton.prop("disabled", !result.message); // this.$saveUserButton.prop("disabled", !result.message); @@ -226,7 +225,8 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget { // this.$saveUserButton.prop("disabled", false); // server.get("oauth/validate").then((result) => { // if (result.success) { - // this.$tokenStatus.text("Logged in!"); + this.$UserAccountName.text(result.name); + this.$UserAccountEmail.text(result.email); // if (result.user) { // this.$userStatus.text("User saved!"); @@ -246,8 +246,8 @@ export default class MultiFactorAuthenticationOptions extends OptionsWidget { // this.$envEnabledOAuth.text( // "OAuth can only be enabled with environment variables. REQUIRES RESTART" // ); - // } - // }); + } + }); server.get("totp/status").then((result) => { console.log(result); diff --git a/src/routes/routes.ts b/src/routes/routes.ts index d6f2024ea..844f995a8 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -129,6 +129,7 @@ function register(app: express.Application) { apiRoute(GET, '/api/totp/get', totp.getSecret); apiRoute(GET, '/api/oauth/status', openID.getOAuthStatus); + apiRoute(GET, '/api/oauth/clearUser', openID.clearSavedUser); apiRoute(GET, '/api/oauth/validate', openID.isTokenValid); apiRoute(PST, '/api/totp_recovery/set', recoveryCodes.setRecoveryCodes); diff --git a/src/services/encryption/open_id_encryption.ts b/src/services/encryption/open_id_encryption.ts index aef3b3abf..85711c90f 100644 --- a/src/services/encryption/open_id_encryption.ts +++ b/src/services/encryption/open_id_encryption.ts @@ -5,7 +5,7 @@ import dataEncryptionService from "./data_encryption.js"; import sql from "../sql.js"; import sqlInit from "../sql_init.js"; -function saveSubjectIdentifier(subjectIdentifier: string) { +function saveUser(subjectIdentifier: string, name: string, email: string) { if (isUserSaved()) return false; // Allows setup with existing instances of trilium @@ -13,6 +13,8 @@ function saveSubjectIdentifier(subjectIdentifier: string) { CREATE TABLE IF NOT EXISTS "user_data" ( tmpID INT, + username TEXT, + email TEXT, userIDEcnryptedDataKey TEXT, userIDVerificationHash TEXT, salt TEXT, @@ -52,9 +54,10 @@ function saveSubjectIdentifier(subjectIdentifier: string) { derivedKey: derivedKeySalt, userIDEcnryptedDataKey: userIDEncryptedDataKey, isSetup: "true", + username: name, + email: email }; - console.log("Saved data: " + data); sql.upsert("user_data", "tmpID", data); return true; } @@ -158,6 +161,6 @@ export default { verifyOpenIDSubjectIdentifier, getDataKey, setDataKey, - saveSubjectIdentifier, + saveUser, isSubjectIdentifierSaved, }; \ No newline at end of file diff --git a/src/services/open_id.ts b/src/services/open_id.ts index 4e45444f3..c431b6c2d 100644 --- a/src/services/open_id.ts +++ b/src/services/open_id.ts @@ -11,8 +11,27 @@ function isOpenIDEnabled() { } function isUserSaved() { - const dbf = sql.getValue("SELECT isSetup FROM user_data;"); - return dbf === "true" ? true : false; + const data = sql.getValue("SELECT isSetup FROM user_data;"); + return data === "true" ? true : false; +} + +function getUsername() { + const username = sql.getValue("SELECT username FROM user_data;"); + return username; +} + +function getUserEmail() { + const email = sql.getValue("SELECT email FROM user_data;"); + return email; +} + +function clearSavedUser() { + sql.execute("DELETE FROM user_data"); + options.setOption("isUserSaved", false); + return { + success: true, + message: "Account data removed." + }; } function checkOpenIDRequirements() { @@ -45,7 +64,9 @@ function checkOpenIDRequirements() { function getOAuthStatus() { return { success: true, - message: checkOpenIDRequirements(), + name: getUsername(), + email: getUserEmail(), + enabled: isOpenIDEnabled(), }; } @@ -117,12 +138,17 @@ function generateOAuthConfig() { if (isUserSaved()) return session; - if (req.oidc.user === undefined) console.log("user invalid!"); - else openIDEncryption.saveSubjectIdentifier(req.oidc.user.sub.toString()); - + if (req.oidc.user === undefined) { + console.log("user invalid!"); + }else { + openIDEncryption.saveUser( + req.oidc.user.sub.toString(), + req.oidc.user.name.toString(), + req.oidc.user.email.toString()); + } return session; }, - }; + }; return authConfig; } @@ -130,6 +156,7 @@ export default { generateOAuthConfig, getOAuthStatus, isOpenIDEnabled, + clearSavedUser, checkOpenIDRequirements, isTokenValid, isUserSaved,