From bd22c8c1a9e8a08b337bbfa2bdfe36b560db8df0 Mon Sep 17 00:00:00 2001 From: Akash K <57758277+amk-dev@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:22:59 +0530 Subject: [PATCH] feat: disable tracking request history (#4607) Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com> --- packages/hoppscotch-common/locales/en.json | 1 + .../src/components/history/index.vue | 30 ++++- .../hoppscotch-common/src/platform/history.ts | 7 ++ .../__tests__/history.searcher.spec.ts | 9 ++ .../spotlight/searchers/history.searcher.ts | 19 +++- .../api/queries/IsUserHistoryEnabled.graphql | 6 + .../UserHistoryAllDeleted.graphql | 3 + .../UserHistoryStoreStatusChanged.graphql | 3 + .../src/platform/history/history.api.ts | 27 +++++ .../src/platform/history/history.platform.ts | 76 +++++++++++++ .../api/queries/IsUserHistoryEnabled.graphql | 6 + .../UserHistoryAllDeleted.graphql | 3 + .../UserHistoryStoreStatusChanged.graphql | 3 + .../src/platform/history/history.api.ts | 27 +++++ .../src/platform/history/history.platform.ts | 81 +++++++++++++- .../src/platform/history/history.sync.ts | 10 ++ packages/hoppscotch-sh-admin/locales/en.json | 10 ++ .../components/settings/Configurations.vue | 1 + .../settings/HistoryConfiguration.vue | 104 ++++++++++++++++++ .../src/components/settings/ServerRestart.vue | 14 +++ .../src/composables/useConfigHandler.ts | 24 ++++ .../RevokeAllUserHistoryByAdmin.graphql | 3 + .../mutations/ToggleUserHistoryStore.graphql | 3 + .../src/helpers/configs.ts | 13 +++ 24 files changed, 477 insertions(+), 6 deletions(-) create mode 100644 packages/hoppscotch-selfhost-desktop/src/api/queries/IsUserHistoryEnabled.graphql create mode 100644 packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryAllDeleted.graphql create mode 100644 packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql create mode 100644 packages/hoppscotch-selfhost-web/src/api/queries/IsUserHistoryEnabled.graphql create mode 100644 packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryAllDeleted.graphql create mode 100644 packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql create mode 100644 packages/hoppscotch-sh-admin/src/components/settings/HistoryConfiguration.vue create mode 100644 packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/RevokeAllUserHistoryByAdmin.graphql create mode 100644 packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ToggleUserHistoryStore.graphql diff --git a/packages/hoppscotch-common/locales/en.json b/packages/hoppscotch-common/locales/en.json index 1b638364..685c3951 100644 --- a/packages/hoppscotch-common/locales/en.json +++ b/packages/hoppscotch-common/locales/en.json @@ -797,6 +797,7 @@ "sync_description": "These settings are synced to cloud.", "sync_environments": "Environments", "sync_history": "History", + "history_disabled": "History is disabled", "system_mode": "System", "telemetry": "Telemetry", "telemetry_helps_us": "Telemetry helps us to personalize our operations and deliver the best experience to you.", diff --git a/packages/hoppscotch-common/src/components/history/index.vue b/packages/hoppscotch-common/src/components/history/index.vue index 750994a4..db71fd9a 100644 --- a/packages/hoppscotch-common/src/components/history/index.vue +++ b/packages/hoppscotch-common/src/components/history/index.vue @@ -51,7 +51,11 @@ -
+
+ + ( [] ) +const { isHistoryStoreEnabled, isFetchingHistoryStoreStatus } = + "requestHistoryStore" in platform.sync.history && + platform.sync.history.requestHistoryStore + ? platform.sync.history.requestHistoryStore + : { + isHistoryStoreEnabled: ref(true), + isFetchingHistoryStoreStatus: ref(false), + } + const deepCheckForRegex = (value: unknown, regExp: RegExp): boolean => { if (value === null || value === undefined) return false diff --git a/packages/hoppscotch-common/src/platform/history.ts b/packages/hoppscotch-common/src/platform/history.ts index 08736099..7a3cceda 100644 --- a/packages/hoppscotch-common/src/platform/history.ts +++ b/packages/hoppscotch-common/src/platform/history.ts @@ -1,3 +1,10 @@ +import { Ref } from "vue" + export type HistoryPlatformDef = { initHistorySync: () => void + requestHistoryStore?: { + isHistoryStoreEnabled: Ref + isFetchingHistoryStoreStatus: Ref + hasErrorFetchingHistoryStoreStatus: Ref + } } diff --git a/packages/hoppscotch-common/src/services/spotlight/searchers/__tests__/history.searcher.spec.ts b/packages/hoppscotch-common/src/services/spotlight/searchers/__tests__/history.searcher.spec.ts index 5d2484bd..8c2e6873 100644 --- a/packages/hoppscotch-common/src/services/spotlight/searchers/__tests__/history.searcher.spec.ts +++ b/packages/hoppscotch-common/src/services/spotlight/searchers/__tests__/history.searcher.spec.ts @@ -8,6 +8,7 @@ import { getDefaultRESTRequest } from "~/helpers/rest/default" import { HoppAction, HoppActionWithArgs } from "~/helpers/actions" import { getDefaultGQLRequest } from "~/helpers/graphql/default" import { RESTTabService } from "~/services/tab/rest" +import { PlatformDef, setPlatformDef } from "~/platform" async function flushPromises() { return await new Promise((r) => setTimeout(r)) @@ -74,6 +75,14 @@ describe("HistorySpotlightSearcherService", () => { actionsMock.invokeAction.mockReset() createNewTabFn.mockReset() + + const platform = { + sync: { + history: {}, + }, + } + + setPlatformDef(platform as PlatformDef) }) it("registers with the spotlight service upon initialization", async () => { diff --git a/packages/hoppscotch-common/src/services/spotlight/searchers/history.searcher.ts b/packages/hoppscotch-common/src/services/spotlight/searchers/history.searcher.ts index a2ce4d0a..91ed1ba9 100644 --- a/packages/hoppscotch-common/src/services/spotlight/searchers/history.searcher.ts +++ b/packages/hoppscotch-common/src/services/spotlight/searchers/history.searcher.ts @@ -20,6 +20,7 @@ import { useStreamStatic } from "~/composables/stream" import { activeActions$, invokeAction } from "~/helpers/actions" import { map } from "rxjs/operators" import { HoppRequestDocument } from "~/helpers/rest/document" +import { platform } from "~/platform" /** * This searcher is responsible for searching through the history. @@ -48,6 +49,22 @@ export class HistorySpotlightSearcherService } )[0] + private hasHistoryPlatformDef = "requestHistoryStore" in platform.sync.history + + private isHistoryEnabledPlatformRef = + platform.sync.history.requestHistoryStore?.isHistoryStoreEnabled + + private clearHistoryActionEnabledCombined = computed(() => { + // if the platform has not defined the history store, by default we consider history is enabled + if (!this.hasHistoryPlatformDef) return this.clearHistoryActionEnabled.value + + // if the platform has defined the history store, we check the defined values to determine if history is enabled + return ( + this.clearHistoryActionEnabled.value && + this.isHistoryEnabledPlatformRef?.value + ) + }) + private restHistoryEntryOpenable = useStreamStatic( activeActions$.pipe( map((actions) => actions.includes("rest.request.open")) @@ -82,7 +99,7 @@ export class HistorySpotlightSearcherService }) const stopWatchHandle = watch( - this.clearHistoryActionEnabled, + this.clearHistoryActionEnabledCombined, (enabled) => { if (enabled) { if (minisearch.has("clear-history")) return diff --git a/packages/hoppscotch-selfhost-desktop/src/api/queries/IsUserHistoryEnabled.graphql b/packages/hoppscotch-selfhost-desktop/src/api/queries/IsUserHistoryEnabled.graphql new file mode 100644 index 00000000..77bd9650 --- /dev/null +++ b/packages/hoppscotch-selfhost-desktop/src/api/queries/IsUserHistoryEnabled.graphql @@ -0,0 +1,6 @@ +query IsUserHistoryEnabled { + isUserHistoryEnabled { + name + value + } +} diff --git a/packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryAllDeleted.graphql b/packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryAllDeleted.graphql new file mode 100644 index 00000000..2e57592c --- /dev/null +++ b/packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryAllDeleted.graphql @@ -0,0 +1,3 @@ +subscription UserHistoryAllDeleted { + userHistoryAllDeleted +} diff --git a/packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql b/packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql new file mode 100644 index 00000000..bde1df55 --- /dev/null +++ b/packages/hoppscotch-selfhost-desktop/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql @@ -0,0 +1,3 @@ +subscription UserHistoryStoreStatusChanged { + infraConfigUpdate(configName: USER_HISTORY_STORE_ENABLED) +} diff --git a/packages/hoppscotch-selfhost-desktop/src/platform/history/history.api.ts b/packages/hoppscotch-selfhost-desktop/src/platform/history/history.api.ts index 862f776f..0b8c4697 100644 --- a/packages/hoppscotch-selfhost-desktop/src/platform/history/history.api.ts +++ b/packages/hoppscotch-selfhost-desktop/src/platform/history/history.api.ts @@ -25,6 +25,11 @@ import { UserHistoryDeletedDocument, UserHistoryDeletedManyDocument, UserHistoryUpdatedDocument, + IsUserHistoryEnabledQuery, + IsUserHistoryEnabledQueryVariables, + IsUserHistoryEnabledDocument, + UserHistoryStoreStatusChangedDocument, + UserHistoryAllDeletedDocument, } from "../../api/generated/graphql" export const getUserHistoryEntries = () => @@ -33,6 +38,16 @@ export const getUserHistoryEntries = () => variables: {}, }) +export const getUserHistoryStore = () => + runGQLQuery< + IsUserHistoryEnabledQuery, + IsUserHistoryEnabledQueryVariables, + "" + >({ + query: IsUserHistoryEnabledDocument, + variables: {}, + }) + export const createUserHistory = ( reqData: string, resMetadata: string, @@ -98,3 +113,15 @@ export const runUserHistoryDeletedManySubscription = () => query: UserHistoryDeletedManyDocument, variables: {}, }) + +export const runUserHistoryStoreStatusChangedSubscription = () => + runGQLSubscription({ + query: UserHistoryStoreStatusChangedDocument, + variables: {}, + }) + +export const runUserHistoryAllDeletedSubscription = () => + runGQLSubscription({ + query: UserHistoryAllDeletedDocument, + variables: {}, + }) diff --git a/packages/hoppscotch-selfhost-desktop/src/platform/history/history.platform.ts b/packages/hoppscotch-selfhost-desktop/src/platform/history/history.platform.ts index fd0042a7..7189d693 100644 --- a/packages/hoppscotch-selfhost-desktop/src/platform/history/history.platform.ts +++ b/packages/hoppscotch-selfhost-desktop/src/platform/history/history.platform.ts @@ -18,9 +18,12 @@ import { import { HistoryPlatformDef } from "@hoppscotch/common/platform/history" import { getUserHistoryEntries, + getUserHistoryStore, + runUserHistoryAllDeletedSubscription, runUserHistoryCreatedSubscription, runUserHistoryDeletedManySubscription, runUserHistoryDeletedSubscription, + runUserHistoryStoreStatusChangedSubscription, runUserHistoryUpdatedSubscription, } from "./history.api" @@ -29,6 +32,7 @@ import { restHistorySyncer, gqlHistorySyncer } from "./history.sync" import { runGQLSubscription } from "@hoppscotch/common/helpers/backend/GQLClient" import { runDispatchWithOutSyncing } from "@lib/sync" import { ReqType } from "../../api/generated/graphql" +import { ref } from "vue" function initHistorySync() { const currentUser$ = platformAuth.getCurrentUserStream() @@ -38,9 +42,12 @@ function initHistorySync() { gqlHistorySyncer.startStoreSync() + getUserHistoryStatus() loadHistoryEntries() currentUser$.subscribe(async (user) => { + getUserHistoryStatus() + if (user) { await loadHistoryEntries() } @@ -64,12 +71,17 @@ function setupSubscriptions() { const userHistoryUpdatedSub = setupUserHistoryUpdatedSubscription() const userHistoryDeletedSub = setupUserHistoryDeletedSubscription() const userHistoryDeletedManySub = setupUserHistoryDeletedManySubscription() + const userHistoryStoreStatusChangedSub = + setupUserHistoryStoreStatusChangedSubscription() + const userHistoryAllDeletedSub = setupUserHistoryAllDeletedSubscription() subs = [ userHistoryCreatedSub, userHistoryUpdatedSub, userHistoryDeletedSub, userHistoryDeletedManySub, + userHistoryStoreStatusChangedSub, + userHistoryAllDeletedSub, ] return () => { @@ -109,6 +121,30 @@ async function loadHistoryEntries() { } } +async function getUserHistoryStatus() { + const currentUser = platformAuth.getCurrentUser() + + if (!currentUser) { + isHistoryStoreEnabled.value = true + return + } + + isFetchingHistoryStoreStatus.value = true + + const res = await getUserHistoryStore() + + if (E.isLeft(res)) { + hasErrorFetchingHistoryStoreStatus.value = true + isFetchingHistoryStoreStatus.value = false + return + } + + isHistoryStoreEnabled.value = + res.right.isUserHistoryEnabled.value === "ENABLE" + + isFetchingHistoryStoreStatus.value = false +} + function setupUserHistoryCreatedSubscription() { const [userHistoryCreated$, userHistoryCreatedSub] = runUserHistoryCreatedSubscription() @@ -256,6 +292,46 @@ function setupUserHistoryDeletedManySubscription() { return userHistoryDeletedManySub } +function setupUserHistoryStoreStatusChangedSubscription() { + const [userHistoryStoreStatusChanged$, userHistoryStoreStatusChangedSub] = + runUserHistoryStoreStatusChangedSubscription() + + userHistoryStoreStatusChanged$.subscribe((res) => { + if (E.isRight(res)) { + const status = res.right.infraConfigUpdate == "ENABLE" ? true : false + + isHistoryStoreEnabled.value = status + } + }) + + return userHistoryStoreStatusChangedSub +} + +function setupUserHistoryAllDeletedSubscription() { + const [userHistoryAllDeleted$, userHistoryAllDeletedSub] = + runUserHistoryAllDeletedSubscription() + + userHistoryAllDeleted$.subscribe((res) => { + if (E.isRight(res)) { + runDispatchWithOutSyncing(() => { + clearRESTHistory() + clearGraphqlHistory() + }) + } + }) + + return userHistoryAllDeletedSub +} + +export const isHistoryStoreEnabled = ref(false) +const isFetchingHistoryStoreStatus = ref(false) +const hasErrorFetchingHistoryStoreStatus = ref(false) + export const def: HistoryPlatformDef = { initHistorySync, + requestHistoryStore: { + isHistoryStoreEnabled, + isFetchingHistoryStoreStatus, + hasErrorFetchingHistoryStoreStatus, + }, } diff --git a/packages/hoppscotch-selfhost-web/src/api/queries/IsUserHistoryEnabled.graphql b/packages/hoppscotch-selfhost-web/src/api/queries/IsUserHistoryEnabled.graphql new file mode 100644 index 00000000..77bd9650 --- /dev/null +++ b/packages/hoppscotch-selfhost-web/src/api/queries/IsUserHistoryEnabled.graphql @@ -0,0 +1,6 @@ +query IsUserHistoryEnabled { + isUserHistoryEnabled { + name + value + } +} diff --git a/packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryAllDeleted.graphql b/packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryAllDeleted.graphql new file mode 100644 index 00000000..2e57592c --- /dev/null +++ b/packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryAllDeleted.graphql @@ -0,0 +1,3 @@ +subscription UserHistoryAllDeleted { + userHistoryAllDeleted +} diff --git a/packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql b/packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql new file mode 100644 index 00000000..bde1df55 --- /dev/null +++ b/packages/hoppscotch-selfhost-web/src/api/subscriptions/UserHistoryStoreStatusChanged.graphql @@ -0,0 +1,3 @@ +subscription UserHistoryStoreStatusChanged { + infraConfigUpdate(configName: USER_HISTORY_STORE_ENABLED) +} diff --git a/packages/hoppscotch-selfhost-web/src/platform/history/history.api.ts b/packages/hoppscotch-selfhost-web/src/platform/history/history.api.ts index 862f776f..0b8c4697 100644 --- a/packages/hoppscotch-selfhost-web/src/platform/history/history.api.ts +++ b/packages/hoppscotch-selfhost-web/src/platform/history/history.api.ts @@ -25,6 +25,11 @@ import { UserHistoryDeletedDocument, UserHistoryDeletedManyDocument, UserHistoryUpdatedDocument, + IsUserHistoryEnabledQuery, + IsUserHistoryEnabledQueryVariables, + IsUserHistoryEnabledDocument, + UserHistoryStoreStatusChangedDocument, + UserHistoryAllDeletedDocument, } from "../../api/generated/graphql" export const getUserHistoryEntries = () => @@ -33,6 +38,16 @@ export const getUserHistoryEntries = () => variables: {}, }) +export const getUserHistoryStore = () => + runGQLQuery< + IsUserHistoryEnabledQuery, + IsUserHistoryEnabledQueryVariables, + "" + >({ + query: IsUserHistoryEnabledDocument, + variables: {}, + }) + export const createUserHistory = ( reqData: string, resMetadata: string, @@ -98,3 +113,15 @@ export const runUserHistoryDeletedManySubscription = () => query: UserHistoryDeletedManyDocument, variables: {}, }) + +export const runUserHistoryStoreStatusChangedSubscription = () => + runGQLSubscription({ + query: UserHistoryStoreStatusChangedDocument, + variables: {}, + }) + +export const runUserHistoryAllDeletedSubscription = () => + runGQLSubscription({ + query: UserHistoryAllDeletedDocument, + variables: {}, + }) diff --git a/packages/hoppscotch-selfhost-web/src/platform/history/history.platform.ts b/packages/hoppscotch-selfhost-web/src/platform/history/history.platform.ts index 9e364e30..793761dc 100644 --- a/packages/hoppscotch-selfhost-web/src/platform/history/history.platform.ts +++ b/packages/hoppscotch-selfhost-web/src/platform/history/history.platform.ts @@ -18,9 +18,12 @@ import { import { HistoryPlatformDef } from "@hoppscotch/common/platform/history" import { getUserHistoryEntries, + getUserHistoryStore, + runUserHistoryAllDeletedSubscription, runUserHistoryCreatedSubscription, runUserHistoryDeletedManySubscription, runUserHistoryDeletedSubscription, + runUserHistoryStoreStatusChangedSubscription, runUserHistoryUpdatedSubscription, } from "./history.api" @@ -28,7 +31,8 @@ import * as E from "fp-ts/Either" import { restHistorySyncer, gqlHistorySyncer } from "./history.sync" import { runGQLSubscription } from "@hoppscotch/common/helpers/backend/GQLClient" import { runDispatchWithOutSyncing } from "@lib/sync" -import { ReqType } from "../../api/generated/graphql" +import { ReqType, ServiceStatus } from "../../api/generated/graphql" +import { ref } from "vue" function initHistorySync() { const currentUser$ = platformAuth.getCurrentUserStream() @@ -38,11 +42,14 @@ function initHistorySync() { gqlHistorySyncer.startStoreSync() + getUserHistoryStatus() loadHistoryEntries() currentUser$.subscribe(async (user) => { + getUserHistoryStatus() + if (user) { - await loadHistoryEntries() + loadHistoryEntries() } }) @@ -64,12 +71,17 @@ function setupSubscriptions() { const userHistoryUpdatedSub = setupUserHistoryUpdatedSubscription() const userHistoryDeletedSub = setupUserHistoryDeletedSubscription() const userHistoryDeletedManySub = setupUserHistoryDeletedManySubscription() + const userHistoryStoreStatusChangedSub = + setupUserHistoryStoreStatusChangedSubscription() + const userHistoryAllDeletedSub = setupUserHistoryAllDeletedSubscription() subs = [ userHistoryCreatedSub, userHistoryUpdatedSub, userHistoryDeletedSub, userHistoryDeletedManySub, + userHistoryStoreStatusChangedSub, + userHistoryAllDeletedSub, ] return () => { @@ -109,6 +121,30 @@ async function loadHistoryEntries() { } } +async function getUserHistoryStatus() { + const currentUser = platformAuth.getCurrentUser() + + if (!currentUser) { + isHistoryStoreEnabled.value = true + return + } + + isFetchingHistoryStoreStatus.value = true + + const res = await getUserHistoryStore() + + if (E.isLeft(res)) { + hasErrorFetchingHistoryStoreStatus.value = true + isFetchingHistoryStoreStatus.value = false + return + } + + isHistoryStoreEnabled.value = + res.right.isUserHistoryEnabled.value === ServiceStatus.Enable + + isFetchingHistoryStoreStatus.value = false +} + function setupUserHistoryCreatedSubscription() { const [userHistoryCreated$, userHistoryCreatedSub] = runUserHistoryCreatedSubscription() @@ -256,6 +292,47 @@ function setupUserHistoryDeletedManySubscription() { return userHistoryDeletedManySub } +function setupUserHistoryStoreStatusChangedSubscription() { + const [userHistoryStoreStatusChanged$, userHistoryStoreStatusChangedSub] = + runUserHistoryStoreStatusChangedSubscription() + + userHistoryStoreStatusChanged$.subscribe((res) => { + if (E.isRight(res)) { + const status = + res.right.infraConfigUpdate == ServiceStatus.Enable ? true : false + + isHistoryStoreEnabled.value = status + } + }) + + return userHistoryStoreStatusChangedSub +} + +function setupUserHistoryAllDeletedSubscription() { + const [userHistoryAllDeleted$, userHistoryAllDeletedSub] = + runUserHistoryAllDeletedSubscription() + + userHistoryAllDeleted$.subscribe((res) => { + if (E.isRight(res)) { + runDispatchWithOutSyncing(() => { + clearRESTHistory() + clearGraphqlHistory() + }) + } + }) + + return userHistoryAllDeletedSub +} + +export const isHistoryStoreEnabled = ref(false) +const isFetchingHistoryStoreStatus = ref(false) +const hasErrorFetchingHistoryStoreStatus = ref(false) + export const def: HistoryPlatformDef = { initHistorySync, + requestHistoryStore: { + isHistoryStoreEnabled, + isFetchingHistoryStoreStatus, + hasErrorFetchingHistoryStoreStatus, + }, } diff --git a/packages/hoppscotch-selfhost-web/src/platform/history/history.sync.ts b/packages/hoppscotch-selfhost-web/src/platform/history/history.sync.ts index 340c185a..50ffc2c1 100644 --- a/packages/hoppscotch-selfhost-web/src/platform/history/history.sync.ts +++ b/packages/hoppscotch-selfhost-web/src/platform/history/history.sync.ts @@ -22,10 +22,16 @@ import { } from "./history.api" import { ReqType } from "../../api/generated/graphql" +import { isHistoryStoreEnabled } from "./history.platform" + export const restHistoryStoreSyncDefinition: StoreSyncDefinitionOf< typeof restHistoryStore > = { async addEntry({ entry }) { + if (!isHistoryStoreEnabled.value) { + return + } + const res = await createUserHistory( JSON.stringify(entry.request), JSON.stringify(entry.responseMeta), @@ -58,6 +64,10 @@ export const gqlHistoryStoreSyncDefinition: StoreSyncDefinitionOf< typeof graphqlHistoryStore > = { async addEntry({ entry }) { + if (!isHistoryStoreEnabled.value) { + return + } + const res = await createUserHistory( JSON.stringify(entry.request), JSON.stringify(entry.response), diff --git a/packages/hoppscotch-sh-admin/locales/en.json b/packages/hoppscotch-sh-admin/locales/en.json index 86830c54..e7bcd817 100644 --- a/packages/hoppscotch-sh-admin/locales/en.json +++ b/packages/hoppscotch-sh-admin/locales/en.json @@ -58,6 +58,16 @@ "update_failure": "Failed to update smtp configurations!!", "user": "MAILER USER" }, + "history_configs": { + "description": "Disable or enable tracking history of sent requests from the Hoppscotch app", + "title": "History Configurations", + "enable_history": "Enable History", + "clear_history": "Clear existing history", + "clear_failure": "Failed to clear history!!", + "clear_success": "History cleared successfully.", + "toggle_failure": "Failed to toggle history!!", + "clear_confirm": "Are you sure you want to clear all history?" + }, "reset": { "confirm_reset": "Hoppscotch server must restart to reflect the new changes. Confirm the reset of server configurations?", "description": "Default configurations will be loaded as specified in the environment file", diff --git a/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue b/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue index c7f939ef..3bcc7e47 100644 --- a/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue +++ b/packages/hoppscotch-sh-admin/src/components/settings/Configurations.vue @@ -2,6 +2,7 @@
+
diff --git a/packages/hoppscotch-sh-admin/src/components/settings/HistoryConfiguration.vue b/packages/hoppscotch-sh-admin/src/components/settings/HistoryConfiguration.vue new file mode 100644 index 00000000..6f62dcf4 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/components/settings/HistoryConfiguration.vue @@ -0,0 +1,104 @@ + + + diff --git a/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue b/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue index 641ec1e3..100cd836 100644 --- a/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue +++ b/packages/hoppscotch-sh-admin/src/components/settings/ServerRestart.vue @@ -23,6 +23,7 @@ import { ResetInfraConfigsDocument, ToggleAnalyticsCollectionDocument, ToggleSmtpDocument, + ToggleUserHistoryStoreDocument, UpdateInfraConfigsDocument, } from '~/helpers/backend/graphql'; import { ServerConfigs } from '~/helpers/configs'; @@ -55,6 +56,10 @@ const toggleDataSharingMutation = useMutation( ); const toggleSMTPMutation = useMutation(ToggleSmtpDocument); +const toggleUserHistoryStoreMutation = useMutation( + ToggleUserHistoryStoreDocument +); + // Mutation handlers const { updateInfraConfigs, @@ -62,6 +67,7 @@ const { resetInfraConfigs, updateDataSharingConfigs, toggleSMTPConfigs, + toggleUserHistoryStore, } = useConfigHandler(props.workingConfigs); // Call relevant mutations on component mount and initiate server restart @@ -120,6 +126,14 @@ onMounted(async () => { if (!smtpResult) { return triggerComponentUnMount(); } + + const userHistoryStoreResult = await toggleUserHistoryStore( + toggleUserHistoryStoreMutation + ); + + if (!userHistoryStoreResult) { + return triggerComponentUnMount(); + } } restart.value = true; diff --git a/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts b/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts index 81ff83b4..a5bf7198 100644 --- a/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts +++ b/packages/hoppscotch-sh-admin/src/composables/useConfigHandler.ts @@ -14,6 +14,7 @@ import { ServiceStatus, ToggleAnalyticsCollectionMutation, ToggleSmtpMutation, + ToggleUserHistoryStoreMutation, UpdateInfraConfigsMutation, } from '~/helpers/backend/graphql'; import { @@ -141,6 +142,14 @@ export function useConfigHandler(updatedConfigs?: ServerConfigs) { (x) => x.name === 'ALLOW_ANALYTICS_COLLECTION' && x.value === 'true' ), }, + historyConfig: { + name: 'history_settings', + enabled: !!infraConfigs.value.find( + (config) => + config.name === 'USER_HISTORY_STORE_ENABLED' && + config.value === 'ENABLE' + ), + }, }; // Cloning the current configs to working configs @@ -384,12 +393,27 @@ export function useConfigHandler(updatedConfigs?: ServerConfigs) { 'configs.mail_configs.toggle_failure' ); + // Toggle User History Store + const toggleUserHistoryStore = ( + toggleUserHistoryStore: UseMutationResponse + ) => + executeMutation( + toggleUserHistoryStore, + { + status: updatedConfigs?.historyConfig.enabled + ? ServiceStatus.Enable + : ServiceStatus.Disable, + }, + 'configs.user_history_store.toggle_failure' + ); + return { currentConfigs, workingConfigs, updateAuthProvider, updateDataSharingConfigs, toggleSMTPConfigs, + toggleUserHistoryStore, updateInfraConfigs, resetInfraConfigs, fetchingInfraConfigs, diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/RevokeAllUserHistoryByAdmin.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/RevokeAllUserHistoryByAdmin.graphql new file mode 100644 index 00000000..e2251828 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/RevokeAllUserHistoryByAdmin.graphql @@ -0,0 +1,3 @@ +mutation RevokeAllUserHistoryByAdmin { + revokeAllUserHistoryByAdmin +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ToggleUserHistoryStore.graphql b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ToggleUserHistoryStore.graphql new file mode 100644 index 00000000..fa0e6375 --- /dev/null +++ b/packages/hoppscotch-sh-admin/src/helpers/backend/gql/mutations/ToggleUserHistoryStore.graphql @@ -0,0 +1,3 @@ +mutation ToggleUserHistoryStore($status: ServiceStatus!) { + toggleUserHistoryStore(status: $status) +} diff --git a/packages/hoppscotch-sh-admin/src/helpers/configs.ts b/packages/hoppscotch-sh-admin/src/helpers/configs.ts index a57cafdf..08ee88df 100644 --- a/packages/hoppscotch-sh-admin/src/helpers/configs.ts +++ b/packages/hoppscotch-sh-admin/src/helpers/configs.ts @@ -54,6 +54,11 @@ export type ServerConfigs = { }; }; + historyConfig: { + name: string; + enabled: boolean; + }; + dataSharingConfigs: { name: string; enabled: boolean; @@ -195,6 +200,13 @@ const DATA_SHARING_CONFIGS: Omit[] = [ }, ]; +export const HISTORY_STORE_CONFIG: Config[] = [ + { + name: InfraConfigEnum.UserHistoryStoreEnabled, + key: 'history_store_enabled', + }, +]; + export const ALL_CONFIGS = [ GOOGLE_CONFIGS, MICROSOFT_CONFIGS, @@ -202,4 +214,5 @@ export const ALL_CONFIGS = [ MAIL_CONFIGS, CUSTOM_MAIL_CONFIGS, DATA_SHARING_CONFIGS, + HISTORY_STORE_CONFIG, ];