More self-review
parent
ac029c389e
commit
92c384374a
2
go.sum
2
go.sum
|
@ -2,8 +2,6 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
|
cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA=
|
||||||
cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
|
cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
|
||||||
cloud.google.com/go/compute v1.19.2 h1:GbJtPo8OKVHbVep8jvM57KidbYHxeE68LOVqouNLrDY=
|
|
||||||
cloud.google.com/go/compute v1.19.2/go.mod h1:5f5a+iC1IriXYauaQ0EyQmEAEq9CGRnV5xJSQSlTV08=
|
|
||||||
cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds=
|
cloud.google.com/go/compute v1.19.3 h1:DcTwsFgGev/wV5+q8o2fzgcHOaac+DKGC91ZlvpsQds=
|
||||||
cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI=
|
cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
|
|
|
@ -550,6 +550,7 @@ func (s *Server) handleWebConfig(w http.ResponseWriter, _ *http.Request, _ *visi
|
||||||
EnableSignup: s.config.EnableSignup,
|
EnableSignup: s.config.EnableSignup,
|
||||||
EnablePayments: s.config.StripeSecretKey != "",
|
EnablePayments: s.config.StripeSecretKey != "",
|
||||||
EnableCalls: s.config.TwilioAccount != "",
|
EnableCalls: s.config.TwilioAccount != "",
|
||||||
|
EnableEmails: s.config.SMTPSenderFrom != "",
|
||||||
EnableReservations: s.config.EnableReservations,
|
EnableReservations: s.config.EnableReservations,
|
||||||
BillingContact: s.config.BillingContact,
|
BillingContact: s.config.BillingContact,
|
||||||
DisallowedTopics: s.config.DisallowedTopics,
|
DisallowedTopics: s.config.DisallowedTopics,
|
||||||
|
@ -911,7 +912,7 @@ func (s *Server) parsePublishParams(r *http.Request, m *message) (cache bool, fi
|
||||||
return false, false, "", "", false, errHTTPBadRequestEmailDisabled
|
return false, false, "", "", false, errHTTPBadRequestEmailDisabled
|
||||||
}
|
}
|
||||||
call = readParam(r, "x-call", "call")
|
call = readParam(r, "x-call", "call")
|
||||||
if call != "" && s.config.TwilioAccount == "" && s.userManager == nil {
|
if call != "" && (s.config.TwilioAccount == "" || s.userManager == nil) {
|
||||||
return false, false, "", "", false, errHTTPBadRequestPhoneCallsDisabled
|
return false, false, "", "", false, errHTTPBadRequestPhoneCallsDisabled
|
||||||
} else if call != "" && !isBoolValue(call) && !phoneNumberRegex.MatchString(call) {
|
} else if call != "" && !isBoolValue(call) && !phoneNumberRegex.MatchString(call) {
|
||||||
return false, false, "", "", false, errHTTPBadRequestPhoneNumberInvalid
|
return false, false, "", "", false, errHTTPBadRequestPhoneNumberInvalid
|
||||||
|
|
|
@ -146,6 +146,11 @@
|
||||||
|
|
||||||
# If enabled, ntfy can perform voice calls via Twilio via the "X-Call" header.
|
# If enabled, ntfy can perform voice calls via Twilio via the "X-Call" header.
|
||||||
#
|
#
|
||||||
|
# - twilio-account is the Twilio account SID, e.g. AC12345beefbeef67890beefbeef122586
|
||||||
|
# - twilio-auth-token is the Twilio auth token, e.g. affebeef258625862586258625862586
|
||||||
|
# - twilio-from-number is the outgoing phone number you purchased, e.g. +18775132586
|
||||||
|
# - twilio-verify-service is the Twilio Verify service SID, e.g. VA12345beefbeef67890beefbeef122586
|
||||||
|
#
|
||||||
# twilio-account:
|
# twilio-account:
|
||||||
# twilio-auth-token:
|
# twilio-auth-token:
|
||||||
# twilio-from-number:
|
# twilio-from-number:
|
||||||
|
|
|
@ -108,17 +108,19 @@ func (s *Server) handleAccountGet(w http.ResponseWriter, r *http.Request, v *vis
|
||||||
CancelAt: u.Billing.StripeSubscriptionCancelAt.Unix(),
|
CancelAt: u.Billing.StripeSubscriptionCancelAt.Unix(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reservations, err := s.userManager.Reservations(u.Name)
|
if s.config.EnableReservations {
|
||||||
if err != nil {
|
reservations, err := s.userManager.Reservations(u.Name)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
if len(reservations) > 0 {
|
}
|
||||||
response.Reservations = make([]*apiAccountReservation, 0)
|
if len(reservations) > 0 {
|
||||||
for _, r := range reservations {
|
response.Reservations = make([]*apiAccountReservation, 0)
|
||||||
response.Reservations = append(response.Reservations, &apiAccountReservation{
|
for _, r := range reservations {
|
||||||
Topic: r.Topic,
|
response.Reservations = append(response.Reservations, &apiAccountReservation{
|
||||||
Everyone: r.Everyone.String(),
|
Topic: r.Topic,
|
||||||
})
|
Everyone: r.Everyone.String(),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokens, err := s.userManager.Tokens(u.ID)
|
tokens, err := s.userManager.Tokens(u.ID)
|
||||||
|
@ -141,12 +143,14 @@ func (s *Server) handleAccountGet(w http.ResponseWriter, r *http.Request, v *vis
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
phoneNumbers, err := s.userManager.PhoneNumbers(u.ID)
|
if s.config.TwilioAccount != "" {
|
||||||
if err != nil {
|
phoneNumbers, err := s.userManager.PhoneNumbers(u.ID)
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
if len(phoneNumbers) > 0 {
|
}
|
||||||
response.PhoneNumbers = phoneNumbers
|
if len(phoneNumbers) > 0 {
|
||||||
|
response.PhoneNumbers = phoneNumbers
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
response.Username = user.Everyone
|
response.Username = user.Everyone
|
||||||
|
|
|
@ -151,6 +151,8 @@ func TestAccount_Get_Anonymous(t *testing.T) {
|
||||||
require.Equal(t, int64(1004), account.Stats.MessagesRemaining)
|
require.Equal(t, int64(1004), account.Stats.MessagesRemaining)
|
||||||
require.Equal(t, int64(0), account.Stats.Emails)
|
require.Equal(t, int64(0), account.Stats.Emails)
|
||||||
require.Equal(t, int64(24), account.Stats.EmailsRemaining)
|
require.Equal(t, int64(24), account.Stats.EmailsRemaining)
|
||||||
|
require.Equal(t, int64(0), account.Stats.Calls)
|
||||||
|
require.Equal(t, int64(0), account.Stats.CallsRemaining)
|
||||||
|
|
||||||
rr = request(t, s, "POST", "/mytopic", "", nil)
|
rr = request(t, s, "POST", "/mytopic", "", nil)
|
||||||
require.Equal(t, 200, rr.Code)
|
require.Equal(t, 200, rr.Code)
|
||||||
|
@ -498,6 +500,8 @@ func TestAccount_Reservation_AddAdminSuccess(t *testing.T) {
|
||||||
func TestAccount_Reservation_AddRemoveUserWithTierSuccess(t *testing.T) {
|
func TestAccount_Reservation_AddRemoveUserWithTierSuccess(t *testing.T) {
|
||||||
conf := newTestConfigWithAuthFile(t)
|
conf := newTestConfigWithAuthFile(t)
|
||||||
conf.EnableSignup = true
|
conf.EnableSignup = true
|
||||||
|
conf.EnableReservations = true
|
||||||
|
conf.TwilioAccount = "dummy"
|
||||||
s := newTestServer(t, conf)
|
s := newTestServer(t, conf)
|
||||||
|
|
||||||
// Create user
|
// Create user
|
||||||
|
@ -510,6 +514,7 @@ func TestAccount_Reservation_AddRemoveUserWithTierSuccess(t *testing.T) {
|
||||||
MessageLimit: 123,
|
MessageLimit: 123,
|
||||||
MessageExpiryDuration: 86400 * time.Second,
|
MessageExpiryDuration: 86400 * time.Second,
|
||||||
EmailLimit: 32,
|
EmailLimit: 32,
|
||||||
|
CallLimit: 10,
|
||||||
ReservationLimit: 2,
|
ReservationLimit: 2,
|
||||||
AttachmentFileSizeLimit: 1231231,
|
AttachmentFileSizeLimit: 1231231,
|
||||||
AttachmentTotalSizeLimit: 123123,
|
AttachmentTotalSizeLimit: 123123,
|
||||||
|
@ -551,6 +556,7 @@ func TestAccount_Reservation_AddRemoveUserWithTierSuccess(t *testing.T) {
|
||||||
require.Equal(t, int64(123), account.Limits.Messages)
|
require.Equal(t, int64(123), account.Limits.Messages)
|
||||||
require.Equal(t, int64(86400), account.Limits.MessagesExpiryDuration)
|
require.Equal(t, int64(86400), account.Limits.MessagesExpiryDuration)
|
||||||
require.Equal(t, int64(32), account.Limits.Emails)
|
require.Equal(t, int64(32), account.Limits.Emails)
|
||||||
|
require.Equal(t, int64(10), account.Limits.Calls)
|
||||||
require.Equal(t, int64(2), account.Limits.Reservations)
|
require.Equal(t, int64(2), account.Limits.Reservations)
|
||||||
require.Equal(t, int64(1231231), account.Limits.AttachmentFileSize)
|
require.Equal(t, int64(1231231), account.Limits.AttachmentFileSize)
|
||||||
require.Equal(t, int64(123123), account.Limits.AttachmentTotalSize)
|
require.Equal(t, int64(123123), account.Limits.AttachmentTotalSize)
|
||||||
|
|
|
@ -1194,7 +1194,7 @@ func TestServer_PublishDelayedEmail_Fail(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_PublishDelayedCall_Fail(t *testing.T) {
|
func TestServer_PublishDelayedCall_Fail(t *testing.T) {
|
||||||
c := newTestConfig(t)
|
c := newTestConfigWithAuthFile(t)
|
||||||
c.TwilioAccount = "AC1234567890"
|
c.TwilioAccount = "AC1234567890"
|
||||||
c.TwilioAuthToken = "AAEAA1234567890"
|
c.TwilioAuthToken = "AAEAA1234567890"
|
||||||
c.TwilioFromNumber = "+1234567890"
|
c.TwilioFromNumber = "+1234567890"
|
||||||
|
|
|
@ -228,7 +228,7 @@ func TestServer_Twilio_Call_UnverifiedNumber(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_Twilio_Call_InvalidNumber(t *testing.T) {
|
func TestServer_Twilio_Call_InvalidNumber(t *testing.T) {
|
||||||
c := newTestConfig(t)
|
c := newTestConfigWithAuthFile(t)
|
||||||
c.TwilioCallsBaseURL = "https://127.0.0.1"
|
c.TwilioCallsBaseURL = "https://127.0.0.1"
|
||||||
c.TwilioAccount = "AC1234567890"
|
c.TwilioAccount = "AC1234567890"
|
||||||
c.TwilioAuthToken = "AAEAA1234567890"
|
c.TwilioAuthToken = "AAEAA1234567890"
|
||||||
|
@ -242,7 +242,7 @@ func TestServer_Twilio_Call_InvalidNumber(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServer_Twilio_Call_Anonymous(t *testing.T) {
|
func TestServer_Twilio_Call_Anonymous(t *testing.T) {
|
||||||
c := newTestConfig(t)
|
c := newTestConfigWithAuthFile(t)
|
||||||
c.TwilioCallsBaseURL = "https://127.0.0.1"
|
c.TwilioCallsBaseURL = "https://127.0.0.1"
|
||||||
c.TwilioAccount = "AC1234567890"
|
c.TwilioAccount = "AC1234567890"
|
||||||
c.TwilioAuthToken = "AAEAA1234567890"
|
c.TwilioAuthToken = "AAEAA1234567890"
|
||||||
|
|
|
@ -394,6 +394,7 @@ type apiConfigResponse struct {
|
||||||
EnableSignup bool `json:"enable_signup"`
|
EnableSignup bool `json:"enable_signup"`
|
||||||
EnablePayments bool `json:"enable_payments"`
|
EnablePayments bool `json:"enable_payments"`
|
||||||
EnableCalls bool `json:"enable_calls"`
|
EnableCalls bool `json:"enable_calls"`
|
||||||
|
EnableEmails bool `json:"enable_emails"`
|
||||||
EnableReservations bool `json:"enable_reservations"`
|
EnableReservations bool `json:"enable_reservations"`
|
||||||
BillingContact string `json:"billing_contact"`
|
BillingContact string `json:"billing_contact"`
|
||||||
DisallowedTopics []string `json:"disallowed_topics"`
|
DisallowedTopics []string `json:"disallowed_topics"`
|
||||||
|
|
|
@ -16262,16 +16262,16 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.0.4",
|
"version": "4.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||||
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||||
"peer": true,
|
"peer": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
"tsserver": "bin/tsserver"
|
"tsserver": "bin/tsserver"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=12.20"
|
"node": ">=4.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/unbox-primitive": {
|
"node_modules/unbox-primitive": {
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
// During web development, you may change values here for rapid testing.
|
// During web development, you may change values here for rapid testing.
|
||||||
|
|
||||||
var config = {
|
var config = {
|
||||||
base_url: "http://127.0.0.1:2586",// FIXME window.location.origin, // Change to test against a different server
|
base_url: window.location.origin, // Change to test against a different server
|
||||||
app_root: "/app",
|
app_root: "/app",
|
||||||
enable_login: true,
|
enable_login: true,
|
||||||
enable_signup: true,
|
enable_signup: true,
|
||||||
enable_payments: true,
|
enable_payments: true,
|
||||||
enable_reservations: true,
|
enable_reservations: true,
|
||||||
|
enable_emails: true,
|
||||||
enable_calls: true,
|
enable_calls: true,
|
||||||
billing_contact: "",
|
billing_contact: "",
|
||||||
disallowed_topics: ["docs", "static", "file", "app", "account", "settings", "signup", "login", "v1"]
|
disallowed_topics: ["docs", "static", "file", "app", "account", "settings", "signup", "login", "v1"]
|
||||||
|
|
|
@ -571,22 +571,24 @@ const Stats = () => {
|
||||||
value={account.role === Role.USER ? normalize(account.stats.messages, account.limits.messages) : 100}
|
value={account.role === Role.USER ? normalize(account.stats.messages, account.limits.messages) : 100}
|
||||||
/>
|
/>
|
||||||
</Pref>
|
</Pref>
|
||||||
<Pref title={
|
{config.enable_emails &&
|
||||||
<>
|
<Pref title={
|
||||||
{t("account_usage_emails_title")}
|
<>
|
||||||
<Tooltip title={t("account_usage_limits_reset_daily")}><span><InfoIcon/></span></Tooltip>
|
{t("account_usage_emails_title")}
|
||||||
</>
|
<Tooltip title={t("account_usage_limits_reset_daily")}><span><InfoIcon/></span></Tooltip>
|
||||||
}>
|
</>
|
||||||
<div>
|
}>
|
||||||
<Typography variant="body2" sx={{float: "left"}}>{account.stats.emails.toLocaleString()}</Typography>
|
<div>
|
||||||
<Typography variant="body2" sx={{float: "right"}}>{account.role === Role.USER ? t("account_usage_of_limit", { limit: account.limits.emails.toLocaleString() }) : t("account_usage_unlimited")}</Typography>
|
<Typography variant="body2" sx={{float: "left"}}>{account.stats.emails.toLocaleString()}</Typography>
|
||||||
</div>
|
<Typography variant="body2" sx={{float: "right"}}>{account.role === Role.USER ? t("account_usage_of_limit", { limit: account.limits.emails.toLocaleString() }) : t("account_usage_unlimited")}</Typography>
|
||||||
<LinearProgress
|
</div>
|
||||||
variant="determinate"
|
<LinearProgress
|
||||||
value={account.role === Role.USER ? normalize(account.stats.emails, account.limits.emails) : 100}
|
variant="determinate"
|
||||||
/>
|
value={account.role === Role.USER ? normalize(account.stats.emails, account.limits.emails) : 100}
|
||||||
</Pref>
|
/>
|
||||||
{(account.role === Role.ADMIN || account.limits.calls > 0) &&
|
</Pref>
|
||||||
|
}
|
||||||
|
{config.enable_calls && (account.role === Role.ADMIN || account.limits.calls > 0) &&
|
||||||
<Pref title={
|
<Pref title={
|
||||||
<>
|
<>
|
||||||
{t("account_usage_calls_title")}
|
{t("account_usage_calls_title")}
|
||||||
|
|
Loading…
Reference in New Issue