fix
This commit is contained in:
@@ -11,7 +11,9 @@
|
||||
// -password 'choose-a-strong-password' \
|
||||
// -confirm
|
||||
//
|
||||
// Env aliases: PLATFORM_ADMIN_EMAIL, PLATFORM_ADMIN_PASSWORD, DATABASE_URL.
|
||||
// Env aliases: none for credentials — pass -email / -password (or use
|
||||
// `npm run seed:platform-admin -- --email … --password …`). DATABASE_URL may
|
||||
// come from the shell or monorepo-root .env via config.LoadDotEnv.
|
||||
//
|
||||
// -promote-only grants admin on an existing user without changing the password
|
||||
// (-password is ignored). Always requires -confirm.
|
||||
@@ -28,15 +30,18 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/auth"
|
||||
"github.com/descrybe/descrybe-v2/apps/api/internal/config"
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
func main() {
|
||||
config.LoadDotEnv()
|
||||
|
||||
postgresURL := flag.String("postgres", os.Getenv("DATABASE_URL"), "Postgres URL")
|
||||
email := flag.String("email", os.Getenv("PLATFORM_ADMIN_EMAIL"), "Platform admin email")
|
||||
password := flag.String("password", os.Getenv("PLATFORM_ADMIN_PASSWORD"), "Password (min 8; ignored with -promote-only)")
|
||||
email := flag.String("email", "", "Platform admin email (required; do not put in .env)")
|
||||
password := flag.String("password", "", "Password (min 8; ignored with -promote-only; do not put in .env)")
|
||||
name := flag.String("name", "", "Display name (defaults to email local-part)")
|
||||
promoteOnly := flag.Bool("promote-only", false, "Grant platform admin on an existing user; do not set password")
|
||||
confirm := flag.Bool("confirm", false, "Required: acknowledge this writes is_platform_admin + staff_role=admin")
|
||||
@@ -93,11 +98,11 @@ func parseOptions(postgresURL, email, password, name string, promoteOnly, confir
|
||||
}
|
||||
pg := strings.TrimSpace(postgresURL)
|
||||
if pg == "" {
|
||||
return options{}, fmt.Errorf("-postgres / DATABASE_URL is required")
|
||||
return options{}, fmt.Errorf("-postgres / DATABASE_URL is required (export it, pass -postgres, or put DATABASE_URL in monorepo-root .env — the API loads .env, your shell may not)")
|
||||
}
|
||||
emailNorm := strings.ToLower(strings.TrimSpace(email))
|
||||
if emailNorm == "" || !strings.Contains(emailNorm, "@") {
|
||||
return options{}, fmt.Errorf("-email / PLATFORM_ADMIN_EMAIL is required")
|
||||
return options{}, fmt.Errorf("-email is required (pass on the CLI; do not store admin credentials in .env)")
|
||||
}
|
||||
if err := rejectLocalDemoAccount(emailNorm, appEnv); err != nil {
|
||||
return options{}, err
|
||||
@@ -122,7 +127,7 @@ func parseOptions(postgresURL, email, password, name string, promoteOnly, confir
|
||||
}
|
||||
pass := password // keep as provided (do not trim interior spaces)
|
||||
if len(pass) < 8 {
|
||||
return options{}, fmt.Errorf("-password / PLATFORM_ADMIN_PASSWORD must be at least 8 characters")
|
||||
return options{}, fmt.Errorf("-password must be at least 8 characters (pass on the CLI; do not store in .env)")
|
||||
}
|
||||
if err := rejectDemoPassword(pass, appEnv); err != nil {
|
||||
return options{}, err
|
||||
|
||||
@@ -5,6 +5,14 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseOptionsRequiresPostgres(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := parseOptions("", "a@b.com", "password1", "", false, true, "development")
|
||||
if err == nil || !strings.Contains(err.Error(), "DATABASE_URL") {
|
||||
t.Fatalf("err = %v, want DATABASE_URL required", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseOptionsRequiresConfirm(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := parseOptions("postgres://x", "a@b.com", "password1", "", false, false, "development")
|
||||
|
||||
@@ -7,6 +7,13 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LoadDotEnv loads the monorepo-root .env into the process environment.
|
||||
// Existing variables are never overridden. Safe for CLI tools that only need
|
||||
// DATABASE_URL without a full config.Load (production often has no .env file).
|
||||
func LoadDotEnv() {
|
||||
loadDotEnv()
|
||||
}
|
||||
|
||||
// loadDotEnv loads the monorepo-root .env into the process environment.
|
||||
// Existing variables (including empty ones set by tests) are never overridden.
|
||||
// Missing file is a no-op — production typically injects env without a file.
|
||||
|
||||
Reference in New Issue
Block a user