Rename webUrl to baseUrl (#711)

This commit is contained in:
Sung 2025-11-01 00:57:37 -07:00 committed by GitHub
commit ce5c9b242a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 81 additions and 81 deletions

View file

@ -139,15 +139,15 @@ func TestServerStartHelp(t *testing.T) {
outputStr := string(output)
assert.Equal(t, strings.Contains(outputStr, "dnote-server start [flags]"), true, "output should contain usage")
assert.Equal(t, strings.Contains(outputStr, "--port"), true, "output should contain port flag")
assert.Equal(t, strings.Contains(outputStr, "--webUrl"), true, "output should contain webUrl flag")
assert.Equal(t, strings.Contains(outputStr, "--baseUrl"), true, "output should contain baseUrl flag")
assert.Equal(t, strings.Contains(outputStr, "--dbPath"), true, "output should contain dbPath flag")
assert.Equal(t, strings.Contains(outputStr, "--disableRegistration"), true, "output should contain disableRegistration flag")
}
func TestServerStartInvalidConfig(t *testing.T) {
cmd := exec.Command(testServerBinary, "start")
// Set invalid WebURL to trigger validation failure
cmd.Env = []string{"WebURL=not-a-valid-url"}
// Set invalid BaseURL to trigger validation failure
cmd.Env = []string{"BaseURL=not-a-valid-url"}
output, err := cmd.CombinedOutput()
@ -158,9 +158,9 @@ func TestServerStartInvalidConfig(t *testing.T) {
outputStr := string(output)
assert.Equal(t, strings.Contains(outputStr, "Error:"), true, "output should contain error message")
assert.Equal(t, strings.Contains(outputStr, "Invalid WebURL"), true, "output should mention invalid WebURL")
assert.Equal(t, strings.Contains(outputStr, "Invalid BaseURL"), true, "output should mention invalid BaseURL")
assert.Equal(t, strings.Contains(outputStr, "dnote-server start [flags]"), true, "output should show usage")
assert.Equal(t, strings.Contains(outputStr, "--webUrl"), true, "output should show flags")
assert.Equal(t, strings.Contains(outputStr, "--baseUrl"), true, "output should show flags")
}
func TestServerUnknownCommand(t *testing.T) {

View file

@ -27,8 +27,8 @@ var (
ErrEmptyDB = errors.New("No database connection was provided")
// ErrEmptyClock is an error for missing clock in the app configuration
ErrEmptyClock = errors.New("No clock was provided")
// ErrEmptyWebURL is an error for missing WebURL content in the app configuration
ErrEmptyWebURL = errors.New("No WebURL was provided")
// ErrEmptyBaseURL is an error for missing BaseURL content in the app configuration
ErrEmptyBaseURL = errors.New("No BaseURL was provided")
// ErrEmptyEmailBackend is an error for missing EmailBackend content in the app configuration
ErrEmptyEmailBackend = errors.New("No EmailBackend was provided")
// ErrEmptyHTTP500Page is an error for missing HTTP 500 page content
@ -42,7 +42,7 @@ type App struct {
EmailBackend mailer.Backend
Files map[string][]byte
HTTP500Page []byte
WebURL string
BaseURL string
DisableRegistration bool
Port string
DBPath string
@ -51,8 +51,8 @@ type App struct {
// Validate validates the app configuration
func (a *App) Validate() error {
if a.WebURL == "" {
return ErrEmptyWebURL
if a.BaseURL == "" {
return ErrEmptyBaseURL
}
if a.Clock == nil {
return ErrEmptyClock

View file

@ -27,8 +27,8 @@ import (
var defaultSender = "admin@getdnote.com"
// GetSenderEmail returns the sender email
func GetSenderEmail(webURL, want string) (string, error) {
addr, err := getNoreplySender(webURL)
func GetSenderEmail(baseURL, want string) (string, error) {
addr, err := getNoreplySender(baseURL)
if err != nil {
return "", errors.Wrap(err, "getting sender email address")
}
@ -52,10 +52,10 @@ func getDomainFromURL(rawURL string) (string, error) {
return domain, nil
}
func getNoreplySender(webURL string) (string, error) {
domain, err := getDomainFromURL(webURL)
func getNoreplySender(baseURL string) (string, error) {
domain, err := getDomainFromURL(baseURL)
if err != nil {
return "", errors.Wrap(err, "parsing web url")
return "", errors.Wrap(err, "parsing base url")
}
addr := fmt.Sprintf("noreply@%s", domain)
@ -64,14 +64,14 @@ func getNoreplySender(webURL string) (string, error) {
// SendWelcomeEmail sends welcome email
func (a *App) SendWelcomeEmail(email string) error {
from, err := GetSenderEmail(a.WebURL, defaultSender)
from, err := GetSenderEmail(a.BaseURL, defaultSender)
if err != nil {
return errors.Wrap(err, "getting the sender email")
}
data := mailer.WelcomeTmplData{
AccountEmail: email,
WebURL: a.WebURL,
BaseURL: a.BaseURL,
}
if err := a.EmailBackend.SendEmail(mailer.EmailTypeWelcome, from, []string{email}, data); err != nil {
@ -87,7 +87,7 @@ func (a *App) SendPasswordResetEmail(email, tokenValue string) error {
return ErrEmailRequired
}
from, err := GetSenderEmail(a.WebURL, defaultSender)
from, err := GetSenderEmail(a.BaseURL, defaultSender)
if err != nil {
return errors.Wrap(err, "getting the sender email")
}
@ -95,7 +95,7 @@ func (a *App) SendPasswordResetEmail(email, tokenValue string) error {
data := mailer.EmailResetPasswordTmplData{
AccountEmail: email,
Token: tokenValue,
WebURL: a.WebURL,
BaseURL: a.BaseURL,
}
if err := a.EmailBackend.SendEmail(mailer.EmailTypeResetPassword, from, []string{email}, data); err != nil {
@ -111,14 +111,14 @@ func (a *App) SendPasswordResetEmail(email, tokenValue string) error {
// SendPasswordResetAlertEmail sends email that notifies users of a password change
func (a *App) SendPasswordResetAlertEmail(email string) error {
from, err := GetSenderEmail(a.WebURL, defaultSender)
from, err := GetSenderEmail(a.BaseURL, defaultSender)
if err != nil {
return errors.Wrap(err, "getting the sender email")
}
data := mailer.EmailResetPasswordAlertTmplData{
AccountEmail: email,
WebURL: a.WebURL,
BaseURL: a.BaseURL,
}
if err := a.EmailBackend.SendEmail(mailer.EmailTypeResetPasswordAlert, from, []string{email}, data); err != nil {

View file

@ -27,7 +27,7 @@ func TestSendWelcomeEmail(t *testing.T) {
emailBackend := testutils.MockEmailbackendImplementation{}
a := NewTest()
a.EmailBackend = &emailBackend
a.WebURL = "http://example.com"
a.BaseURL = "http://example.com"
if err := a.SendWelcomeEmail("alice@example.com"); err != nil {
t.Fatal(err, "failed to perform")
@ -43,7 +43,7 @@ func TestSendPasswordResetEmail(t *testing.T) {
emailBackend := testutils.MockEmailbackendImplementation{}
a := NewTest()
a.EmailBackend = &emailBackend
a.WebURL = "http://example.com"
a.BaseURL = "http://example.com"
if err := a.SendPasswordResetEmail("alice@example.com", "mockTokenValue"); err != nil {
t.Fatal(err, "failed to perform")
@ -57,21 +57,21 @@ func TestSendPasswordResetEmail(t *testing.T) {
func TestGetSenderEmail(t *testing.T) {
testCases := []struct {
webURL string
baseURL string
expectedSender string
}{
{
webURL: "https://www.example.com",
baseURL: "https://www.example.com",
expectedSender: "noreply@example.com",
},
{
webURL: "https://www.example2.com",
baseURL: "https://www.example2.com",
expectedSender: "alice@example2.com",
},
}
for _, tc := range testCases {
t.Run(fmt.Sprintf("web url %s", tc.webURL), func(t *testing.T) {
t.Run(fmt.Sprintf("base url %s", tc.baseURL), func(t *testing.T) {
})
}
}

View file

@ -27,7 +27,7 @@ func NewTest() App {
Clock: clock.NewMock(),
EmailBackend: &testutils.MockEmailbackendImplementation{},
HTTP500Page: assets.MustGetHTTP500ErrorPage(),
WebURL: "http://127.0.0.0.1",
BaseURL: "http://127.0.0.0.1",
Port: "3000",
DisableRegistration: false,
DBPath: "",

View file

@ -57,7 +57,7 @@ func initApp(cfg config.Config) app.App {
Clock: clock.New(),
EmailBackend: emailBackend,
HTTP500Page: cfg.HTTP500Page,
WebURL: cfg.WebURL,
BaseURL: cfg.BaseURL,
DisableRegistration: cfg.DisableRegistration,
Port: cfg.Port,
DBPath: cfg.DBPath,

View file

@ -33,7 +33,7 @@ func startCmd(args []string) {
fs := setupFlagSet("start", "dnote-server start")
port := fs.String("port", "", "Server port (env: PORT, default: 3001)")
webURL := fs.String("webUrl", "", "Full URL to server without trailing slash (env: WebURL, default: http://localhost:3001)")
baseURL := fs.String("baseUrl", "", "Full URL to server without trailing slash (env: BaseURL, default: http://localhost:3001)")
dbPath := fs.String("dbPath", "", "Path to SQLite database file (env: DBPath, default: $XDG_DATA_HOME/dnote/server.db)")
disableRegistration := fs.Bool("disableRegistration", false, "Disable user registration (env: DisableRegistration, default: false)")
logLevel := fs.String("logLevel", "", "Log level: debug, info, warn, or error (env: LOG_LEVEL, default: info)")
@ -42,7 +42,7 @@ func startCmd(args []string) {
cfg, err := config.New(config.Params{
Port: *port,
WebURL: *webURL,
BaseURL: *baseURL,
DBPath: *dbPath,
DisableRegistration: *disableRegistration,
LogLevel: *logLevel,

View file

@ -40,8 +40,8 @@ var (
var (
// ErrDBMissingPath is an error for an incomplete configuration missing the database path
ErrDBMissingPath = errors.New("DB Path is empty")
// ErrWebURLInvalid is an error for an incomplete configuration with invalid web url
ErrWebURLInvalid = errors.New("Invalid WebURL")
// ErrBaseURLInvalid is an error for an incomplete configuration with invalid base url
ErrBaseURLInvalid = errors.New("Invalid BaseURL")
// ErrPortInvalid is an error for an incomplete configuration with invalid port
ErrPortInvalid = errors.New("Invalid Port")
)
@ -63,7 +63,7 @@ func getOrEnv(value, envKey, defaultVal string) string {
// Config is an application configuration
type Config struct {
WebURL string
BaseURL string
DisableRegistration bool
Port string
DBPath string
@ -75,7 +75,7 @@ type Config struct {
// Params are the configuration parameters for creating a new Config
type Params struct {
Port string
WebURL string
BaseURL string
DBPath string
DisableRegistration bool
LogLevel string
@ -86,7 +86,7 @@ type Params struct {
func New(p Params) (Config, error) {
c := Config{
Port: getOrEnv(p.Port, "PORT", "3001"),
WebURL: getOrEnv(p.WebURL, "WebURL", "http://localhost:3001"),
BaseURL: getOrEnv(p.BaseURL, "BaseURL", "http://localhost:3001"),
DBPath: getOrEnv(p.DBPath, "DBPath", DefaultDBPath),
DisableRegistration: p.DisableRegistration || readBoolEnv("DisableRegistration"),
LogLevel: getOrEnv(p.LogLevel, "LOG_LEVEL", "info"),
@ -102,8 +102,8 @@ func New(p Params) (Config, error) {
}
func validate(c Config) error {
if _, err := url.ParseRequestURI(c.WebURL); err != nil {
return errors.Wrapf(ErrWebURLInvalid, "'%s'", c.WebURL)
if _, err := url.ParseRequestURI(c.BaseURL); err != nil {
return errors.Wrapf(ErrBaseURLInvalid, "'%s'", c.BaseURL)
}
if c.Port == "" {
return ErrPortInvalid

View file

@ -30,17 +30,17 @@ func TestValidate(t *testing.T) {
}{
{
config: Config{
DBPath: "test.db",
WebURL: "http://mock.url",
Port: "3000",
DBPath: "test.db",
BaseURL: "http://mock.url",
Port: "3000",
},
expectedErr: nil,
},
{
config: Config{
DBPath: "",
WebURL: "http://mock.url",
Port: "3000",
DBPath: "",
BaseURL: "http://mock.url",
Port: "3000",
},
expectedErr: ErrDBMissingPath,
},
@ -48,12 +48,12 @@ func TestValidate(t *testing.T) {
config: Config{
DBPath: "test.db",
},
expectedErr: ErrWebURLInvalid,
expectedErr: ErrBaseURLInvalid,
},
{
config: Config{
DBPath: "test.db",
WebURL: "http://mock.url",
DBPath: "test.db",
BaseURL: "http://mock.url",
},
expectedErr: ErrPortInvalid,
},

View file

@ -41,7 +41,7 @@ func TestDefaultBackendSendEmail(t *testing.T) {
data := WelcomeTmplData{
AccountEmail: "bob@example.com",
WebURL: "https://example.com",
BaseURL: "https://example.com",
}
err := backend.SendEmail(EmailTypeWelcome, "alice@example.com", []string{"bob@example.com"}, data)
@ -94,7 +94,7 @@ func TestStdoutBackendSendEmail(t *testing.T) {
data := WelcomeTmplData{
AccountEmail: "bob@example.com",
WebURL: "https://example.com",
BaseURL: "https://example.com",
}
err := backend.SendEmail(EmailTypeWelcome, "alice@example.com", []string{"bob@example.com"}, data)

View file

@ -44,26 +44,26 @@ func TestAllTemplatesInitialized(t *testing.T) {
func TestResetPasswordEmail(t *testing.T) {
testCases := []struct {
token string
webURL string
token string
baseURL string
}{
{
token: "someRandomToken1",
webURL: "http://localhost:3000",
token: "someRandomToken1",
baseURL: "http://localhost:3000",
},
{
token: "someRandomToken2",
webURL: "http://localhost:3001",
token: "someRandomToken2",
baseURL: "http://localhost:3001",
},
}
tmpl := NewTemplates()
for _, tc := range testCases {
t.Run(fmt.Sprintf("with WebURL %s", tc.webURL), func(t *testing.T) {
t.Run(fmt.Sprintf("with BaseURL %s", tc.baseURL), func(t *testing.T) {
dat := EmailResetPasswordTmplData{
Token: tc.token,
WebURL: tc.webURL,
Token: tc.token,
BaseURL: tc.baseURL,
}
subject, body, err := tmpl.Execute(EmailTypeResetPassword, EmailKindText, dat)
if err != nil {
@ -73,8 +73,8 @@ func TestResetPasswordEmail(t *testing.T) {
if subject != "Reset your Dnote password" {
t.Errorf("expected subject 'Reset your Dnote password', got '%s'", subject)
}
if ok := strings.Contains(body, tc.webURL); !ok {
t.Errorf("email body did not contain %s", tc.webURL)
if ok := strings.Contains(body, tc.baseURL); !ok {
t.Errorf("email body did not contain %s", tc.baseURL)
}
if ok := strings.Contains(body, tc.token); !ok {
t.Errorf("email body did not contain %s", tc.token)
@ -86,25 +86,25 @@ func TestResetPasswordEmail(t *testing.T) {
func TestWelcomeEmail(t *testing.T) {
testCases := []struct {
accountEmail string
webURL string
baseURL string
}{
{
accountEmail: "test@example.com",
webURL: "http://localhost:3000",
baseURL: "http://localhost:3000",
},
{
accountEmail: "user@example.org",
webURL: "http://localhost:3001",
baseURL: "http://localhost:3001",
},
}
tmpl := NewTemplates()
for _, tc := range testCases {
t.Run(fmt.Sprintf("with WebURL %s and email %s", tc.webURL, tc.accountEmail), func(t *testing.T) {
t.Run(fmt.Sprintf("with BaseURL %s and email %s", tc.baseURL, tc.accountEmail), func(t *testing.T) {
dat := WelcomeTmplData{
AccountEmail: tc.accountEmail,
WebURL: tc.webURL,
BaseURL: tc.baseURL,
}
subject, body, err := tmpl.Execute(EmailTypeWelcome, EmailKindText, dat)
if err != nil {
@ -114,8 +114,8 @@ func TestWelcomeEmail(t *testing.T) {
if subject != "Welcome to Dnote!" {
t.Errorf("expected subject 'Welcome to Dnote!', got '%s'", subject)
}
if ok := strings.Contains(body, tc.webURL); !ok {
t.Errorf("email body did not contain %s", tc.webURL)
if ok := strings.Contains(body, tc.baseURL); !ok {
t.Errorf("email body did not contain %s", tc.baseURL)
}
if ok := strings.Contains(body, tc.accountEmail); !ok {
t.Errorf("email body did not contain %s", tc.accountEmail)
@ -127,25 +127,25 @@ func TestWelcomeEmail(t *testing.T) {
func TestResetPasswordAlertEmail(t *testing.T) {
testCases := []struct {
accountEmail string
webURL string
baseURL string
}{
{
accountEmail: "test@example.com",
webURL: "http://localhost:3000",
baseURL: "http://localhost:3000",
},
{
accountEmail: "user@example.org",
webURL: "http://localhost:3001",
baseURL: "http://localhost:3001",
},
}
tmpl := NewTemplates()
for _, tc := range testCases {
t.Run(fmt.Sprintf("with WebURL %s and email %s", tc.webURL, tc.accountEmail), func(t *testing.T) {
t.Run(fmt.Sprintf("with BaseURL %s and email %s", tc.baseURL, tc.accountEmail), func(t *testing.T) {
dat := EmailResetPasswordAlertTmplData{
AccountEmail: tc.accountEmail,
WebURL: tc.webURL,
BaseURL: tc.baseURL,
}
subject, body, err := tmpl.Execute(EmailTypeResetPasswordAlert, EmailKindText, dat)
if err != nil {
@ -155,8 +155,8 @@ func TestResetPasswordAlertEmail(t *testing.T) {
if subject != "Your Dnote password was changed" {
t.Errorf("expected subject 'Your Dnote password was changed', got '%s'", subject)
}
if ok := strings.Contains(body, tc.webURL); !ok {
t.Errorf("email body did not contain %s", tc.webURL)
if ok := strings.Contains(body, tc.baseURL); !ok {
t.Errorf("email body did not contain %s", tc.baseURL)
}
if ok := strings.Contains(body, tc.accountEmail); !ok {
t.Errorf("email body did not contain %s", tc.accountEmail)

View file

@ -2,4 +2,4 @@ You are receiving this because you requested to reset the password of the '{{ .A
Please click on the following link, or paste this into your browser to complete the process:
{{ .WebURL }}/password-reset/{{ .Token }}
{{ .BaseURL }}/password-reset/{{ .Token }}

View file

@ -2,7 +2,7 @@ Hi,
This email is to notify you that the password for your Dnote account "{{ .AccountEmail }}" has changed.
If you did not initiate this password change, reset your password at {{ .WebURL }}/password-reset.
If you did not initiate this password change, reset your password at {{ .BaseURL }}/password-reset.
Thanks.

View file

@ -4,8 +4,8 @@ Dnote is a simple command-line notebook.
YOUR ACCOUNT
Your {{ .WebURL }} account is "{{ .AccountEmail }}". Log in at {{ .WebURL }}/login
If you ever forget your password, you can reset it at {{ .WebURL }}/password-reset
Your {{ .BaseURL }} account is "{{ .AccountEmail }}". Log in at {{ .BaseURL }}/login
If you ever forget your password, you can reset it at {{ .BaseURL }}/password-reset
SOURCE CODE

View file

@ -19,17 +19,17 @@ package mailer
type EmailResetPasswordTmplData struct {
AccountEmail string
Token string
WebURL string
BaseURL string
}
// EmailResetPasswordAlertTmplData is a template data for reset password emails
type EmailResetPasswordAlertTmplData struct {
AccountEmail string
WebURL string
BaseURL string
}
// WelcomeTmplData is a template data for welcome emails
type WelcomeTmplData struct {
AccountEmail string
WebURL string
BaseURL string
}