Self-review (cont'd)
parent
7e38419cdb
commit
b026e45189
|
@ -42,6 +42,7 @@ import (
|
||||||
- HIGH Self-review
|
- HIGH Self-review
|
||||||
- MEDIUM: Test for expiring messages after reservation removal
|
- MEDIUM: Test for expiring messages after reservation removal
|
||||||
- MEDIUM: Test new token endpoints & never-expiring token
|
- MEDIUM: Test new token endpoints & never-expiring token
|
||||||
|
- MEDIUM: Tests for manager.go
|
||||||
- LOW: UI: Flickering upgrade banner when logging in
|
- LOW: UI: Flickering upgrade banner when logging in
|
||||||
- LOW: Menu item -> popup click should not open page
|
- LOW: Menu item -> popup click should not open page
|
||||||
- LOW: get rid of reservation id, replace with DELETE X-Topic: ...
|
- LOW: get rid of reservation id, replace with DELETE X-Topic: ...
|
||||||
|
|
|
@ -121,11 +121,8 @@ func (s *Server) handleAccountBillingSubscriptionCreate(w http.ResponseWriter, r
|
||||||
return errNotAPaidTier
|
return errNotAPaidTier
|
||||||
}
|
}
|
||||||
logvr(v, r).
|
logvr(v, r).
|
||||||
|
With(tier).
|
||||||
Tag(tagStripe).
|
Tag(tagStripe).
|
||||||
Fields(log.Context{
|
|
||||||
"tier": tier,
|
|
||||||
"stripe_price_id": tier.StripePriceID,
|
|
||||||
}).
|
|
||||||
Info("Creating Stripe checkout flow")
|
Info("Creating Stripe checkout flow")
|
||||||
var stripeCustomerID *string
|
var stripeCustomerID *string
|
||||||
if u.Billing.StripeCustomerID != "" {
|
if u.Billing.StripeCustomerID != "" {
|
||||||
|
@ -196,11 +193,9 @@ func (s *Server) handleAccountBillingSubscriptionCreateSuccess(w http.ResponseWr
|
||||||
}
|
}
|
||||||
v.SetUser(u)
|
v.SetUser(u)
|
||||||
logvr(v, r).
|
logvr(v, r).
|
||||||
|
With(tier).
|
||||||
Tag(tagStripe).
|
Tag(tagStripe).
|
||||||
Fields(log.Context{
|
Fields(log.Context{
|
||||||
"tier_id": tier.ID,
|
|
||||||
"tier_name": tier.Name,
|
|
||||||
"stripe_price_id": tier.StripePriceID,
|
|
||||||
"stripe_customer_id": sess.Customer.ID,
|
"stripe_customer_id": sess.Customer.ID,
|
||||||
"stripe_subscription_id": sub.ID,
|
"stripe_subscription_id": sub.ID,
|
||||||
"stripe_subscription_status": string(sub.Status),
|
"stripe_subscription_status": string(sub.Status),
|
||||||
|
@ -273,7 +268,8 @@ func (s *Server) handleAccountBillingSubscriptionUpdate(w http.ResponseWriter, r
|
||||||
}
|
}
|
||||||
|
|
||||||
// handleAccountBillingSubscriptionDelete facilitates downgrading a paid user to a tier-less user,
|
// handleAccountBillingSubscriptionDelete facilitates downgrading a paid user to a tier-less user,
|
||||||
// and cancelling the Stripe subscription entirely
|
// and cancelling the Stripe subscription entirely. Note that this does not actually change the tier.
|
||||||
|
// That is done by a webhook at the period end (in X days).
|
||||||
func (s *Server) handleAccountBillingSubscriptionDelete(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
func (s *Server) handleAccountBillingSubscriptionDelete(w http.ResponseWriter, r *http.Request, v *visitor) error {
|
||||||
logvr(v, r).Tag(tagStripe).Info("Deleting Stripe subscription")
|
logvr(v, r).Tag(tagStripe).Info("Deleting Stripe subscription")
|
||||||
u := v.User()
|
u := v.User()
|
||||||
|
|
|
@ -3,6 +3,7 @@ package user
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/stripe/stripe-go/v74"
|
"github.com/stripe/stripe-go/v74"
|
||||||
|
"heckel.io/ntfy/log"
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"regexp"
|
"regexp"
|
||||||
"time"
|
"time"
|
||||||
|
@ -92,6 +93,14 @@ type Tier struct {
|
||||||
StripePriceID string // Price ID for paid tiers (price_...)
|
StripePriceID string // Price ID for paid tiers (price_...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Tier) Context() log.Context {
|
||||||
|
return log.Context{
|
||||||
|
"tier_id": t.ID,
|
||||||
|
"tier_name": t.Name,
|
||||||
|
"stripe_price_id": t.StripePriceID,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Subscription represents a user's topic subscription
|
// Subscription represents a user's topic subscription
|
||||||
type Subscription struct {
|
type Subscription struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"login_title": "Sign in to your ntfy account",
|
"login_title": "Sign in to your ntfy account",
|
||||||
"login_form_button_submit": "Sign in",
|
"login_form_button_submit": "Sign in",
|
||||||
"login_link_signup": "Sign up",
|
"login_link_signup": "Sign up",
|
||||||
|
"login_disabled": "Login is disabled",
|
||||||
"action_bar_show_menu": "Show menu",
|
"action_bar_show_menu": "Show menu",
|
||||||
"action_bar_logo_alt": "ntfy logo",
|
"action_bar_logo_alt": "ntfy logo",
|
||||||
"action_bar_settings": "Settings",
|
"action_bar_settings": "Settings",
|
||||||
|
@ -46,6 +47,8 @@
|
||||||
"nav_button_subscribe": "Subscribe to topic",
|
"nav_button_subscribe": "Subscribe to topic",
|
||||||
"nav_button_muted": "Notifications muted",
|
"nav_button_muted": "Notifications muted",
|
||||||
"nav_button_connecting": "connecting",
|
"nav_button_connecting": "connecting",
|
||||||
|
"nav_upgrade_banner_label": "Upgrade to ntfy Pro",
|
||||||
|
"nav_upgrade_banner_description": "Reserve topics, more messages & emails, and larger attachments",
|
||||||
"alert_grant_title": "Notifications are disabled",
|
"alert_grant_title": "Notifications are disabled",
|
||||||
"alert_grant_description": "Grant your browser permission to display desktop notifications.",
|
"alert_grant_description": "Grant your browser permission to display desktop notifications.",
|
||||||
"alert_grant_button": "Grant now",
|
"alert_grant_button": "Grant now",
|
||||||
|
|
|
@ -43,7 +43,7 @@ const Login = () => {
|
||||||
if (!config.enable_login) {
|
if (!config.enable_login) {
|
||||||
return (
|
return (
|
||||||
<AvatarBox>
|
<AvatarBox>
|
||||||
<Typography sx={{ typography: 'h6' }}>{t("Login is disabled")}</Typography>
|
<Typography sx={{ typography: 'h6' }}>{t("login_disabled")}</Typography>
|
||||||
</AvatarBox>
|
</AvatarBox>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,6 +177,7 @@ const NavList = (props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const UpgradeBanner = () => {
|
const UpgradeBanner = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
const [dialogKey, setDialogKey] = useState(0);
|
const [dialogKey, setDialogKey] = useState(0);
|
||||||
const [dialogOpen, setDialogOpen] = useState(false);
|
const [dialogOpen, setDialogOpen] = useState(false);
|
||||||
|
|
||||||
|
@ -198,8 +199,8 @@ const UpgradeBanner = () => {
|
||||||
<ListItemIcon><CelebrationIcon sx={{ color: "#55b86e" }} fontSize="large"/></ListItemIcon>
|
<ListItemIcon><CelebrationIcon sx={{ color: "#55b86e" }} fontSize="large"/></ListItemIcon>
|
||||||
<ListItemText
|
<ListItemText
|
||||||
sx={{ ml: 1 }}
|
sx={{ ml: 1 }}
|
||||||
primary={"Upgrade to ntfy Pro"}
|
primary={t("nav_upgrade_banner_label")}
|
||||||
secondary={"Reserve topics, more messages & emails, and larger attachments"}
|
secondary={t("nav_upgrade_banner_description")}
|
||||||
primaryTypographyProps={{
|
primaryTypographyProps={{
|
||||||
style: {
|
style: {
|
||||||
fontWeight: 500,
|
fontWeight: 500,
|
||||||
|
|
Loading…
Reference in New Issue