From fc31cc49f66967e946d574b4bda519436d7b309f Mon Sep 17 00:00:00 2001 From: Abdullah Atta Date: Wed, 28 Feb 2024 23:21:22 +0500 Subject: [PATCH] core: add support for setting user profile --- packages/core/src/api/user-manager.ts | 54 +++++++++++++-------------- packages/core/src/database/kv.ts | 2 +- packages/core/src/types.ts | 33 ++++++++++++++++ 3 files changed, 59 insertions(+), 30 deletions(-) diff --git a/packages/core/src/api/user-manager.ts b/packages/core/src/api/user-manager.ts index a909b58f2..fa1ff8b2e 100644 --- a/packages/core/src/api/user-manager.ts +++ b/packages/core/src/api/user-manager.ts @@ -17,40 +17,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -import "../types"; +import { User, Profile } from "../types"; import http from "../utils/http"; import constants from "../utils/constants"; import TokenManager from "./token-manager"; import { EV, EVENTS } from "../common"; import { HealthCheck } from "./healthcheck"; import Database from "."; -import { Cipher, SerializedKey } from "@notesnook/crypto"; - -export type AuthenticatorType = "app" | "sms" | "email"; -export type User = { - id: string; - email: string; - isEmailConfirmed: boolean; - salt: string; - attachmentsKey?: Cipher<"base64">; - marketingConsent?: boolean; - mfa: { - isEnabled: boolean; - primaryMethod: AuthenticatorType; - secondaryMethod?: AuthenticatorType; - remainingValidCodes: number; - }; - subscription: { - appId: 0; - cancelURL: string | null; - expiry: number; - productId: string; - provider: 0 | 1 | 2 | 3; - start: number; - type: 0 | 1 | 2 | 5 | 6 | 7; - updateURL: string | null; - }; -}; +import { SerializedKey } from "@notesnook/crypto"; const ENDPOINTS = { signup: "/users", @@ -301,7 +275,7 @@ class UserManager { return true; } - async updateUser(user: User) { + private async updateUser(user: User) { const token = await this.tokenManager.getAccessToken(); await http.patch.json( `${constants.API_HOST}${ENDPOINTS.user}`, @@ -312,6 +286,28 @@ class UserManager { await this.setUser(user); } + async setProfile(profile: Partial) { + const user = await this.getUser(); + const key = await this.getEncryptionKey(); + if (!user || !key) return; + + user.profile = await this.db + .storage() + .encrypt(key, JSON.stringify({ ...user.profile, ...profile })); + await this.updateUser(user); + } + + async getProfile() { + const user = await this.getUser(); + const key = await this.getEncryptionKey(); + if (!user || !key || !user.profile) return; + + const profile = JSON.parse( + await this.db.storage().decrypt(key, user.profile) + ); + return profile as Profile; + } + async deleteUser(password: string) { const token = await this.tokenManager.getAccessToken(); const user = await this.getUser(); diff --git a/packages/core/src/database/kv.ts b/packages/core/src/database/kv.ts index 5917adca0..5eb6c9174 100644 --- a/packages/core/src/database/kv.ts +++ b/packages/core/src/database/kv.ts @@ -19,7 +19,7 @@ along with this program. If not, see . import { DatabaseAccessor, RawDatabaseSchema } from "."; import { Token } from "../api/token-manager"; -import { User } from "../api/user-manager"; +import { User } from "../types"; interface KV { v: number; diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 183285224..c7b32001d 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -505,6 +505,39 @@ export type BaseTrashItem> = export type TrashItem = BaseTrashItem | BaseTrashItem; +export type AuthenticatorType = "app" | "sms" | "email"; + +export type User = { + id: string; + email: string; + isEmailConfirmed: boolean; + salt: string; + attachmentsKey?: Cipher<"base64">; + profile?: Cipher<"base64">; + marketingConsent?: boolean; + mfa: { + isEnabled: boolean; + primaryMethod: AuthenticatorType; + secondaryMethod?: AuthenticatorType; + remainingValidCodes: number; + }; + subscription: { + appId: 0; + cancelURL: string | null; + expiry: number; + productId: string; + provider: 0 | 1 | 2 | 3; + start: number; + type: 0 | 1 | 2 | 5 | 6 | 7; + updateURL: string | null; + }; +}; + +export type Profile = { + fullName?: string; + profilePicture?: string; +}; + export function isDeleted(item: any): item is DeletedItem { return !!item.deleted && item.type !== "trash"; }