95 lines
2.9 KiB
Go
95 lines
2.9 KiB
Go
package keys
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/go-errors/errors"
|
|
"github.com/go-git/go-git/v5"
|
|
"github.com/spf13/afero"
|
|
"github.com/supabase/cli/internal/utils"
|
|
"github.com/supabase/cli/pkg/config"
|
|
)
|
|
|
|
type CustomName struct {
|
|
DbHost string `env:"db.host,default=NEXT_PUBLIC_SUPABASE_URL"`
|
|
DbPassword string `env:"db.password,default=SUPABASE_DB_PASSWORD"`
|
|
JWTSecret string `env:"db.password,default=SUPABASE_AUTH_JWT_SECRET"`
|
|
AnonKey string `env:"auth.anon_key,default=SUPABASE_AUTH_ANON_KEY"`
|
|
ServiceRoleKey string `env:"auth.service_role_key,default=SUPABASE_AUTH_SERVICE_ROLE_KEY"`
|
|
}
|
|
|
|
func Run(ctx context.Context, projectRef, format string, names CustomName, fsys afero.Fs) error {
|
|
branch := GetGitBranch(fsys)
|
|
if err := GenerateSecrets(ctx, projectRef, branch, fsys); err != nil {
|
|
return err
|
|
}
|
|
return utils.EncodeOutput(format, os.Stdout, map[string]string{
|
|
names.DbHost: fmt.Sprintf("%s-%s.fly.dev", projectRef, branch),
|
|
names.DbPassword: utils.Config.Db.Password,
|
|
names.JWTSecret: utils.Config.Auth.JwtSecret,
|
|
names.AnonKey: utils.Config.Auth.AnonKey,
|
|
names.ServiceRoleKey: utils.Config.Auth.ServiceRoleKey,
|
|
})
|
|
}
|
|
|
|
func GenerateSecrets(ctx context.Context, projectRef, branch string, fsys afero.Fs) error {
|
|
// Load JWT secret from api
|
|
resp, err := utils.GetSupabase().V1GetPostgrestServiceConfigWithResponse(ctx, projectRef)
|
|
if err != nil {
|
|
return errors.Errorf("failed to get postgrest config: %w", err)
|
|
}
|
|
if resp.JSON200 == nil {
|
|
return errors.New("Unexpected error retrieving JWT secret: " + string(resp.Body))
|
|
}
|
|
utils.Config.Auth.JwtSecret = *resp.JSON200.JwtSecret
|
|
// Generate database password
|
|
key := strings.Join([]string{
|
|
projectRef,
|
|
utils.Config.Auth.JwtSecret,
|
|
branch,
|
|
}, ":")
|
|
hash := sha256.Sum256([]byte(key))
|
|
utils.Config.Db.Password = hex.EncodeToString(hash[:])
|
|
// Generate JWT tokens
|
|
anonToken := config.CustomClaims{
|
|
Issuer: "supabase",
|
|
Ref: projectRef,
|
|
Role: "anon",
|
|
}.NewToken()
|
|
if utils.Config.Auth.AnonKey, err = anonToken.SignedString([]byte(utils.Config.Auth.JwtSecret)); err != nil {
|
|
return errors.Errorf("failed to sign anon key: %w", err)
|
|
}
|
|
serviceToken := config.CustomClaims{
|
|
Issuer: "supabase",
|
|
Ref: projectRef,
|
|
Role: "service_role",
|
|
}.NewToken()
|
|
if utils.Config.Auth.ServiceRoleKey, err = serviceToken.SignedString([]byte(utils.Config.Auth.JwtSecret)); err != nil {
|
|
return errors.Errorf("failed to sign service_role key: %w", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func GetGitBranch(fsys afero.Fs) string {
|
|
return GetGitBranchOrDefault("main", fsys)
|
|
}
|
|
|
|
func GetGitBranchOrDefault(def string, fsys afero.Fs) string {
|
|
head := os.Getenv("GITHUB_HEAD_REF")
|
|
if len(head) > 0 {
|
|
return head
|
|
}
|
|
opts := &git.PlainOpenOptions{DetectDotGit: true}
|
|
if repo, err := git.PlainOpenWithOptions(".", opts); err == nil {
|
|
if ref, err := repo.Head(); err == nil {
|
|
return ref.Name().Short()
|
|
}
|
|
}
|
|
return def
|
|
}
|