package internal import ( "bytes" "encoding/json" "errors" "fmt" "os" "path/filepath" "go.salty.im/saltyim" ) const ( wellknownPath = ".well-known/salty" avatarsPath = "avatars" avatarResolution = 80 // 80x80 px blobsPath = "blobs" ) var ( ErrAddressExists = errors.New("error: address already exists") ErrBlobNotFound = errors.New("error: blob not found") ) func CreateConfig(conf *Config, hash string, key string) error { p := filepath.Join(conf.Data, wellknownPath) p = saltyim.FixUnixHome(p) fn := filepath.Join(p, fmt.Sprintf("%s.json", hash)) if FileExists(fn) { return ErrAddressExists } if err := os.MkdirAll(p, 0755); err != nil { return fmt.Errorf("error creating config paths %s: %w", p, err) } ulid, err := saltyim.GenerateULID() if err != nil { return fmt.Errorf("error generating ulid") } endpointURL := *conf.baseURL endpointURL.Path = fmt.Sprintf("/inbox/%s", ulid) config := saltyim.Config{ Endpoint: endpointURL.String(), Key: key, } data, err := json.Marshal(config) if err != nil { return fmt.Errorf("error serializing config") } if err := os.WriteFile(fn, data, 0644); err != nil { return fmt.Errorf("error writing config to %s: %w", fn, err) } return nil } func CreateOrUpdateAvatar(conf *Config, addr saltyim.Addr, contents []byte) error { p := filepath.Join(conf.Data, avatarsPath) p = saltyim.FixUnixHome(p) if err := os.MkdirAll(p, 0755); err != nil { return fmt.Errorf("error creating avatars paths %s: %w", p, err) } fn := filepath.Join(p, fmt.Sprintf("%s.png", addr.Hash())) if err := SaveAvatar(fn, bytes.NewBuffer(contents), avatarResolution); err != nil { return fmt.Errorf("error writing avatar %s: %w", fn, err) } return nil } func CreateOrUpdateBlob(conf *Config, key string, data []byte, signer string) error { p := filepath.Join(conf.Data, blobsPath, signer) p = saltyim.FixUnixHome(p) if err := os.MkdirAll(p, 0755); err != nil { return fmt.Errorf("error creating blobs paths %s: %w", p, err) } fn := filepath.Join(p, key) if err := os.WriteFile(fn, data, os.FileMode(0644)); err != nil { return fmt.Errorf("error writing blob %s: %w", fn, err) } return nil } func GetBlob(conf *Config, key string, signer string) (*saltyim.Blob, error) { p := filepath.Join(conf.Data, blobsPath, signer) p = saltyim.FixUnixHome(p) if err := os.MkdirAll(p, 0755); err != nil { return nil, fmt.Errorf("error creating blobs paths %s: %w", p, err) } fn := filepath.Join(p, key) if !FileExists(fn) { return nil, ErrBlobNotFound } return saltyim.OpenBlob(fn) } func DeleteBlob(conf *Config, key string, signer string) error { p := filepath.Join(conf.Data, blobsPath, signer) p = saltyim.FixUnixHome(p) if err := os.MkdirAll(p, 0755); err != nil { return fmt.Errorf("error creating blobs paths %s: %w", p, err) } fn := filepath.Join(p, key) if !FileExists(fn) { return ErrBlobNotFound } // TODO: Delete the .json properties metadata files too return os.Remove(fn) }