pathes
Build self-hosted HTTP Toolkit / build (linux-x64, ubuntu-latest, true) (push) Canceled after 0s
Build self-hosted HTTP Toolkit / build (macos-arm64, macos-latest, true) (push) Canceled after 0s
Build self-hosted HTTP Toolkit / build (windows-x64, windows-latest, false) (push) Canceled after 0s
Build self-hosted HTTP Toolkit / release (push) Canceled after 0s

This commit is contained in:
2026-08-15 01:59:20 +05:00
commit aeb59e8eda
16 changed files with 862 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
diff --git a/src/model/account/account-store.ts b/src/model/account/account-store.ts
index c5595776..5c05538a 100644
--- a/src/model/account/account-store.ts
+++ b/src/model/account/account-store.ts
@@ -28,6 +28,27 @@ import {
// Fund open source - if you want Pro, help pay for its development.
// Can't afford it? Get in touch: tim@httptoolkit.com.
// ------------------------------------------------------------------
+
+// Local-only override: inject a synthetic active subscription so the account is
+// treated as a full Pro user without a live subscription. We set the underlying
+// data (rather than overriding isPaidUser() etc.) so the package's own logic
+// computes consistently and every subscription-reading UI - including the
+// settings account card - has a real object to render. Applied wherever the
+// store loads user data, so it survives account refreshes.
+const forceProUser = (user: User): User => {
+ user.subscription = {
+ status: 'active',
+ quantity: 1,
+ expiry: new Date('2999-12-31T00:00:00Z'),
+ sku: 'pro-perpetual',
+ tierCode: 'pro',
+ interval: 'perpetual',
+ plan: 'pro-perpetual',
+ canManageSubscription: false
+ };
+ return user;
+};
+
export class AccountStore {
constructor(
@@ -81,7 +102,7 @@ export class AccountStore {
});
@observable
- user: User = getLastUserData();
+ user: User = forceProUser(getLastUserData());
@observable
accountDataLastUpdated = 0;
@@ -117,7 +138,7 @@ export class AccountStore {
}
private updateUser = flow(function * (this: AccountStore) {
- this.user = yield getLatestUserData();
+ this.user = forceProUser(yield getLatestUserData());
this.accountDataLastUpdated = Date.now();
// Include the user id in error reports whilst they're logged in.
@@ -0,0 +1,140 @@
diff --git a/src/components/settings/settings-page.tsx b/src/components/settings/settings-page.tsx
index ab867e9f..dae383cf 100644
--- a/src/components/settings/settings-page.tsx
+++ b/src/components/settings/settings-page.tsx
@@ -142,135 +142,10 @@ class SettingsPage extends React.Component<SettingsPageProps> {
</SettingsPagePlaceholder>;
}
- // ! because we know this is set, as we have a paid user
- const sub = userSubscription!;
-
return <SettingsPageScrollContainer>
<SettingPageContainer>
<SettingsHeading>Settings</SettingsHeading>
- <CollapsibleCard {...cardProps.account}>
- <header>
- <CollapsibleCardHeading onCollapseToggled={
- cardProps.account.onCollapseToggled
- }>
- Account
- </CollapsibleCardHeading>
- </header>
- <AccountDetailsContainer>
- <ContentLabel>
- Account email
- </ContentLabel>
- <ContentValue>
- { userEmail }
- </ContentValue>
-
- <ContentLabel>
- Subscription status
- </ContentLabel>
- <ContentValue>
- {
- ({
- 'active': 'Active',
- 'trialing': 'Active (trial)',
- 'past_due': <strong
- title={dedent`
- Your subscription payment failed, and will be reattempted.
- If retried payments fail your subscription will be cancelled.
- `}
- >Past due <WarningIcon /></strong>,
- 'deleted': sub.expiry && isFuture(sub.expiry)
- ? `Active (until ${sub.expiry.toLocaleDateString()})`
- : 'Cancelled'
- }[sub.status]) || 'Unknown'
- }
- { isAccountUpdateInProcess &&
- <AccountUpdateSpinner />
- }
- </ContentValue>
-
- <ContentLabel>
- Subscription plan
- </ContentLabel>
- <ContentValue>
- {
- subscriptionPlans.state === 'fulfilled'
- ? (subscriptionPlans.value as SubscriptionPlans)[sub.sku]?.name
- // If the accounts API is unavailable for plan metadata for some reason, we can just
- // format the raw SKU to get something workable, no worries:
- : _.startCase(sub.sku)
- }
- </ContentValue>
-
- <ContentLabel>
- {
- ({
- 'active': 'Next renews',
- 'trialing': 'Renews',
- 'past_due': 'Next payment attempt',
- 'deleted': 'Ends',
- }[sub.status]) || 'Current period ends'
- }
- </ContentLabel>
- <ContentValue>
- {
- distanceInWordsStrict(new Date(), sub.expiry, {
- addSuffix: true,
- partialMethod: 'round'
- })
- } ({
- format(sub.expiry.toString(), 'Do [of] MMMM YYYY')
- })
- </ContentValue>
- </AccountDetailsContainer>
-
- <AccountControls>
- { sub.lastReceiptUrl &&
- <SettingsButtonLink
- href={ sub.lastReceiptUrl }
- target='_blank'
- rel='noreferrer noopener'
- >
- View latest invoice
- </SettingsButtonLink>
- }
- { canManageSubscription && <>
- { sub.updateBillingDetailsUrl &&
- <SettingsButtonLink
- href={sub.updateBillingDetailsUrl}
- target='_blank'
- rel='noreferrer noopener'
- highlight={sub.status === 'past_due'}
- >
- Update billing details
- </SettingsButtonLink>
- }
- <SettingsButton
- onClick={this.confirmSubscriptionCancellation}
- disabled={isAccountUpdateInProcess}
- >
- Cancel subscription
- { isAccountUpdateInProcess &&
- <AccountUpdateSpinner />
- }
- </SettingsButton>
- </> }
- <SettingsButton onClick={logOut}>Log out</SettingsButton>
- </AccountControls>
-
- <AccountContactFooter>
- Questions? Email <strong>billing@httptoolkit.com</strong>
- </AccountContactFooter>
- </CollapsibleCard>
-
- {/*
- The above shows for both active paid users, and recently paid users whose most recent
- payments failed. For those users, we drop other Pro features, but keep the settings
- UI so they can easily log out, update billing details or cancel fully.
-
- The rest is active paid users only:
- */}
-
{ user.isPaidUser() && <>
{
_.isString(serverVersion.value) &&
@@ -0,0 +1,23 @@
diff --git a/src/components/app.tsx b/src/components/app.tsx
index 0fbf3e39..805c08a6 100644
--- a/src/components/app.tsx
+++ b/src/components/app.tsx
@@ -212,17 +212,7 @@ class App extends React.Component<{
onClick: this.props.uiStore.openMcpModal
}]
: []
- ),
-
- {
- name: 'Give feedback',
- title: "Suggest features or report issues",
- icon: 'ChatText',
- position: 'bottom',
- highlight: true,
- type: 'web',
- url: 'https://github.com/httptoolkit/httptoolkit/issues/new/choose'
- }
+ )
] as SidebarItem[];
}