116 lines
4.0 KiB
PowerShell
116 lines
4.0 KiB
PowerShell
# Staging auth rehearsal helper (Windows / Laragon).
|
|||
|
|
# Docs: docs/staging-auth-rehearsal.md
|
||
|
|
#
|
||
|
|
# Does NOT read repo `.env` or any live secrets file.
|
||
|
|
# Requires DATABASE_URL in the environment (or -DatabaseUrl).
|
||
|
|
#
|
||
|
|
# Examples:
|
||
|
|
# $env:DATABASE_URL = "postgres://descrybe:descrybe@localhost:5433/descrybe?sslmode=disable"
|
||
|
|
# .\scripts\staging-auth-rehearsal.ps1 # print SQL + next steps
|
||
|
|
# .\scripts\staging-auth-rehearsal.ps1 -IssueInvites # also re-issue invites (no SMTP)
|
||
|
|
# .\scripts\staging-auth-rehearsal.ps1 -IssueInvites -DryRun
|
||
|
|
|
||
|
|
param(
|
||
|
|
[string]$DatabaseUrl = $env:DATABASE_URL,
|
||
|
|
[string]$WebOrigin = $env:WEB_ORIGIN,
|
||
|
|
[string]$MapsDir = "",
|
||
|
|
[switch]$IssueInvites,
|
||
|
|
[switch]$DryRun
|
||
|
|
)
|
||
|
|
|
||
|
|
$ErrorActionPreference = "Stop"
|
||
|
|
|
||
|
|
$Root = Resolve-Path (Join-Path $PSScriptRoot "..")
|
||
|
|
$ApiDir = Join-Path $Root "apps\api"
|
||
|
|
if (-not $MapsDir) {
|
||
|
|
$MapsDir = Join-Path $Root "artifacts"
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host "==> Staging auth rehearsal (no SMTP / link-copy path)"
|
||
|
|
Write-Host " Docs: docs/staging-auth-rehearsal.md"
|
||
|
|
Write-Host ""
|
||
|
|
|
||
|
|
if (-not $DatabaseUrl) {
|
||
|
|
Write-Host "DATABASE_URL is not set. Export it in this shell only (do not paste production secrets into the repo)."
|
||
|
|
Write-Host 'Example: $env:DATABASE_URL = "postgres://descrybe:descrybe@localhost:5433/descrybe?sslmode=disable"'
|
||
|
|
Write-Host ""
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host "=== 1. Promote company admin (preferred: migrator CLI; dry-run first) ==="
|
||
|
|
Write-Host @"
|
||
|
|
cd apps/api
|
||
|
|
go run ./cmd/migrator -list-member-memberships -postgres "`$DATABASE_URL"
|
||
|
|
go run ./cmd/migrator -promote-company-admins -email '<real-email>' -dry-run -postgres "`$DATABASE_URL"
|
||
|
|
go run ./cmd/migrator -promote-company-admins -email '<real-email>' -confirm -postgres "`$DATABASE_URL"
|
||
|
|
|
||
|
|
# SQL alternate (fill UUIDs):
|
||
|
|
-- List
|
||
|
|
SELECT u.id AS user_id, u.email, u.must_set_password, u.is_platform_admin,
|
||
|
|
m.company_id, c.name AS company_name, m.role, m.status
|
||
|
|
FROM memberships m
|
||
|
|
JOIN users u ON u.id = m.user_id
|
||
|
|
JOIN companies c ON c.id = m.company_id
|
||
|
|
WHERE m.status = 'active'
|
||
|
|
ORDER BY c.name, u.email;
|
||
|
|
|
||
|
|
-- Promote (fill UUIDs)
|
||
|
|
UPDATE memberships
|
||
|
|
SET role = 'admin'
|
||
|
|
WHERE user_id = '<user-uuid>'
|
||
|
|
AND company_id = '<company-uuid>'
|
||
|
|
AND status = 'active'
|
||
|
|
RETURNING user_id, company_id, role;
|
||
|
|
"@
|
||
|
|
Write-Host ""
|
||
|
|
|
||
|
|
if (-not $IssueInvites) {
|
||
|
|
Write-Host "=== 2. Re-issue set-password (skipped) ==="
|
||
|
|
Write-Host "Re-run with -IssueInvites after emails are real (not *@legacy.local)."
|
||
|
|
Write-Host " .\scripts\staging-auth-rehearsal.ps1 -IssueInvites"
|
||
|
|
Write-Host ""
|
||
|
|
Write-Host "=== 3. Login smoke (manual) ==="
|
||
|
|
Write-Host "Copy one URL from migrator stdout or artifacts/password_invites.json"
|
||
|
|
Write-Host "-> open /accept-invite -> set password -> /login -> confirm must_set_password=false"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
if (-not $DatabaseUrl) {
|
||
|
|
Write-Error "DATABASE_URL is required for -IssueInvites"
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($WebOrigin) {
|
||
|
|
$env:WEB_ORIGIN = $WebOrigin
|
||
|
|
Write-Host "WEB_ORIGIN=$WebOrigin"
|
||
|
|
} else {
|
||
|
|
Write-Host "WEB_ORIGIN unset -> migrator default http://localhost:28472"
|
||
|
|
}
|
||
|
|
|
||
|
|
New-Item -ItemType Directory -Force -Path $MapsDir | Out-Null
|
||
|
|
Set-Location $ApiDir
|
||
|
|
|
||
|
|
$mapsRel = Resolve-Path $MapsDir
|
||
|
|
Write-Host "=== 2. Re-issue set-password invites (maps-dir=$mapsRel) ==="
|
||
|
|
$migratorArgs = @(
|
||
|
|
"./cmd/migrator",
|
||
|
|
"-issue-set-password-invites",
|
||
|
|
"-postgres", $DatabaseUrl,
|
||
|
|
"-maps-dir", $mapsRel
|
||
|
|
)
|
||
|
|
if ($DryRun) {
|
||
|
|
$migratorArgs += "-dry-run"
|
||
|
|
Write-Host "(dry-run: no invites written)"
|
||
|
|
}
|
||
|
|
|
||
|
|
& go run @migratorArgs
|
||
|
|
if ($LASTEXITCODE -ne 0) {
|
||
|
|
Write-Error "migrator -issue-set-password-invites failed (exit $LASTEXITCODE)"
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host ""
|
||
|
|
Write-Host "=== 3. Login smoke (manual - no SMTP) ==="
|
||
|
|
Write-Host "1. Copy one email<TAB>url line from stdout above (or $mapsRel\password_invites.json)."
|
||
|
|
Write-Host "2. Open the URL -> set password (at least 8 chars)."
|
||
|
|
Write-Host "3. Sign in at /login with the same email."
|
||
|
|
Write-Host '4. SQL: SELECT email, must_set_password FROM users WHERE lower(email)=lower(''<smoke-email>'');'
|
||
|
|
Write-Host "Do NOT run cmd/mailhooks for this rehearsal."
|