diff --git a/backend/config/config.go b/backend/config/config.go index 2184ea2..56f62ba 100644 --- a/backend/config/config.go +++ b/backend/config/config.go @@ -26,7 +26,7 @@ import ( type Config struct { Hostname string `mapstructure:"HOSTNAME"` - Port string `mapstructure:"PORT"` + Port uint16 `mapstructure:"PORT"` DatabaseUrl string `mapstructure:"POSTGRES_URL"` RedisUrl string `mapstructure:"REDIS_URL"` @@ -39,6 +39,16 @@ type Config struct { JwtExpAccess int `mapstructure:"JWT_EXP_ACCESS"` JwtExpRefresh int `mapstructure:"JWT_EXP_REFRESH"` + SmtpEnabled bool `mapstructure:"SMTP_ENABLED"` + SmtpServer string `mapstructure:"SMTP_SERVER"` + SmtpPort uint16 `mapstructure:"SMTP_PORT"` + SmtpUser string `mapstructure:"SMTP_USER"` + SmtpPassword string `mapstructure:"SMTP_PASSWORD"` + SmtpFrom string `mapstructure:"SMTP_FROM"` + SmtpUseTLS bool `mapstructure:"SMTP_USE_TLS"` + SmtpUseSSL bool `mapstructure:"SMTP_USE_SSL"` + SmtpTimeout uint `mapstructure:"SMTP_TIMEOUT"` + PasswordMinLength int `mapstructure:"PASSWORD_MIN_LENGTH"` PasswordMaxLength int `mapstructure:"PASSWORD_MIN_LENGTH"` PasswordCheckNumbers bool `mapstructure:"PASSWORD_CHECK_NUMBERS"` @@ -47,7 +57,7 @@ type Config struct { PasswordCheckSymbols bool `mapstructure:"PASSWORD_CHECK_SYMBOLS"` PasswordCheckLeaked bool `mapstructure:"PASSWORD_CHECK_LEAKED"` - Environment string `mapstructure:"ENVIRONMENT"` + Environment string `mapstructure:"ENVIRONMENT"` } func Load() (*Config, error) { @@ -62,6 +72,11 @@ func Load() (*Config, error) { viper.SetDefault("JWT_AUDIENCE", "easywish") viper.SetDefault("JWT_ISSUER", "easywish") + viper.SetDefault("SMTP_ENABLED", false) + viper.SetDefault("SMTP_USE_TLS", false) + viper.SetDefault("SMTP_USE_SSL", false) + viper.SetDefault("SMTP_FROM", "An Easywish instance") + viper.SetDefault("PASSWORD_MIN_LENGTH", 6) viper.SetDefault("PASSWORD_MAX_LENGTH", 100) viper.SetDefault("PASSWORD_CHECK_NUMBERS", false) @@ -93,6 +108,16 @@ func Load() (*Config, error) { viper.BindEnv("JWT_EXP_ACCESS") viper.BindEnv("JWT_EXP_REFRESH") + viper.BindEnv("SMTP_ENABLED") + viper.BindEnv("SMTP_SERVER") + viper.BindEnv("SMTP_PORT") + viper.BindEnv("SMTP_USER") + viper.BindEnv("SMTP_PASSWORD") + viper.BindEnv("SMTP_FROM") + viper.BindEnv("SMTP_USE_TLS") + viper.BindEnv("SMTP_USE_SSL") + viper.BindEnv("SMTP_TIMEOUT") + viper.BindEnv("PASSWORD_MIN_LENGTH") viper.BindEnv("PASSWORD_MAX_LENGTH") viper.BindEnv("PASSWORD_CHECK_NUMBERS") diff --git a/backend/internal/errors/postgres.go b/backend/internal/errors/postgres.go index 79abeca..a58151c 100644 --- a/backend/internal/errors/postgres.go +++ b/backend/internal/errors/postgres.go @@ -1,3 +1,20 @@ +// Copyright (c) 2025 Nikolai Papin +// +// This file is part of Easywish +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +// the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + package errors import ( diff --git a/backend/internal/services/smtp.go b/backend/internal/services/smtp.go new file mode 100644 index 0000000..f56b2f7 --- /dev/null +++ b/backend/internal/services/smtp.go @@ -0,0 +1,18 @@ +// Copyright (c) 2025 Nikolai Papin +// +// This file is part of Easywish +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +// the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package services diff --git a/backend/internal/utils/pointer.go b/backend/internal/utils/pointer.go index c6cd178..1a3b459 100644 --- a/backend/internal/utils/pointer.go +++ b/backend/internal/utils/pointer.go @@ -1,3 +1,20 @@ +// Copyright (c) 2025 Nikolai Papin +// +// This file is part of Easywish +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +// the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + package utils func NewPointer[T any](d T) *T { diff --git a/sqlc/query.sql b/sqlc/query.sql index c043b27..e15eb78 100644 --- a/sqlc/query.sql +++ b/sqlc/query.sql @@ -1,5 +1,22 @@ -- vim:fileencoding=utf-8:foldmethod=marker +-- Copyright (c) 2025 Nikolai Papin +-- +-- This file is part of Easywish +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +-- the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + --: User Object {{{ ;-- name: CreateUser :one @@ -163,6 +180,12 @@ WHERE id = $1; SELECT * FROM sessions WHERE user_id = $1 AND terminated IS FALSE; +;-- name: TerminateAllSessionsForUserByUsername :exec +UPDATE sessions +SET terminated = TRUE +FROM users +WHERE sessions.user_id = users.id AND users.username = @username::text; + ;-- name: PruneTerminatedSessions :exec DELETE FROM sessions WHERE terminated IS TRUE; diff --git a/sqlc/schema.sql b/sqlc/schema.sql index 3e6c2df..cb9b186 100644 --- a/sqlc/schema.sql +++ b/sqlc/schema.sql @@ -1,3 +1,22 @@ +-- Copyright (c) 2025 Nikolai Papin +-- +-- This file is part of Easywish +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +-- the GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +; + CREATE EXTENSION IF NOT EXISTS "pgcrypto"; CREATE TABLE IF NOT EXISTS "users" (