diff --git a/docker/ss-atlas/internal/handlers/subscription.go b/docker/ss-atlas/internal/handlers/subscription.go index 42853f5..1c52059 100644 --- a/docker/ss-atlas/internal/handlers/subscription.go +++ b/docker/ss-atlas/internal/handlers/subscription.go @@ -155,38 +155,33 @@ func (a *App) handleSuccess(w http.ResponseWriter, r *http.Request) { log.Printf("ldap add to customers failed for %s: %v (create group 'customers' in LLDAP admin if missing)", result.Username, err) } - inGroup, _ := a.ldap.IsInGroup(result.Username, "customers") - - if result.IsNew || !inGroup { - // New or lapsed: send password email, show success page. + // New or lapsed: send password-set email so they can create their login. + if result.IsNew { if err := a.triggerPasswordReset(r, result.Username); err != nil { log.Printf("authelia reset trigger failed for %s: %v", username, err) } else { resendRateLimiter.record(result.Username) } - if err := a.tmpl.ExecuteTemplate(w, "success.html", map[string]any{ - "AppURL": a.cfg.AppURL, - "Username": result.Username, - }); err != nil { - log.Printf("template error: %v", err) - http.Error(w, "internal error", http.StatusInternalServerError) - } - return } - - // Returning active customer: ensure stack exists, go to dashboard + // Returning customer: ensure stack exists (no redirect; show same success page). stackName := fmt.Sprintf("customer-%s", result.Username) exists, _ := a.swarm.StackExists(stackName) if !exists { if err := a.swarm.RestoreVolumes(stackName, a.cfg.ArchivePath); err != nil { - log.Printf("resubscribe: volume restore failed for %s: %v", result.Username, err) + log.Printf("success: volume restore failed for %s: %v", result.Username, err) } if err := a.swarm.DeployStack(stackName, result.Username, a.cfg.TraefikDomain); err != nil { - log.Printf("resubscribe: stack deploy failed for %s: %v", result.Username, err) + log.Printf("success: stack deploy failed for %s: %v", result.Username, err) } } - log.Printf("resubscribe: %s payment verified, redirecting to dashboard", result.Username) - http.Redirect(w, r, a.cfg.AppURL+"/dashboard", http.StatusSeeOther) + // Always show success page: set password via email first, then dashboard. + if err := a.tmpl.ExecuteTemplate(w, "success.html", map[string]any{ + "AppURL": a.cfg.AppURL, + "Username": result.Username, + }); err != nil { + log.Printf("template error: %v", err) + http.Error(w, "internal error", http.StatusInternalServerError) + } } // handleLinkStripeCustomer creates a Stripe customer for the current user and saves the ID in LDAP, diff --git a/docker/ss-atlas/templates/pages/success.html b/docker/ss-atlas/templates/pages/success.html index 1fff24d..ea7d254 100644 --- a/docker/ss-atlas/templates/pages/success.html +++ b/docker/ss-atlas/templates/pages/success.html @@ -56,6 +56,20 @@ .resend .msg { font-size: 0.85rem; margin-top: 0.5rem; } .resend .msg.success { color: var(--green, #22c55e); } .resend .msg.error { color: #ef4444; } + .dashboard-cta { margin-top: 1.5rem; padding-top: 1rem; border-top: 1px solid var(--border); } + .dashboard-cta .muted { color: var(--muted); font-size: 0.9rem; margin-bottom: 0.5rem; } + .dashboard-cta .btn-primary { + display: inline-block; + background: var(--accent); + color: #fff; + text-decoration: none; + padding: 0.6rem 1.25rem; + font-size: 0.95rem; + font-weight: 600; + border-radius: 8px; + transition: background 0.2s; + } + .dashboard-cta .btn-primary:hover { background: var(--accent-hover); } {{template "analytics"}} @@ -63,13 +77,9 @@
We've sent a password set email to your address. Use the link in that email to create your password and sign in.
-You'll be required to:
-You should have received an email from a250.ca to set your login. Use the link in that email to create your password and sign in.
+Do that first. You'll need to set a password and (when prompted) enable two-factor authentication or a passkey.
Once you've signed in, you can activate your workspace from the dashboard.
{{if .Username}}