Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion internal/handlers/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"instant.dev/internal/config"
"instant.dev/internal/middleware"
"instant.dev/internal/models"
"instant.dev/internal/urls"
)

// --- Browser OAuth flow shared helpers ---
Expand All @@ -34,7 +35,9 @@ const defaultReturnTo = "https://instanode.dev/login/callback"
// Hardcoded rather than reading from cfg because the registered redirect_uri
// at GitHub/Google is fixed at app-registration time — varying it per
// deployment would require multiple OAuth apps.
const canonicalAPIBase = "https://api.instanode.dev"
// canonicalAPIBase is preserved as an alias of urls.PublicAPIBase so any
// external reference keeps compiling. New code should use urls.PublicAPIBase.
const canonicalAPIBase = urls.PublicAPIBase

// allowedReturnOrigins is the static allowlist for ?return_to= validation.
// Anything not on this list collapses to defaultReturnTo. The list is
Expand Down
10 changes: 5 additions & 5 deletions internal/handlers/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ package handlers
import (
"context"
"database/sql"
"fmt"
"log/slog"
"time"

Expand All @@ -20,6 +19,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/metrics"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/plans"
"instant.dev/internal/provisioner"
Expand Down Expand Up @@ -68,7 +68,7 @@ func (h *CacheHandler) provisionCache(ctx context.Context, token, tier string) (
func (h *CacheHandler) NewCache(c *fiber.Ctx) error {
if !h.cfg.IsServiceEnabled("redis") {
return respondError(c, fiber.StatusServiceUnavailable, "service_disabled",
"Redis provisioning is coming in Phase 3. Sign up at https://instanode.dev/start to be notified.")
"Redis provisioning is coming in Phase 3. Sign up at "+urls.StartURLPrefix+" to be notified.")
}

start := time.Now()
Expand All @@ -95,7 +95,7 @@ func (h *CacheHandler) NewCache(c *fiber.Ctx) error {
// ── Dedicated requires authentication ─────────────────────────────────────
if body.Dedicated {
return respondError(c, fiber.StatusPaymentRequired, "auth_required",
"isolated resources require an authenticated team. Sign up at https://instanode.dev/start")
"isolated resources require an authenticated team. Sign up at "+urls.StartURLPrefix)
}

// ── Anonymous path ─────────────────────────────────────────────────────────
Expand All @@ -117,7 +117,7 @@ func (h *CacheHandler) NewCache(c *fiber.Ctx) error {
}
upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}
// Decrypt the stored connection_url to return it in plaintext.
Expand Down Expand Up @@ -230,7 +230,7 @@ func (h *CacheHandler) NewCache(c *fiber.Ctx) error {

upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}

Expand Down
10 changes: 5 additions & 5 deletions internal/handlers/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package handlers
import (
"context"
"database/sql"
"fmt"
"log/slog"
"time"

Expand All @@ -30,6 +29,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/metrics"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/plans"
dbprovider "instant.dev/internal/providers/db"
Expand Down Expand Up @@ -79,7 +79,7 @@ func (h *DBHandler) provisionDB(ctx context.Context, token, tier string) (*dbpro
func (h *DBHandler) NewDB(c *fiber.Ctx) error {
if !h.cfg.IsServiceEnabled("postgres") {
return respondError(c, fiber.StatusServiceUnavailable, "service_disabled",
"Postgres provisioning is coming in Phase 2. Sign up at https://instanode.dev/start to be notified.")
"Postgres provisioning is coming in Phase 2. Sign up at "+urls.StartURLPrefix+" to be notified.")
}

start := time.Now()
Expand All @@ -106,7 +106,7 @@ func (h *DBHandler) NewDB(c *fiber.Ctx) error {
// ── Dedicated requires authentication ─────────────────────────────────────
if body.Dedicated {
return respondError(c, fiber.StatusPaymentRequired, "auth_required",
"isolated resources require an authenticated team. Sign up at https://instanode.dev/start")
"isolated resources require an authenticated team. Sign up at "+urls.StartURLPrefix)
}

// ── Anonymous path ─────────────────────────────────────────────────────────
Expand All @@ -129,7 +129,7 @@ func (h *DBHandler) NewDB(c *fiber.Ctx) error {
}
upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}
// Decrypt the stored connection_url to return it in plaintext.
Expand Down Expand Up @@ -229,7 +229,7 @@ func (h *DBHandler) NewDB(c *fiber.Ctx) error {

upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}

Expand Down
5 changes: 3 additions & 2 deletions internal/handlers/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/redis/go-redis/v9"
"instant.dev/internal/config"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/providers/compute"
"instant.dev/internal/providers/compute/k8s"
Expand Down Expand Up @@ -115,7 +116,7 @@ func (h *DeployHandler) requireTeam(c *fiber.Ctx) (*models.Team, error) {
teamIDStr := middleware.GetTeamID(c)
if teamIDStr == "" {
return nil, respondError(c, fiber.StatusUnauthorized, "unauthorized",
"A session token is required to deploy. Sign in at https://instanode.dev/start")
"A session token is required to deploy. Sign in at "+urls.StartURLPrefix)
}
teamUUID, err := parseTeamID(teamIDStr)
if err != nil {
Expand Down Expand Up @@ -183,7 +184,7 @@ func (h *DeployHandler) runDeploy(d *models.Deployment, tarball []byte) {
func (h *DeployHandler) New(c *fiber.Ctx) error {
if !h.cfg.IsServiceEnabled("deploy") {
return respondError(c, fiber.StatusServiceUnavailable, "service_disabled",
"Container deployment is coming in Phase 6. Sign up at https://instanode.dev/start to be notified.")
"Container deployment is coming in Phase 6. Sign up at "+urls.StartURLPrefix+" to be notified.")
}

team, err := h.requireTeam(c)
Expand Down
14 changes: 9 additions & 5 deletions internal/handlers/internal_url.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package handlers

import "net/url"
import (
"net/url"

"instant.dev/internal/urls"
)

// proxiedInternalURL rewrites a customer-facing public URL to the cluster-internal
// address of the per-protocol proxy. Workloads deployed inside the same cluster
Expand All @@ -26,13 +30,13 @@ func proxiedInternalURL(publicURL, resourceType string) string {
}
switch resourceType {
case "postgres":
parsed.Host = "instant-pg-proxy.instant.svc.cluster.local:5432"
parsed.Host = urls.InternalPGProxy
case "redis":
parsed.Host = "instant-redis-proxy.instant.svc.cluster.local:6379"
parsed.Host = urls.InternalRedisProxy
case "mongodb":
parsed.Host = "instant-mongo-proxy.instant.svc.cluster.local:27017"
parsed.Host = urls.InternalMongoProxy
case "queue":
parsed.Host = "instant-nats-proxy.instant.svc.cluster.local:4222"
parsed.Host = urls.InternalNATSProxy
default:
return publicURL
}
Expand Down
10 changes: 5 additions & 5 deletions internal/handlers/nosql.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ package handlers
import (
"context"
"database/sql"
"fmt"
"log/slog"
"time"

Expand All @@ -19,6 +18,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/metrics"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/plans"
"instant.dev/internal/provisioner"
Expand Down Expand Up @@ -67,7 +67,7 @@ func (h *NoSQLHandler) provisionNoSQL(ctx context.Context, token, tier string) (
func (h *NoSQLHandler) NewNoSQL(c *fiber.Ctx) error {
if !h.cfg.IsServiceEnabled("mongodb") {
return respondError(c, fiber.StatusServiceUnavailable, "service_disabled",
"MongoDB provisioning is coming in Phase 4. Sign up at https://instanode.dev/start to be notified.")
"MongoDB provisioning is coming in Phase 4. Sign up at "+urls.StartURLPrefix+" to be notified.")
}

start := time.Now()
Expand All @@ -94,7 +94,7 @@ func (h *NoSQLHandler) NewNoSQL(c *fiber.Ctx) error {
// ── Dedicated requires authentication ─────────────────────────────────────
if body.Dedicated {
return respondError(c, fiber.StatusPaymentRequired, "auth_required",
"isolated resources require an authenticated team. Sign up at https://instanode.dev/start")
"isolated resources require an authenticated team. Sign up at "+urls.StartURLPrefix)
}

// ── Anonymous path ─────────────────────────────────────────────────────────
Expand All @@ -116,7 +116,7 @@ func (h *NoSQLHandler) NewNoSQL(c *fiber.Ctx) error {
}
upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}
// Decrypt the stored connection_url to return it in plaintext.
Expand Down Expand Up @@ -218,7 +218,7 @@ func (h *NoSQLHandler) NewNoSQL(c *fiber.Ctx) error {

upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}

Expand Down
5 changes: 3 additions & 2 deletions internal/handlers/provision_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/models"
"instant.dev/internal/plans"
"instant.dev/internal/urls"
)

// provisionHelper holds the shared dependencies used by every provisioning handler.
Expand Down Expand Up @@ -182,7 +183,7 @@ func upgradeNote(upgradeURL string) string {
if upgradeURL != "" {
return fmt.Sprintf("Works for 24h free. Claim to keep — from $9/mo: %s", upgradeURL)
}
return "Works for 24h free. Claim to keep — from $9/mo: https://instanode.dev/start"
return "Works for 24h free. Claim to keep — from $9/mo: " + urls.StartURLPrefix
}

// limitExceededNote builds the note for the rate-limit-exceeded path.
Expand All @@ -196,7 +197,7 @@ func limitExceededNote(upgradeURL string, expiresAt time.Time) string {
if upgradeURL != "" {
return fmt.Sprintf("Returning your existing resource.%s Claim to keep — from $9/mo: %s", expiry, upgradeURL)
}
return fmt.Sprintf("Returning your existing resource.%s Claim to keep — from $9/mo: https://instanode.dev/start", expiry)
return fmt.Sprintf("Returning your existing resource.%s Claim to keep — from $9/mo: %s", expiry, urls.StartURLPrefix)
}

// formatDuration formats a duration as "Xh Ym" or "Xm".
Expand Down
10 changes: 5 additions & 5 deletions internal/handlers/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ package handlers
import (
"context"
"database/sql"
"fmt"
"log/slog"
"time"

Expand All @@ -34,6 +33,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/metrics"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/plans"
"instant.dev/internal/provisioner"
Expand Down Expand Up @@ -83,7 +83,7 @@ func (h *QueueHandler) provisionQueue(ctx context.Context, token, tier string) (
func (h *QueueHandler) NewQueue(c *fiber.Ctx) error {
if !h.cfg.IsServiceEnabled("queue") {
return respondError(c, fiber.StatusServiceUnavailable, "service_disabled",
"NATS JetStream provisioning is coming in Phase 4. Sign up at https://instanode.dev/start to be notified.")
"NATS JetStream provisioning is coming in Phase 4. Sign up at "+urls.StartURLPrefix+" to be notified.")
}

start := time.Now()
Expand All @@ -110,7 +110,7 @@ func (h *QueueHandler) NewQueue(c *fiber.Ctx) error {
// ── Dedicated requires authentication ─────────────────────────────────────
if body.Dedicated {
return respondError(c, fiber.StatusPaymentRequired, "auth_required",
"isolated resources require an authenticated team. Sign up at https://instanode.dev/start")
"isolated resources require an authenticated team. Sign up at "+urls.StartURLPrefix)
}

// ── Anonymous path ─────────────────────────────────────────────────────────
Expand All @@ -132,7 +132,7 @@ func (h *QueueHandler) NewQueue(c *fiber.Ctx) error {
}
upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}
// Decrypt the stored connection_url to return it in plaintext.
Expand Down Expand Up @@ -227,7 +227,7 @@ func (h *QueueHandler) NewQueue(c *fiber.Ctx) error {

upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}

Expand Down
7 changes: 4 additions & 3 deletions internal/handlers/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/manifest"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/plans"
compute "instant.dev/internal/providers/compute"
Expand Down Expand Up @@ -84,7 +85,7 @@ func (h *StackHandler) requireStackTeam(c *fiber.Ctx) (*models.Team, error) {
teamIDStr := middleware.GetTeamID(c)
if teamIDStr == "" {
return nil, respondError(c, fiber.StatusUnauthorized, "unauthorized",
"A session token is required for this action. Sign in at https://instanode.dev/start")
"A session token is required for this action. Sign in at "+urls.StartURLPrefix)
}
teamUUID, err := parseTeamID(teamIDStr)
if err != nil {
Expand Down Expand Up @@ -355,7 +356,7 @@ func (h *StackHandler) New(c *fiber.Ctx) error {
return c.Status(fiber.StatusTooManyRequests).JSON(fiber.Map{
"ok": false,
"error": "rate_limit_exceeded",
"message": "Anonymous deploy limit reached. Upgrade at https://instanode.dev/start",
"message": "Anonymous deploy limit reached. Upgrade at "+urls.StartURLPrefix,
})
}
}
Expand Down Expand Up @@ -646,7 +647,7 @@ func (h *StackHandler) New(c *fiber.Ctx) error {
// Step 9: Return 202.
noteMsg := "Stack is building. Poll GET /stacks/" + slug + " for status."
if anon {
noteMsg += " Anonymous stacks expire in 24h. Upgrade at https://instanode.dev/start"
noteMsg += " Anonymous stacks expire in 24h. Upgrade at "+urls.StartURLPrefix+""
}
if len(warnings) > 0 {
noteMsg = fmt.Sprintf("%d warning(s) from manifest parsing. %s", len(warnings), noteMsg)
Expand Down
5 changes: 3 additions & 2 deletions internal/handlers/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
"instant.dev/internal/crypto"
"instant.dev/internal/metrics"
"instant.dev/internal/middleware"
"instant.dev/internal/urls"
"instant.dev/internal/models"
"instant.dev/internal/plans"
storageprovider "instant.dev/internal/providers/storage"
Expand Down Expand Up @@ -123,7 +124,7 @@ func (h *StorageHandler) NewStorage(c *fiber.Ctx) error {
}
upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}
metrics.FingerprintAbuseBlocked.Inc()
Expand Down Expand Up @@ -212,7 +213,7 @@ func (h *StorageHandler) NewStorage(c *fiber.Ctx) error {

upgradeURL := ""
if jwtToken != "" {
upgradeURL = fmt.Sprintf("https://instanode.dev/start?t=%s", jwtToken)
upgradeURL = urls.UpgradeStartURL(jwtToken)
c.Set("X-Instant-Upgrade", upgradeURL)
}

Expand Down
Loading