Skip to content

Commit

Permalink
Homebase tabs (#256)
Browse files Browse the repository at this point in the history
Co-authored-by: Jesse Paterson <[email protected]>
  • Loading branch information
hiporox and j-paterson authored Jul 28, 2024
1 parent 47336d5 commit 9d2bac5
Show file tree
Hide file tree
Showing 10 changed files with 613 additions and 95 deletions.
62 changes: 30 additions & 32 deletions src/common/data/stores/app/accounts/authenticatorStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export interface AuthenticatorState {

export interface AuthenticatorActions {
loadAuthenitcators: () => Promise<void>;
commitAuthenticatorUpdatesToDatabase: () => Promise<void>;
commitAuthenticatorUpdatesToDatabase: () => Promise<void> | undefined;
saveAuthenticatorConfig: (newConfig: AuthenticatorConfig) => Promise<void>;
listInstalledAuthenticators: () => string[];
resetAuthenticators: () => void;
Expand Down Expand Up @@ -87,38 +87,36 @@ export const authenticatorStore = (
console.debug("Could not locate authenticator data");
}
},
commitAuthenticatorUpdatesToDatabase: async () => {
debounce(async () => {
if (
get().account.authenticatorConfig ===
get().account.authenticatorRemoteConfig
) {
// Only update if changes have been made
return;
}
const configFile = await get().account.createEncryptedSignedFile(
stringify(get().account.authenticatorConfig),
"json",
);
const postData: AuthenticatorUpdateRequest = {
file: configFile,
identityPublicKey: get().account.currentSpaceIdentityPublicKey!,
};
commitAuthenticatorUpdatesToDatabase: debounce(async () => {
if (
get().account.authenticatorConfig ===
get().account.authenticatorRemoteConfig
) {
// Only update if changes have been made
return;
}
const configFile = await get().account.createEncryptedSignedFile(
stringify(get().account.authenticatorConfig),
"json",
);
const postData: AuthenticatorUpdateRequest = {
file: configFile,
identityPublicKey: get().account.currentSpaceIdentityPublicKey!,
};

try {
await axiosBackend.post("/api/space/authenticators/", postData, {
headers: { "Content-Type": "application/json" },
});
set((draft) => {
draft.account.authenticatorRemoteConfig =
get().account.authenticatorConfig;
}, "commitAuthenticatorUpdatesToDatabase");
} catch (e) {
console.debug("failed to save authenticator data, trying again");
get().account.commitAuthenticatorUpdatesToDatabase();
}
}, 1000)();
},
try {
await axiosBackend.post("/api/space/authenticators/", postData, {
headers: { "Content-Type": "application/json" },
});
set((draft) => {
draft.account.authenticatorRemoteConfig =
get().account.authenticatorConfig;
}, "commitAuthenticatorUpdatesToDatabase");
} catch (e) {
console.debug("failed to save authenticator data, trying again");
get().account.commitAuthenticatorUpdatesToDatabase();
}
}, 1000),
saveAuthenticatorConfig: async (newConfig) => {
set((draft) => {
draft.account.authenticatorConfig = newConfig;
Expand Down
11 changes: 8 additions & 3 deletions src/common/data/stores/app/accounts/prekeyStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ interface PreKeyActions {
createEncryptedSignedFile: (
data: string,
fileType: string,
useRootKey?: boolean,
options?: {
useRootKey?: boolean;
fileName?: string;
},
) => Promise<SignedFile>;
decryptEncryptedSignedFile: (file: SignedFile) => Promise<string>;
generatePreKey: () => Promise<PreSpaceKeys>;
Expand Down Expand Up @@ -88,7 +91,8 @@ export const prekeyStore = (
currentIdentity.rootKeys.privateKey,
);
},
createEncryptedSignedFile: async (data, fileType, useRootKey = false) => {
createEncryptedSignedFile: async (data, fileType, options) => {
const useRootKey = options?.useRootKey || false;
const key = useRootKey
? get().account.getCurrentIdentity()!.rootKeys
: get().account.getCurrentPrekey() ||
Expand All @@ -102,6 +106,7 @@ export const prekeyStore = (
publicKey: key.publicKey,
isEncrypted: true,
timestamp: moment().toISOString(),
fileName: options?.fileName,
};
return signSignable(file, key.privateKey);
},
Expand Down Expand Up @@ -145,7 +150,7 @@ export const prekeyStore = (
const keyFile = await get().account.createEncryptedSignedFile(
stringify(prekey),
"json",
true,
{ useRootKey: true },
);
const postData: PreKeyRequest = {
file: keyFile,
Expand Down
56 changes: 30 additions & 26 deletions src/common/data/stores/app/homebase/homebaseStore.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { StoreGet, StoreSet } from "../../createStore";
import { AppStore } from "..";
import axios from "axios";
import { createClient } from "../../../database/supabase/clients/component";
import { createClient } from "@/common/data/database/supabase/clients/component";
import { homebasePath } from "@/constants/supabase";
import { SignedFile } from "@/common/lib/signedFiles";
import { cloneDeep, debounce, isArray, isUndefined, mergeWith } from "lodash";
import stringify from "fast-json-stable-stringify";
import axiosBackend from "../../../api/backend";
import axiosBackend from "@/common/data/api/backend";
import {
SpaceConfig,
SpaceConfigSaveDetails,
Expand All @@ -16,6 +16,10 @@ import {
analytics,
AnalyticsEvent,
} from "@/common/providers/AnalyticsProvider";
import {
HomeBaseTabStore,
createHomeBaseTabStoreFunc,
} from "./homebaseTabsStore";
import moment from "moment";

interface HomeBaseStoreState {
Expand All @@ -25,13 +29,15 @@ interface HomeBaseStoreState {

interface HomeBaseStoreActions {
loadHomebase: () => Promise<SpaceConfig>;
commitHomebaseToDatabase: () => Promise<void>;
commitHomebaseToDatabase: () => Promise<void> | undefined;
saveHomebaseConfig: (config: SpaceConfigSaveDetails) => Promise<void>;
resetHomebaseConfig: () => Promise<void>;
clearHomebase: () => void;
}

export type HomeBaseStore = HomeBaseStoreState & HomeBaseStoreActions;
export type HomeBaseStore = HomeBaseStoreState &
HomeBaseStoreActions &
HomeBaseTabStore;

export const homeBaseStoreDefaults: HomeBaseStoreState = {};

Expand All @@ -40,6 +46,7 @@ export const createHomeBaseStoreFunc = (
get: StoreGet<AppStore>,
): HomeBaseStore => ({
...homeBaseStoreDefaults,
...createHomeBaseTabStoreFunc(set, get),
loadHomebase: async () => {
const supabase = createClient();
const {
Expand Down Expand Up @@ -92,29 +99,26 @@ export const createHomeBaseStoreFunc = (
return cloneDeep(INITIAL_HOMEBASE_CONFIG);
}
},
commitHomebaseToDatabase: async () => {
debounce(async () => {
const localCopy = cloneDeep(get().homebase.homebaseConfig);
if (localCopy) {
const file = await get().account.createEncryptedSignedFile(
stringify(localCopy),
"json",
true,
);
// TO DO: Error handling
try {
await axiosBackend.post(`/api/space/homebase/`, file);
set((draft) => {
draft.homebase.remoteHomebaseConfig = localCopy;
}, "commitHomebaseToDatabase");
analytics.track(AnalyticsEvent.SAVE_HOMEBASE_THEME);
} catch (e) {
console.error(e);
throw e;
}
commitHomebaseToDatabase: debounce(async () => {
const localCopy = cloneDeep(get().homebase.homebaseConfig);
if (localCopy) {
const file = await get().account.createEncryptedSignedFile(
stringify(localCopy),
"json",
{ useRootKey: true },
);
try {
await axiosBackend.post(`/api/space/homebase/`, file);
set((draft) => {
draft.homebase.remoteHomebaseConfig = localCopy;
}, "commitHomebaseToDatabase");
analytics.track(AnalyticsEvent.SAVE_HOMEBASE_THEME);
} catch (e) {
console.error(e);
throw e;
}
}, 1000)();
},
}
}, 1000),
saveHomebaseConfig: async (config) => {
const localCopy = cloneDeep(get().homebase.homebaseConfig) as SpaceConfig;
mergeWith(localCopy, config, (_, newItem) => {
Expand Down
Loading

0 comments on commit 9d2bac5

Please sign in to comment.