Merge remote-tracking branch 'origin/main' into brian/trail-card-tags
This commit is contained in:
2
.github/workflows/release.yaml
vendored
2
.github/workflows/release.yaml
vendored
@@ -86,7 +86,7 @@ jobs:
|
||||
# docker buildx build db/ --no-cache -t flomp/wanderer-db:$VERSION -t flomp/wanderer-db:latest --platform=linux/amd64,linux/arm64 --push
|
||||
|
||||
# Build web image
|
||||
export PUBLIC_VALHALLA_URL=https://valhalla1.openstreetmap.de
|
||||
export PUBLIC_VALHALLA_URL=https://valhalla.openstreetmap.de
|
||||
cd web
|
||||
npm ci && npm run build
|
||||
cd ..
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -3,11 +3,12 @@
|
||||
|
||||
db/pocketbase*
|
||||
|
||||
search/meilisearch
|
||||
search/meilisearch*
|
||||
search/data.ms*
|
||||
search/dumps
|
||||
|
||||
run.sh
|
||||
build*.sh
|
||||
start.*
|
||||
|
||||
data/
|
||||
data*/
|
||||
24
CHANGELOG.md
24
CHANGELOG.md
@@ -1,3 +1,25 @@
|
||||
# v0.17.0
|
||||
> [!CAUTION]
|
||||
This release contains breaking changes. They are marked with a ⚠️.
|
||||
**Please update to version v0.16.5 first before updating to v0.17.0.**
|
||||
|
||||
## Configuration
|
||||
Check the reopsitory's [`docker-compose.yml`](https://github.com/Flomp/wanderer/blob/main/docker-compose.yml) for a valid configuration.
|
||||
|
||||
- ⚠️ The PocketBase environment variable `POCKETBASE_ENCRYPTION_KEY` is now required. It requires a valid 32 character AES key as its value. To generate a key, run `openssl rand -hex 16`.
|
||||
- ⚠️ The PocketBase environment variable `ORIGIN`is now required. It must be set to the public IP or hostname (including the port) of your wanderer frontend and must equal the value set for the frontend's `ORIGIN` environment variable.
|
||||
|
||||
## Features
|
||||
- Adds federation
|
||||
- Adds rich text editor for descriptions and comments
|
||||
|
||||
## Docs
|
||||
- Adds documentation for federation
|
||||
- Restructures the documentation in three distinct parts (for users, admins & developers) for better separation of concerns
|
||||
|
||||
## Translation
|
||||
- New language: Russian (thanks @jeffscrum)
|
||||
|
||||
# v0.16.5
|
||||
|
||||
## Features
|
||||
@@ -251,7 +273,7 @@ This release contains breaking changes. Most migrations will happen automaticall
|
||||
- Fixes issue with GPX export when using Google Chrome (thanks [@tofublock](https://github.com/tofublock))
|
||||
|
||||
## Miscellaneous
|
||||
As the number of contributors to this project continues to grow (which I’m very happy about), I’ve set up a [Discord channel](https://discord.gg/MdpybUHc) for more direct communication. If you’re interested in helping with Wanderer, feel free to join!
|
||||
As the number of contributors to this project continues to grow (which I’m very happy about), I’ve set up a [Discord channel](https://discord.gg/MdpybUHc) for more direct communication. If you’re interested in helping with wanderer, feel free to join!
|
||||
|
||||
# v0.11.0
|
||||
## Features
|
||||
|
||||
@@ -44,7 +44,7 @@ The first startup can take up to 90 seconds after which you can access the front
|
||||
|
||||
> ⚠️ if you are using wanderer in a production environment make sure to change the MEILI_MASTER_KEY variable.
|
||||
|
||||
You can also run wanderer on bare-metal. Check out the [documentation](https://wanderer.to/getting-started/installation/#from-source) for a detailed how-to guide.
|
||||
You can also run wanderer on bare-metal. Check out the [documentation](https://wanderer.to/run/installation/#installation-from-source) for a detailed how-to guide.
|
||||
|
||||
## Support wanderer
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ FROM alpine:3.16
|
||||
WORKDIR /
|
||||
|
||||
COPY migrations ./migrations
|
||||
COPY templates ./templates
|
||||
|
||||
ARG TARGETARCH
|
||||
RUN echo ${TARGETARCH}
|
||||
|
||||
222
db/federation/activity.go
Normal file
222
db/federation/activity.go
Normal file
@@ -0,0 +1,222 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"database/sql"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
|
||||
"sync"
|
||||
|
||||
"github.com/go-ap/jsonld"
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
"golang.org/x/sync/semaphore"
|
||||
)
|
||||
|
||||
func PostActivity(app core.App, actor *core.Record, activity *pub.Activity, recipients []string) error {
|
||||
encryptionKey := os.Getenv("POCKETBASE_ENCRYPTION_KEY")
|
||||
if len(encryptionKey) == 0 {
|
||||
return fmt.Errorf("POCKETBASE_ENCRYPTION_KEY not set")
|
||||
}
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
algs := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
||||
postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"}
|
||||
expiresIn := 60
|
||||
|
||||
body, err := jsonld.WithContext(
|
||||
jsonld.IRI(pub.ActivityBaseURI),
|
||||
jsonld.IRI(pub.SecurityContextURI),
|
||||
).Marshal(activity)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
decryptedPrivateKey, err := security.Decrypt(actor.GetString("private_key"), encryptionKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(decryptedPrivateKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pubID := actor.GetString("iri") + "#main-key"
|
||||
|
||||
client := &http.Client{}
|
||||
var wg sync.WaitGroup
|
||||
|
||||
sem := semaphore.NewWeighted(5) // Limit to 5 concurrent sends
|
||||
|
||||
slices.Sort(recipients)
|
||||
uniqueRecipients := slices.Compact(recipients)
|
||||
|
||||
for _, v := range uniqueRecipients {
|
||||
|
||||
wg.Add(1)
|
||||
go func(inbox string) {
|
||||
defer wg.Done()
|
||||
|
||||
signer, _, err := httpsig.NewSigner(algs, httpsig.DigestSha256, postHeaders, httpsig.Signature, int64(expiresIn))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if err := sem.Acquire(context.Background(), 1); err != nil {
|
||||
app.Logger().Error(fmt.Sprintf("Semaphore acquire failed: %s", err))
|
||||
return
|
||||
}
|
||||
defer sem.Release(1)
|
||||
|
||||
buf := bytes.NewBuffer(body)
|
||||
req, err := http.NewRequest(http.MethodPost, inbox, buf)
|
||||
if err != nil {
|
||||
app.Logger().Error(fmt.Sprintf("Request creation failed: %s", err))
|
||||
return
|
||||
}
|
||||
req.Header.Add("Content-Type", "application/activity+json")
|
||||
req.Header.Add("Date", strings.ReplaceAll(time.Now().UTC().Format(time.RFC1123), "UTC", "GMT"))
|
||||
req.Header.Add("Host", req.Host)
|
||||
|
||||
if err := signer.SignRequest(privateKey, pubID, req, body); err != nil {
|
||||
app.Logger().Error(fmt.Sprintf("Signing request failed: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
app.Logger().Error(fmt.Sprintf("Error sending request to inbox %s: %s", inbox, err))
|
||||
return
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusAccepted {
|
||||
body, _ := io.ReadAll(resp.Body)
|
||||
app.Logger().Error(fmt.Sprintf("Inbox %s responded with %d: %s", inbox, resp.StatusCode, body))
|
||||
} else {
|
||||
app.Logger().Info(fmt.Sprintf("Sent %s to %s", activity.Type, inbox), "activity", activity)
|
||||
}
|
||||
|
||||
}(v)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
|
||||
func ProcessActivity(e *core.RequestEvent) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(e.Request.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var activity pub.Activity
|
||||
activity.UnmarshalJSON(body)
|
||||
|
||||
inbox := fmt.Sprintf("%s%s", origin, e.Request.Header.Get("X-Forwarded-Path"))
|
||||
|
||||
userActor, err := e.App.FindFirstRecordByData("activitypub_actors", "inbox", inbox)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
actor, err := e.App.FindFirstRecordByData("activitypub_actors", "iri", activity.Actor.GetID().String())
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
actor, err = GetActorByIRI(e.App, userActor, activity.Actor.GetID().String(), false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
verified, err := verifySignature(e.App, e.Request, actor.GetString("public_key"))
|
||||
if err != nil || !verified {
|
||||
e.App.Logger().Error(err.Error())
|
||||
return e.UnauthorizedError("Invalid http signature", err)
|
||||
}
|
||||
|
||||
switch activity.Type {
|
||||
case pub.FollowType:
|
||||
ProcessFollowActivity(e.App, actor, activity)
|
||||
case pub.AcceptType:
|
||||
ProcessAcceptActivity(e.App, actor, activity)
|
||||
case pub.UndoType:
|
||||
ProcessUndoActivity(e.App, actor, activity)
|
||||
case pub.UpdateType:
|
||||
fallthrough
|
||||
case pub.CreateType:
|
||||
ProcessCreateOrUpdateActivity(e.App, actor, activity)
|
||||
case pub.DeleteType:
|
||||
ProcessDeleteActivity(e.App, actor, activity)
|
||||
case pub.AnnounceType:
|
||||
ProcessAnnounceActivity(e.App, actor, activity)
|
||||
case pub.LikeType:
|
||||
ProcessLikeActivity(e.App, actor, activity)
|
||||
}
|
||||
return e.JSON(http.StatusOK, nil)
|
||||
}
|
||||
|
||||
func verifySignature(app core.App, req *http.Request, publicKeyPem string) (bool, error) {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return false, fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
block, _ := pem.Decode([]byte(publicKeyPem))
|
||||
if block == nil || block.Type != "PUBLIC KEY" {
|
||||
return false, fmt.Errorf("could not decode publicKeyPem to PUBLIC KEY pem block type")
|
||||
}
|
||||
|
||||
req.URL = &url.URL{
|
||||
Path: req.Header.Get("X-Forwarded-Path"),
|
||||
}
|
||||
|
||||
url, err := url.Parse(origin)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
req.Header.Set("Host", url.Host)
|
||||
req.Host = url.Host
|
||||
|
||||
app.Logger().Info(req.Header.Get("signature"))
|
||||
|
||||
publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
v, err := httpsig.NewVerifier(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
err = v.Verify(publicKey, httpsig.RSA_SHA256)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
368
db/federation/actor.go
Normal file
368
db/federation/actor.go
Normal file
@@ -0,0 +1,368 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/go-fed/httpsig"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
type WebfingerResponse struct {
|
||||
Subject string `json:"subject"`
|
||||
Links []struct {
|
||||
Rel string `json:"rel"`
|
||||
Href string `json:"href"`
|
||||
} `json:"links"`
|
||||
}
|
||||
|
||||
func SplitHandle(handle string) (string, string) {
|
||||
|
||||
cleaned := strings.TrimPrefix(handle, "@")
|
||||
cleaned = strings.TrimSpace(cleaned)
|
||||
|
||||
if !strings.Contains(cleaned, "@") {
|
||||
return cleaned, ""
|
||||
}
|
||||
|
||||
parts := strings.SplitN(cleaned, "@", 2)
|
||||
user := parts[0]
|
||||
domain := parts[1]
|
||||
|
||||
return user, domain
|
||||
}
|
||||
|
||||
func GetActorByHandle(app core.App, actor *core.Record, handle string, includeFollows bool) (*core.Record, error) {
|
||||
username, domain := SplitHandle(handle)
|
||||
|
||||
filter := "preferred_username={:username}&&"
|
||||
if domain != "" {
|
||||
filter += "domain={:domain}"
|
||||
} else {
|
||||
filter += "isLocal=true"
|
||||
}
|
||||
|
||||
var dbActor *core.Record
|
||||
dbActor, err := app.FindFirstRecordByFilter("activitypub_actors", filter, dbx.Params{"username": username, "domain": domain})
|
||||
if err != nil && err == sql.ErrNoRows {
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_actors")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbActor = core.NewRecord(collection)
|
||||
dbActor.Set("isLocal", false)
|
||||
iri, err := iriFromHandle(domain, username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbActor.Set("iri", iri)
|
||||
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return assembleActor(actor, dbActor, app, includeFollows)
|
||||
}
|
||||
|
||||
func GetActorByIRI(app core.App, actor *core.Record, iri string, includeFollows bool) (*core.Record, error) {
|
||||
var dbActor *core.Record
|
||||
dbActor, err := app.FindFirstRecordByFilter("activitypub_actors", "iri={:iri}", dbx.Params{"iri": iri})
|
||||
if err != nil && err == sql.ErrNoRows {
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_actors")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbActor = core.NewRecord(collection)
|
||||
dbActor.Set("isLocal", false)
|
||||
dbActor.Set("iri", iri)
|
||||
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return assembleActor(actor, dbActor, app, includeFollows)
|
||||
}
|
||||
|
||||
func iriFromHandle(domain string, username string) (string, error) {
|
||||
client := &http.Client{}
|
||||
|
||||
webfingerURL := fmt.Sprintf("http://%s/.well-known/webfinger?resource=acct:%s@%s", domain, username, domain)
|
||||
resp, err := client.Get(webfingerURL)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return "", fmt.Errorf("webfinger request failed: %v", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var wf WebfingerResponse
|
||||
if err := json.NewDecoder(resp.Body).Decode(&wf); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, link := range wf.Links {
|
||||
if link.Rel == "self" {
|
||||
return link.Href, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("no iri in response")
|
||||
}
|
||||
|
||||
func assembleActor(actor *core.Record, dbActor *core.Record, app core.App, includeFollows bool) (*core.Record, error) {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return nil, fmt.Errorf("ORIGIN environment variable not set")
|
||||
}
|
||||
|
||||
private := false
|
||||
if dbActor.GetBool("isLocal") {
|
||||
user, err := app.FindRecordById("users", dbActor.GetString("user"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
settings, err := app.FindFirstRecordByData("settings", "user", user.Id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if user.GetString("avatar") != "" {
|
||||
dbActor.Set("icon", fmt.Sprintf("%s/api/v1/files/users/%s/%s", origin, user.Id, user.GetString("avatar")))
|
||||
}
|
||||
dbActor.Set("summary", settings.GetString("bio"))
|
||||
followerCount, err := app.CountRecords("follows", dbx.NewExp("followee={:user}", dbx.Params{"user": dbActor.Id}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbActor.Set("followerCount", followerCount)
|
||||
followingCount, err := app.CountRecords("follows", dbx.NewExp("follower={:user}", dbx.Params{"user": dbActor.Id}))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbActor.Set("followingCount", followingCount)
|
||||
|
||||
dbActor.Set("last_fetched", time.Now())
|
||||
|
||||
privacy := settings.GetString("privacy")
|
||||
result := make(map[string]interface{})
|
||||
json.Unmarshal([]byte(privacy), &result)
|
||||
|
||||
private = result["account"] == "private"
|
||||
|
||||
} else {
|
||||
|
||||
// check if value is still cached
|
||||
twoHoursAgo := time.Now().Add(-2 * time.Hour)
|
||||
if !includeFollows && dbActor.GetDateTime("last_fetched").Time().After(twoHoursAgo) {
|
||||
return dbActor, nil
|
||||
}
|
||||
pubActor, followers, following, err := fetchRemoteActor(actor, dbActor.GetString("iri"), includeFollows)
|
||||
if err != nil {
|
||||
if dbActor.Id != "" {
|
||||
return dbActor, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
icon := ""
|
||||
if pub.IsObject(pubActor.Icon) {
|
||||
iconObject, err := pub.ToObject(pubActor.Icon)
|
||||
if err == nil && iconObject.URL != nil {
|
||||
icon = iconObject.URL.GetID().String()
|
||||
}
|
||||
}
|
||||
|
||||
parsedUrl, err := url.Parse(dbActor.GetString("iri"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
domain := strings.TrimPrefix(parsedUrl.Hostname(), "www.")
|
||||
|
||||
dbActor.Set("domain", domain)
|
||||
dbActor.Set("followers", pubActor.Followers.GetID().String())
|
||||
dbActor.Set("inbox", pubActor.Inbox.GetID().String())
|
||||
dbActor.Set("iri", pubActor.GetID().String())
|
||||
dbActor.Set("username", pubActor.Name.String())
|
||||
dbActor.Set("preferred_username", pubActor.PreferredUsername.String())
|
||||
dbActor.Set("following", pubActor.Following.GetID().String())
|
||||
dbActor.Set("summary", pubActor.Summary.String())
|
||||
dbActor.Set("outbox", pubActor.Outbox.GetID().String())
|
||||
dbActor.Set("icon", icon)
|
||||
dbActor.Set("published", pubActor.Published.String())
|
||||
dbActor.Set("public_key", pubActor.PublicKey.PublicKeyPem)
|
||||
dbActor.Set("last_fetched", time.Now())
|
||||
|
||||
if includeFollows {
|
||||
dbActor.Set("followerCount", int(followers.TotalItems))
|
||||
dbActor.Set("followingCount", int(following.TotalItems))
|
||||
}
|
||||
}
|
||||
|
||||
err := app.Save(dbActor)
|
||||
if err != nil && err.Error() == "iri: Value must be unique." {
|
||||
dbActor, err = app.FindFirstRecordByData("activitypub_actors", "iri", dbActor.GetString("iri"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dbActor, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if private {
|
||||
return dbActor, fmt.Errorf("profile is private")
|
||||
}
|
||||
|
||||
return dbActor, nil
|
||||
}
|
||||
|
||||
// Fetches an AP actor and optionally followers/following collections
|
||||
func fetchRemoteActor(actor *core.Record, iri string, includeFollows bool) (*pub.Actor, *pub.OrderedCollection, *pub.OrderedCollection, error) {
|
||||
encryptionKey := os.Getenv("POCKETBASE_ENCRYPTION_KEY")
|
||||
if len(encryptionKey) == 0 {
|
||||
return nil, nil, nil, fmt.Errorf("POCKETBASE_ENCRYPTION_KEY not set")
|
||||
}
|
||||
|
||||
client := &http.Client{}
|
||||
req, _ := http.NewRequest("GET", iri, nil)
|
||||
|
||||
headers := map[string]string{
|
||||
"Accept": "application/ld+json",
|
||||
"Content-Type": "application/activity+json",
|
||||
"Date": strings.ReplaceAll(time.Now().UTC().Format(time.RFC1123), "UTC", "GMT"),
|
||||
"Host": req.Host,
|
||||
}
|
||||
|
||||
for k, v := range headers {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
|
||||
dbPrivateKey := actor.GetString("private_key")
|
||||
if dbPrivateKey != "" {
|
||||
algs := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
||||
postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"}
|
||||
expiresIn := 60
|
||||
|
||||
signer, _, err := httpsig.NewSigner(algs, httpsig.DigestSha256, postHeaders, httpsig.Signature, int64(expiresIn))
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
decryptedPrivateKey, err := security.Decrypt(dbPrivateKey, encryptionKey)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(decryptedPrivateKey)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
pubID := actor.GetString("iri") + "#main-key"
|
||||
|
||||
if err := signer.SignRequest(privateKey, pubID, req, []byte{}); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("actor fetch failed: %v", err)
|
||||
} else if resp.StatusCode != http.StatusOK {
|
||||
return nil, nil, nil, fmt.Errorf("actor fetch failed: status %v", resp.StatusCode)
|
||||
}
|
||||
|
||||
defer resp.Body.Close()
|
||||
|
||||
var pubActor pub.Actor
|
||||
if err := json.NewDecoder(resp.Body).Decode(&pubActor); err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
var followers, following pub.OrderedCollection
|
||||
|
||||
if includeFollows {
|
||||
// Fetch followers
|
||||
if data, err := FetchCollection(actor, pubActor.Followers.GetID().String()); err == nil {
|
||||
followers = *data
|
||||
}
|
||||
|
||||
// Fetch following
|
||||
if data, err := FetchCollection(actor, pubActor.Following.GetID().String()); err == nil {
|
||||
following = *data
|
||||
}
|
||||
}
|
||||
|
||||
return &pubActor, &followers, &following, nil
|
||||
}
|
||||
|
||||
func FetchCollection(actor *core.Record, url string) (*pub.OrderedCollection, error) {
|
||||
encryptionKey := os.Getenv("POCKETBASE_ENCRYPTION_KEY")
|
||||
if len(encryptionKey) == 0 {
|
||||
return nil, fmt.Errorf("POCKETBASE_ENCRYPTION_KEY not set")
|
||||
}
|
||||
|
||||
req, _ := http.NewRequest("GET", url, nil)
|
||||
|
||||
headers := map[string]string{
|
||||
"Accept": "application/ld+json",
|
||||
"Content-Type": "application/activity+json",
|
||||
"Date": strings.ReplaceAll(time.Now().UTC().Format(time.RFC1123), "UTC", "GMT"),
|
||||
"Host": req.Host,
|
||||
}
|
||||
|
||||
for k, v := range headers {
|
||||
req.Header.Add(k, v)
|
||||
}
|
||||
|
||||
dbPrivateKey := actor.GetString("private_key")
|
||||
if dbPrivateKey != "" {
|
||||
algs := []httpsig.Algorithm{httpsig.RSA_SHA256}
|
||||
postHeaders := []string{"(request-target)", "Date", "Digest", "Content-Type", "Host"}
|
||||
expiresIn := 60
|
||||
|
||||
signer, _, err := httpsig.NewSigner(algs, httpsig.DigestSha256, postHeaders, httpsig.Signature, int64(expiresIn))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decryptedPrivateKey, err := security.Decrypt(dbPrivateKey, encryptionKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(decryptedPrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pubID := actor.GetString("iri") + "#main-key"
|
||||
|
||||
if err := signer.SignRequest(privateKey, pubID, req, []byte{}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil || resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("collection fetch failed for %s: %v", url, err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var collection pub.OrderedCollection
|
||||
if err := json.NewDecoder(resp.Body).Decode(&collection); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &collection, nil
|
||||
}
|
||||
276
db/federation/announce.go
Normal file
276
db/federation/announce.go
Normal file
@@ -0,0 +1,276 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"pocketbase/util"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
)
|
||||
|
||||
type AnnounceType string
|
||||
|
||||
const (
|
||||
TrailAnnounceType AnnounceType = "trail"
|
||||
ListAnnounceType AnnounceType = "list"
|
||||
)
|
||||
|
||||
func CreateAnnounceActivity(app core.App, record *core.Record, typ AnnounceType) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
var subject *core.Record
|
||||
var object pub.Item
|
||||
var err error
|
||||
if typ == TrailAnnounceType {
|
||||
subject, err = app.FindRecordById("trails", record.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
object, err = util.ObjectFromTrail(app, subject, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if typ == ListAnnounceType {
|
||||
subject, err = app.FindRecordById("lists", record.GetString("list"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
object, err = util.ObjectFromList(app, subject)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
} else {
|
||||
return fmt.Errorf("unknown announce type")
|
||||
}
|
||||
|
||||
subjectActor, err := app.FindRecordById("activitypub_actors", subject.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
objectActor, err := app.FindRecordById("activitypub_actors", record.GetString("actor"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := objectActor.GetString("iri")
|
||||
actor := subjectActor.GetString("iri")
|
||||
|
||||
activity := pub.AnnounceNew(pub.IRI(id), object)
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.Actor = pub.IRI(actor)
|
||||
activity.Tag = pub.ItemCollection{
|
||||
pub.Object{
|
||||
Type: pub.NoteType,
|
||||
Name: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, "permission")),
|
||||
Content: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, record.GetString("permission"))),
|
||||
},
|
||||
}
|
||||
|
||||
err = PostActivity(app, subjectActor, activity, []string{objectActor.GetString("inbox")})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activityRecord := core.NewRecord(collection)
|
||||
activityRecord.Set("id", recordId)
|
||||
activityRecord.Set("iri", id)
|
||||
activityRecord.Set("to", []string{to})
|
||||
activityRecord.Set("type", string(pub.AnnounceType))
|
||||
activityRecord.Set("object", object)
|
||||
activityRecord.Set("actor", actor)
|
||||
activityRecord.Set("published", time.Now())
|
||||
|
||||
return app.Save(activityRecord)
|
||||
}
|
||||
|
||||
// process incoming announce activity
|
||||
func ProcessAnnounceActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
object := activity.Object.GetID().String()
|
||||
|
||||
if strings.Contains(object, "/api/v1/trail") {
|
||||
processTrailAnnounceActivity(app, actor, activity)
|
||||
|
||||
} else if strings.Contains(object, "/api/v1/list") {
|
||||
processListAnnounceActivity(app, actor, activity)
|
||||
} else {
|
||||
return fmt.Errorf("unknown announce type")
|
||||
}
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func processTrailAnnounceActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
objectActor, err := app.FindFirstRecordByData("activitypub_actors", "iri", activity.To[0].GetID().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var trail *core.Record
|
||||
if !actor.GetBool("isLocal") {
|
||||
trail, err = util.TrailFromActivity(activity, app, actor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
permission := "view"
|
||||
// tags, err := pub.ToItemCollection(activity.Tag)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// for _, tag := range tags.Collection() {
|
||||
// tagObj, err := pub.ToObject(tag)
|
||||
// if err != nil {
|
||||
// continue
|
||||
// }
|
||||
// name := tagObj.Name.First().Value.String()
|
||||
// content := tagObj.Content.First().Value.String()
|
||||
// if name == "permission" {
|
||||
// permission = content
|
||||
// }
|
||||
// }
|
||||
|
||||
record, err := app.FindFirstRecordByFilter("trail_share", "trail={:trailId}&&actor={:actorId}", dbx.Params{"trailId": trail.Id, "actorId": objectActor.Id})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
collection, err := app.FindCollectionByNameOrId("trail_share")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
record = core.NewRecord(collection)
|
||||
record.Set("trail", trail.Id)
|
||||
record.Set("actor", objectActor.Id)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
record.Set("permission", permission)
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
trailUrl, err := url.Parse(activity.Object.GetID().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trailId := path.Base(trailUrl.Path)
|
||||
trail, err = app.FindRecordById("trails", trailId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
notification := util.Notification{
|
||||
Type: util.TrailShare,
|
||||
Metadata: map[string]string{
|
||||
"id": trail.Id,
|
||||
"trail": trail.GetString("name"),
|
||||
"author": fmt.Sprintf("@%s@%s", actor.GetString("preferred_username"), actor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
err = util.SendNotification(app, notification, objectActor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processListAnnounceActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
objectActor, err := app.FindFirstRecordByData("activitypub_actors", "iri", activity.To[0].GetID().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var list *core.Record
|
||||
if !actor.GetBool("isLocal") {
|
||||
list, err = util.ListFromActivity(activity, app, actor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record, err := app.FindFirstRecordByFilter("list_share", "list={:listId}&&actor={:actorId}", dbx.Params{"listId": list.Id, "actorId": objectActor.Id})
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
collection, err := app.FindCollectionByNameOrId("list_share")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
record = core.NewRecord(collection)
|
||||
record.Set("list", list.Id)
|
||||
record.Set("actor", objectActor.Id)
|
||||
record.Set("permission", "view")
|
||||
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
listUrl, err := url.Parse(activity.Object.GetID().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
listId := path.Base(listUrl.Path)
|
||||
list, err = app.FindRecordById("trails", listId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
notification := util.Notification{
|
||||
Type: util.ListShare,
|
||||
Metadata: map[string]string{
|
||||
"id": list.Id,
|
||||
"list": list.GetString("name"),
|
||||
"author": fmt.Sprintf("@%s@%s", actor.GetString("preferred_username"), actor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
err = util.SendNotification(app, notification, objectActor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
849
db/federation/create.go
Normal file
849
db/federation/create.go
Normal file
@@ -0,0 +1,849 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"pocketbase/util"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/filesystem"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
"golang.org/x/net/html"
|
||||
)
|
||||
|
||||
func CreateTrailActivity(app core.App, actor *core.Record, trail *core.Record, typ pub.ActivityVocabularyType) error {
|
||||
if !trail.GetBool("public") {
|
||||
// only broadcast the trail if it is public
|
||||
return nil
|
||||
}
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
mentionedActors, handles, err := ActorsFromMentions(app, actor, trail.GetString("description"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mentions := []string{}
|
||||
cc := pub.ItemCollection{pub.IRI(trailAuthor.GetString("followers"))}
|
||||
tags := pub.ItemCollection{}
|
||||
for i, m := range mentionedActors {
|
||||
inbox := m.GetString("inbox")
|
||||
mention := pub.MentionNew(pub.IRI(m.GetString("iri")))
|
||||
mention.Href = pub.IRI(m.GetString("iri"))
|
||||
mention.Name = pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, handles[i]))
|
||||
tags.Append(mention)
|
||||
|
||||
mentions = append(mentions, inbox)
|
||||
cc.Append(pub.IRI(inbox))
|
||||
}
|
||||
|
||||
trailObject, err := util.ObjectFromTrail(app, trail, &tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.ActivityNew(pub.IRI(id), typ, trailObject)
|
||||
activity.Actor = pub.IRI(trailAuthor.GetString("iri"))
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.CC = cc
|
||||
activity.Published = time.Now()
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("to", []string{to})
|
||||
record.Set("cc", cc)
|
||||
record.Set("type", string(typ))
|
||||
record.Set("object", trailObject)
|
||||
record.Set("actor", trailAuthor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": trailAuthor.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recipients := mentions
|
||||
for _, f := range follows {
|
||||
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients = append(recipients, follower.GetString("inbox"))
|
||||
}
|
||||
|
||||
return PostActivity(app, trailAuthor, activity, recipients)
|
||||
}
|
||||
|
||||
func CreateCommentActivity(app core.App, actor *core.Record, comment *core.Record, typ pub.ActivityVocabularyType) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
// author of the comment
|
||||
commentAuthor, err := app.FindRecordById("activitypub_actors", comment.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commentTrail, err := app.FindRecordById("trails", comment.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
commentTrailAuthor, err := app.FindRecordById("activitypub_actors", commentTrail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activityRecordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, activityRecordId)
|
||||
to := "https://www.w3.org/ns/activitystreams#Public"
|
||||
|
||||
mentionedActors, handles, err := ActorsFromMentions(app, actor, comment.GetString("text"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients := []string{}
|
||||
tags := pub.ItemCollection{}
|
||||
for i, m := range mentionedActors {
|
||||
mention := pub.MentionNew(pub.IRI(m.GetString("iri")))
|
||||
mention.Href = pub.IRI(m.GetString("iri"))
|
||||
mention.Name = pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, handles[i]))
|
||||
tags.Append(mention)
|
||||
|
||||
recipients = append(recipients, m.GetString("inbox"))
|
||||
}
|
||||
recipients = append(recipients, commentTrailAuthor.GetString("inbox"))
|
||||
|
||||
cc := pub.ItemCollection{}
|
||||
for _, r := range recipients {
|
||||
cc.Append(pub.IRI(r))
|
||||
}
|
||||
|
||||
author := commentAuthor.GetString("iri")
|
||||
|
||||
commentObject, err := util.ObjectFromComment(app, comment, &tags)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.ActivityNew(pub.IRI(id), typ, commentObject)
|
||||
activity.Actor = pub.IRI(author)
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.CC = cc
|
||||
activity.Published = time.Now()
|
||||
activity.Object = commentObject
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", activityRecordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("to", []string{to})
|
||||
record.Set("cc", recipients)
|
||||
record.Set("type", string(typ))
|
||||
record.Set("object", commentObject)
|
||||
record.Set("actor", author)
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return PostActivity(app, commentAuthor, activity, recipients)
|
||||
|
||||
}
|
||||
|
||||
func CreateSummitLogActivity(app core.App, actor *core.Record, summitLog *core.Record, typ pub.ActivityVocabularyType) error {
|
||||
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
summitLogAuthor, err := app.FindRecordById("activitypub_actors", summitLog.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var summitLogAuthorId string
|
||||
// first check if we find the trail locally
|
||||
summitLogTrail, err := app.FindRecordById("trails", summitLog.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !summitLogTrail.GetBool("public") {
|
||||
// only broadcast the log if the trail it belongs to is public
|
||||
return nil
|
||||
}
|
||||
summitLogAuthorId = summitLogTrail.GetString("author")
|
||||
|
||||
summitLogTrailAuthor, err := app.FindRecordById("activitypub_actors", summitLogAuthorId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var trailIRI pub.IRI
|
||||
if summitLogTrailAuthor.GetBool("isLocal") {
|
||||
trailId := summitLog.GetString("trail")
|
||||
trailIRI = pub.IRI(fmt.Sprintf("%s/api/v1/trail/%s", origin, trailId))
|
||||
} else {
|
||||
trailIRI = pub.IRI(summitLogTrail.GetString("iri"))
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := pub.ItemCollection{pub.IRI("https://www.w3.org/ns/activitystreams#Public")}
|
||||
|
||||
// someone else created the summit log on the trail -> inform the trail's author
|
||||
if summitLogAuthor.Id != summitLogTrailAuthor.Id {
|
||||
to.Append(pub.IRI(summitLogTrailAuthor.GetString("iri")))
|
||||
}
|
||||
|
||||
mentionedActors, handles, err := ActorsFromMentions(app, actor, summitLog.GetString("text"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mentions := []string{}
|
||||
cc := pub.ItemCollection{pub.IRI(summitLogAuthor.GetString("followers"))}
|
||||
mentionTags := pub.ItemCollection{}
|
||||
for i, m := range mentionedActors {
|
||||
inbox := m.GetString("inbox")
|
||||
mention := pub.MentionNew(pub.IRI(m.GetString("iri")))
|
||||
mention.Href = pub.IRI(m.GetString("iri"))
|
||||
mention.Name = pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, handles[i]))
|
||||
mentionTags.Append(mention)
|
||||
|
||||
mentions = append(mentions, inbox)
|
||||
cc.Append(pub.IRI(inbox))
|
||||
}
|
||||
|
||||
photos := summitLog.GetStringSlice("photos")
|
||||
|
||||
gpx := ""
|
||||
if summitLog.GetString("gpx") != "" {
|
||||
gpx = fmt.Sprintf("%s/api/v1/files/summit_logs/%s/%s", origin, summitLog.Id, summitLog.GetString("gpx"))
|
||||
}
|
||||
|
||||
attachments := make(pub.ItemCollection, max(len(photos), 2))
|
||||
for i := range len(photos) {
|
||||
iri := fmt.Sprintf("%s/api/v1/files/summit_logs/%s/%s", origin, summitLog.Id, photos[i])
|
||||
|
||||
attachments[i] = pub.Document{
|
||||
Type: pub.ImageType,
|
||||
MediaType: "image/jpeg",
|
||||
URL: pub.IRI(iri),
|
||||
}
|
||||
}
|
||||
if gpx != "" {
|
||||
attachments.Append(pub.Document{
|
||||
Type: pub.DocumentType,
|
||||
MediaType: "application/xml+gpx",
|
||||
URL: pub.IRI(gpx),
|
||||
})
|
||||
}
|
||||
|
||||
tags := pub.ItemCollection{
|
||||
pub.Object{
|
||||
Type: pub.NoteType,
|
||||
Name: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, "elevation_gain")),
|
||||
Content: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, fmt.Sprintf("%fm", summitLog.GetFloat("elevation_gain")))),
|
||||
},
|
||||
pub.Object{
|
||||
Type: pub.NoteType,
|
||||
Name: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, "elevation_loss")),
|
||||
Content: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, fmt.Sprintf("%fm", summitLog.GetFloat("elevation_loss")))),
|
||||
},
|
||||
pub.Object{
|
||||
Type: pub.NoteType,
|
||||
Name: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, "distance")),
|
||||
Content: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, fmt.Sprintf("%fm", summitLog.GetFloat("distance")))),
|
||||
},
|
||||
pub.Object{
|
||||
Type: pub.NoteType,
|
||||
Name: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, "duration")),
|
||||
Content: pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, fmt.Sprintf("%fm", summitLog.GetFloat("duration")))),
|
||||
},
|
||||
}
|
||||
|
||||
for _, m := range mentionTags {
|
||||
tags.Append(m)
|
||||
}
|
||||
|
||||
logObject := pub.ObjectNew(pub.NoteType)
|
||||
|
||||
logObject.Content = pub.NaturalLanguageValuesNew(pub.LangRefValueNew(pub.NilLangRef, summitLog.GetString("text")))
|
||||
logObject.AttributedTo = pub.IRI(summitLogAuthor.GetString("iri"))
|
||||
logObject.Published = summitLog.GetDateTime("created").Time()
|
||||
logObject.ID = pub.IRI(fmt.Sprintf("%s/api/v1/summit-log/%s", origin, summitLog.Id))
|
||||
logObject.URL = pub.IRI(fmt.Sprintf("%s/trail/view/@%s/%s", origin, summitLogTrailAuthor.GetString("preferred_username"), summitLog.GetString("trail")))
|
||||
logObject.InReplyTo = trailIRI
|
||||
logObject.Tag = tags
|
||||
|
||||
logObject.StartTime = summitLog.GetDateTime("date").Time()
|
||||
logObject.Attachment = attachments
|
||||
|
||||
activity := pub.ActivityNew(pub.IRI(id), typ, logObject)
|
||||
activity.Actor = pub.IRI(summitLogAuthor.GetString("iri"))
|
||||
activity.To = to
|
||||
activity.CC = cc
|
||||
activity.Published = time.Now()
|
||||
|
||||
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": summitLogAuthor.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recipients := mentions
|
||||
|
||||
for _, f := range follows {
|
||||
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients = append(recipients, follower.GetString("inbox"))
|
||||
}
|
||||
|
||||
if summitLogAuthor.Id != summitLogTrailAuthor.Id {
|
||||
recipients = append(recipients, summitLogTrailAuthor.GetString("inbox"))
|
||||
}
|
||||
|
||||
err = PostActivity(app, summitLogAuthor, activity, recipients)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("to", to)
|
||||
record.Set("cc", cc)
|
||||
record.Set("type", string(typ))
|
||||
record.Set("object", logObject)
|
||||
record.Set("actor", summitLogAuthor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
func CreateListActivity(app core.App, list *core.Record, typ pub.ActivityVocabularyType) error {
|
||||
if !list.GetBool("public") {
|
||||
// only broadcast the list if it is public
|
||||
return nil
|
||||
}
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
// author of the list
|
||||
listAuthor, err := app.FindRecordById("activitypub_actors", list.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activityRecordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, activityRecordId)
|
||||
to := "https://www.w3.org/ns/activitystreams#Public"
|
||||
cc := listAuthor.GetString("followers")
|
||||
author := listAuthor.GetString("iri")
|
||||
|
||||
listObject, err := util.ObjectFromList(app, list)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.ActivityNew(pub.IRI(id), typ, listObject)
|
||||
activity.Actor = pub.IRI(author)
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.CC = pub.ItemCollection{pub.IRI(cc)}
|
||||
activity.Published = time.Now()
|
||||
activity.Object = listObject
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": listAuthor.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recipients := []string{}
|
||||
for _, f := range follows {
|
||||
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients = append(recipients, follower.GetString("inbox"))
|
||||
}
|
||||
|
||||
err = PostActivity(app, listAuthor, activity, recipients)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", activityRecordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("to", []string{to})
|
||||
record.Set("cc", []string{cc})
|
||||
record.Set("type", string(typ))
|
||||
record.Set("object", listObject)
|
||||
record.Set("actor", author)
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
func ProcessCreateOrUpdateActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
var err error
|
||||
if strings.Contains(activity.Object.GetID().String(), "/api/v1/trail") {
|
||||
err = processCreateOrUpdateTrailActivity(activity, app, actor)
|
||||
} else if strings.Contains(activity.Object.GetID().String(), "/api/v1/summit-log") {
|
||||
err = processCreateOrUpdateSummitLogActivity(activity, app, actor)
|
||||
} else if strings.Contains(activity.Object.GetID().String(), "/api/v1/list") {
|
||||
err = processCreateOrUpdateListActivity(activity, app, actor)
|
||||
} else {
|
||||
err = processCreateOrUpdateCommentActivity(activity, app, actor)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func processCreateOrUpdateTrailActivity(activity pub.Activity, app core.App, actor *core.Record) error {
|
||||
|
||||
// no need to do anything if the actor is local
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
trail, err := util.TrailFromActivity(activity, app, actor)
|
||||
|
||||
trailObject, _ := pub.ToObject(activity.Object)
|
||||
|
||||
for _, t := range trailObject.Tag {
|
||||
if t.GetType() == pub.MentionType {
|
||||
mention := t.(*pub.Mention)
|
||||
mentionedActor, err := app.FindFirstRecordByData("activitypub_actors", "iri", mention.Href.GetID().String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
notification := util.Notification{
|
||||
Type: util.TrailMention,
|
||||
Metadata: map[string]string{
|
||||
"id": trail.Id,
|
||||
"author": fmt.Sprintf("@%s@%s", actor.GetString("preferred_username"), actor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, mentionedActor)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func processCreateOrUpdateCommentActivity(activity pub.Activity, app core.App, actor *core.Record) error {
|
||||
|
||||
commentObject, err := pub.ToObject(activity.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if commentObject.InReplyTo == nil {
|
||||
return fmt.Errorf("error processing comment: InReplyTo empty")
|
||||
}
|
||||
|
||||
trailUrl, err := url.Parse(commentObject.InReplyTo.GetLink().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trailId := path.Base(trailUrl.Path)
|
||||
|
||||
var trail *core.Record
|
||||
trail, err = app.FindFirstRecordByFilter("trails", "iri={:iri} || id={:id}", dbx.Params{"id": trailId, "iri": commentObject.InReplyTo.GetID().String()})
|
||||
|
||||
// if the trail is not present on this instance fetch it
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
trailObject, err := util.TrailObjectFromIRI(commentObject.InReplyTo.GetLink().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
activity := pub.ActivityNew(pub.IRI("new"), pub.CreateType, trailObject)
|
||||
trail, err = util.TrailFromActivity(*activity, app, actor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// no need to do anything else if the actor is local
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
record, err := app.FindFirstRecordByData("comments", "iri", commentObject.ID.String())
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
collection, err := app.FindCollectionByNameOrId("comments")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record = core.NewRecord(collection)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
record.Set("iri", commentObject.ID.String())
|
||||
record.Set("text", commentObject.Content.First().Value)
|
||||
record.Set("author", actor.Id)
|
||||
record.Set("trail", trail.Id)
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// send notifications to all mentioned actors
|
||||
for _, t := range commentObject.Tag {
|
||||
if t.GetType() == pub.MentionType {
|
||||
mention := t.(*pub.Mention)
|
||||
mentionedActor, err := app.FindFirstRecordByData("activitypub_actors", "iri", mention.Href.GetID().String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
notification := util.Notification{
|
||||
Type: util.CommentMention,
|
||||
Metadata: map[string]string{
|
||||
"comment": commentObject.Content.First().Value.String(),
|
||||
"trail_id": trail.Id,
|
||||
"trail_name": trail.GetString("name"),
|
||||
"trail_author": fmt.Sprintf("@%s@%s", trailAuthor.GetString("preferred_username"), trailAuthor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, mentionedActor)
|
||||
}
|
||||
}
|
||||
if activity.Type == pub.CreateType {
|
||||
// send a notification to the trail author
|
||||
notification := util.Notification{
|
||||
Type: util.TrailComment,
|
||||
Metadata: map[string]string{
|
||||
"comment": commentObject.Content.First().Value.String(),
|
||||
"trail_id": trail.Id,
|
||||
"trail_name": trail.GetString("name"),
|
||||
"trail_author": fmt.Sprintf("@%s@%s", trailAuthor.GetString("preferred_username"), trailAuthor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, trailAuthor)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processCreateOrUpdateSummitLogActivity(activity pub.Activity, app core.App, actor *core.Record) error {
|
||||
logObject, err := pub.ToObject(activity.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trailIRI, err := url.Parse(logObject.InReplyTo.GetID().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
trailId := path.Base(trailIRI.Path)
|
||||
|
||||
trail, err := app.FindFirstRecordByFilter("trails", "iri={:iri} || id={:id}", dbx.Params{"id": trailId, "iri": logObject.InReplyTo.GetID().String()})
|
||||
// if the trail is not present on this instance fetch it
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
trailObject, err := util.TrailObjectFromIRI(logObject.InReplyTo.GetLink().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
activity := pub.ActivityNew(pub.IRI("new"), pub.CreateType, trailObject)
|
||||
trail, err = util.TrailFromActivity(*activity, app, actor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newSummitLog := false
|
||||
record, err := app.FindFirstRecordByData("summit_logs", "iri", logObject.ID.String())
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
collection, err := app.FindCollectionByNameOrId("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record = core.NewRecord(collection)
|
||||
newSummitLog = true
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// no need to do anything else if the actor is local
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
var distance, duration, elevation_gain, elevation_loss float64
|
||||
tags, err := pub.ToItemCollection(logObject.Tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, tag := range tags.Collection() {
|
||||
tagObj, err := pub.ToObject(tag)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
content := tagObj.Content.First().Value.String()
|
||||
switch tagObj.Name.First().Value.String() {
|
||||
case "elevation_gain":
|
||||
elevation_gain, err = strconv.ParseFloat(content[:len(content)-1], 64)
|
||||
case "elevation_loss":
|
||||
elevation_loss, err = strconv.ParseFloat(content[:len(content)-1], 64)
|
||||
case "duration":
|
||||
duration, err = strconv.ParseFloat(content[:len(content)-1], 64)
|
||||
case "distance":
|
||||
distance, err = strconv.ParseFloat(content[:len(content)-1], 64)
|
||||
}
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
record.Set("date", logObject.StartTime)
|
||||
record.Set("text", logObject.Content.First().Value)
|
||||
record.Set("distance", distance)
|
||||
record.Set("duration", duration)
|
||||
record.Set("elevation_gain", elevation_gain)
|
||||
record.Set("elevation_loss", elevation_loss)
|
||||
record.Set("author", actor.Id)
|
||||
record.Set("trail", trail.Id)
|
||||
record.Set("iri", logObject.ID.String())
|
||||
|
||||
if logObject.Attachment != nil {
|
||||
attachments, err := pub.ToItemCollection(logObject.Attachment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
photoURLs := []string{}
|
||||
gpxURL := ""
|
||||
for _, a := range attachments.Collection() {
|
||||
attachment, err := pub.ToObject(a)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if attachment.Type == pub.DocumentType && attachment.MediaType == "application/xml+gpx" {
|
||||
gpxURL = attachment.URL.GetLink().String()
|
||||
} else if attachment.Type == pub.ImageType {
|
||||
photoURLs = append(photoURLs, attachment.URL.GetLink().String())
|
||||
}
|
||||
}
|
||||
|
||||
if len(photoURLs) > 0 {
|
||||
photos := make([]*filesystem.File, len(photoURLs))
|
||||
for i, purl := range photoURLs {
|
||||
photo, err := filesystem.NewFileFromURL(context.Background(), purl)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
photos[i] = photo
|
||||
}
|
||||
|
||||
record.Set("photos", photos)
|
||||
}
|
||||
|
||||
if gpxURL != "" {
|
||||
gpx, err := filesystem.NewFileFromURL(context.Background(), gpxURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record.Set("gpx", gpx)
|
||||
}
|
||||
}
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// send notifications to all mentioned actors
|
||||
for _, t := range logObject.Tag {
|
||||
if t.GetType() == pub.MentionType {
|
||||
mention := t.(*pub.Mention)
|
||||
mentionedActor, err := app.FindFirstRecordByData("activitypub_actors", "iri", mention.Href.GetID().String())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
notification := util.Notification{
|
||||
Type: util.SummitLogMention,
|
||||
Metadata: map[string]string{
|
||||
"trail_id": trail.Id,
|
||||
"trail_name": trail.GetString("name"),
|
||||
"trail_author": fmt.Sprintf("@%s@%s", trailAuthor.GetString("preferred_username"), trailAuthor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, mentionedActor)
|
||||
}
|
||||
}
|
||||
|
||||
if newSummitLog {
|
||||
// send a notification to the trail author
|
||||
notification := util.Notification{
|
||||
Type: util.SummitLogCreate,
|
||||
Metadata: map[string]string{
|
||||
"trail_id": trail.Id,
|
||||
"trail_name": trail.GetString("name"),
|
||||
"trail_author": fmt.Sprintf("@%s@%s", trailAuthor.GetString("preferred_username"), trailAuthor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, trailAuthor)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processCreateOrUpdateListActivity(activity pub.Activity, app core.App, actor *core.Record) error {
|
||||
|
||||
// no need to do anything if the actor is local
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err := util.ListFromActivity(activity, app, actor)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func ActorsFromMentions(app core.App, actor *core.Record, htmlStr string) ([]*core.Record, []string, error) {
|
||||
doc, err := html.Parse(strings.NewReader(htmlStr))
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var handles []string
|
||||
var actors []*core.Record
|
||||
|
||||
var f func(*html.Node)
|
||||
f = func(n *html.Node) {
|
||||
if n.Type == html.ElementNode && n.Data == "a" {
|
||||
var isMention bool
|
||||
for _, attr := range n.Attr {
|
||||
if attr.Key == "class" && strings.Contains(attr.Val, "mention") {
|
||||
isMention = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isMention && n.FirstChild != nil && n.FirstChild.Type == html.TextNode {
|
||||
handle := strings.TrimSpace(n.FirstChild.Data)
|
||||
if strings.HasPrefix(handle, "@") {
|
||||
handles = append(handles, handle)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for c := n.FirstChild; c != nil; c = c.NextSibling {
|
||||
f(c)
|
||||
}
|
||||
}
|
||||
|
||||
f(doc)
|
||||
|
||||
for _, h := range handles {
|
||||
actor, err := GetActorByHandle(app, actor, h, false)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
actors = append(actors, actor)
|
||||
}
|
||||
|
||||
return actors, handles, nil
|
||||
}
|
||||
377
db/federation/delete.go
Normal file
377
db/federation/delete.go
Normal file
@@ -0,0 +1,377 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/meilisearch/meilisearch-go"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
func CreateTrailDeleteActivity(app core.App, r *core.Record) error {
|
||||
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
author, err := app.FindRecordById("activitypub_actors", r.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := "https://www.w3.org/ns/activitystreams#Public"
|
||||
cc := author.GetString("iri") + "/followers"
|
||||
object := fmt.Sprintf("%s/api/v1/trail/%s", origin, r.Id)
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.DeleteType))
|
||||
record.Set("to", to)
|
||||
record.Set("cc", cc)
|
||||
record.Set("object", object)
|
||||
record.Set("actor", author.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.DeleteNew(pub.IRI(id), pub.IRI(object))
|
||||
activity.Actor = pub.IRI(author.GetString("iri"))
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.CC = pub.ItemCollection{pub.IRI(cc)}
|
||||
activity.Published = time.Now()
|
||||
|
||||
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": author.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recipients := []string{}
|
||||
for _, f := range follows {
|
||||
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients = append(recipients, follower.GetString("inbox"))
|
||||
}
|
||||
|
||||
return PostActivity(app, author, activity, recipients)
|
||||
}
|
||||
|
||||
func CreateCommentDeleteActivity(app core.App, client meilisearch.ServiceManager, r *core.Record) error {
|
||||
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
author, err := app.FindRecordById("activitypub_actors", r.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !author.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
commentTrail, err := app.FindRecordById("trails", r.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
commentTrailAuthor, err := app.FindRecordById("activitypub_actors", commentTrail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if commentTrailAuthor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := commentTrailAuthor.GetString("iri")
|
||||
object := fmt.Sprintf("%s/api/v1/comment/%s", origin, r.Id)
|
||||
|
||||
activity := pub.DeleteNew(pub.IRI(id), pub.IRI(object))
|
||||
activity.Actor = pub.IRI(author.GetString("iri"))
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.Published = time.Now()
|
||||
|
||||
err = PostActivity(app, author, activity, []string{to + "/inbox"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.DeleteType))
|
||||
record.Set("to", to)
|
||||
record.Set("object", object)
|
||||
record.Set("actor", author.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
func CreateSummitLogDeleteActivity(app core.App, r *core.Record) error {
|
||||
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
author, err := app.FindRecordById("activitypub_actors", r.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !author.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
summitLogTrail, err := app.FindRecordById("trails", r.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
summitLogTrailAuthor, err := app.FindRecordById("activitypub_actors", summitLogTrail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := summitLogTrailAuthor.GetString("iri")
|
||||
object := fmt.Sprintf("%s/api/v1/summit-log/%s", origin, r.Id)
|
||||
cc := pub.ItemCollection{pub.IRI(author.GetString("iri") + "/followers")}
|
||||
|
||||
activity := pub.DeleteNew(pub.IRI(id), pub.IRI(object))
|
||||
activity.Actor = pub.IRI(author.GetString("iri"))
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.CC = cc
|
||||
activity.Published = time.Now()
|
||||
|
||||
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": author.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recipients := []string{}
|
||||
|
||||
for _, f := range follows {
|
||||
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients = append(recipients, follower.GetString("inbox"))
|
||||
}
|
||||
|
||||
if author.Id != summitLogTrailAuthor.Id {
|
||||
recipients = append(recipients, summitLogTrailAuthor.GetString("inbox"))
|
||||
}
|
||||
|
||||
err = PostActivity(app, author, activity, recipients)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.DeleteType))
|
||||
record.Set("to", to)
|
||||
record.Set("cc", cc)
|
||||
record.Set("object", object)
|
||||
record.Set("actor", author.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
func CreateListDeleteActivity(app core.App, r *core.Record) error {
|
||||
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
author, err := app.FindRecordById("activitypub_actors", r.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !author.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
to := "https://www.w3.org/ns/activitystreams#Public"
|
||||
cc := author.GetString("iri") + "/followers"
|
||||
object := fmt.Sprintf("%s/api/v1/list/%s", origin, r.Id)
|
||||
|
||||
activity := pub.DeleteNew(pub.IRI(id), pub.IRI(object))
|
||||
activity.Actor = pub.IRI(author.GetString("iri"))
|
||||
activity.To = pub.ItemCollection{pub.IRI(to)}
|
||||
activity.CC = pub.ItemCollection{pub.IRI(cc)}
|
||||
activity.Published = time.Now()
|
||||
|
||||
follows, err := app.FindRecordsByFilter("follows", "followee={:followee}&&status='accepted'", "", -1, 0, dbx.Params{"followee": author.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recipients := []string{}
|
||||
for _, f := range follows {
|
||||
follower, err := app.FindRecordById("activitypub_actors", f.GetString("follower"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recipients = append(recipients, follower.GetString("inbox"))
|
||||
}
|
||||
|
||||
err = PostActivity(app, author, activity, recipients)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.DeleteType))
|
||||
record.Set("to", to)
|
||||
record.Set("cc", cc)
|
||||
record.Set("object", object)
|
||||
record.Set("actor", author.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
func ProcessDeleteActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
// no need to do anything if the actor is local
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
object := activity.Object.GetID().String()
|
||||
|
||||
var err error
|
||||
switch {
|
||||
case strings.Contains(object, "trail"):
|
||||
err = processDeleteTrailActivity(app, activity)
|
||||
case strings.Contains(object, "comment"):
|
||||
err = processDeleteCommentActivity(app, actor, activity)
|
||||
case strings.Contains(object, "summit-log"):
|
||||
err = processDeleteSummitLogActivity(app, actor, activity)
|
||||
case strings.Contains(object, "list"):
|
||||
err = processDeleteListActivity(app, actor, activity)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func processDeleteTrailActivity(app core.App, activity pub.Activity) error {
|
||||
|
||||
trailUrl, err := url.Parse(activity.Object.GetID().String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
recordId := path.Base(trailUrl.Path)
|
||||
|
||||
trail, err := app.FindRecordById("trails", recordId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return app.Delete(trail)
|
||||
}
|
||||
|
||||
func processDeleteCommentActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
object := activity.Object.GetID().String()
|
||||
|
||||
comment, err := app.FindFirstRecordByData("comments", "iri", object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if comment.GetString("author") != actor.Id {
|
||||
return fmt.Errorf("actor is not comment author")
|
||||
}
|
||||
|
||||
err = app.Delete(comment)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processDeleteSummitLogActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
object := activity.Object.GetID().String()
|
||||
|
||||
summitLog, err := app.FindFirstRecordByData("summit_logs", "iri", object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if summitLog.GetString("author") != actor.Id {
|
||||
return fmt.Errorf("actor is not summit log author")
|
||||
}
|
||||
|
||||
return app.Delete(summitLog)
|
||||
}
|
||||
|
||||
func processDeleteListActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
object := activity.Object.GetID().String()
|
||||
list, err := app.FindFirstRecordByData("lists", "iri", object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if list.GetString("author") != actor.Id {
|
||||
return fmt.Errorf("actor is not summit log author")
|
||||
}
|
||||
return app.Delete(list)
|
||||
}
|
||||
160
db/federation/follow.go
Normal file
160
db/federation/follow.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"pocketbase/util"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
// create outgoing follow activity
|
||||
func CreateFollowActivity(app core.App, follow *core.Record) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
follower := follow.GetString("follower")
|
||||
followee := follow.GetString("followee")
|
||||
|
||||
followerActor, err := app.FindRecordById("activitypub_actors", follower)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
followeeActor, err := app.FindRecordById("activitypub_actors", followee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
activity := pub.FollowNew(pub.IRI(id), pub.IRI(followeeActor.GetString("iri")))
|
||||
activity.Actor = pub.IRI(followerActor.GetString("iri"))
|
||||
|
||||
err = PostActivity(app, followerActor, activity, []string{followeeActor.GetString("inbox")})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.FollowType))
|
||||
record.Set("object", followeeActor.GetString("iri"))
|
||||
record.Set("actor", followerActor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
// process incoming follow activity
|
||||
func ProcessFollowActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
// find the followee in our db
|
||||
object, err := app.FindFirstRecordByData("activitypub_actors", "iri", activity.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// a remote actor has requested the follow
|
||||
// this means we have not yet created a follow entry in our db
|
||||
// we accept it immediately
|
||||
if !actor.GetBool("isLocal") {
|
||||
followCollection, err := app.FindCollectionByNameOrId("follows")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
followRecord := core.NewRecord(followCollection)
|
||||
followRecord.Set("follower", actor.Id)
|
||||
followRecord.Set("followee", object.Id)
|
||||
followRecord.Set("status", "accepted")
|
||||
err = app.Save(followRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
// send the accept activity back to the actor's inbox
|
||||
acceptActivity := pub.AcceptNew(pub.IRI(id), activity)
|
||||
acceptActivity.Actor = activity.Object
|
||||
err = PostActivity(app, object, acceptActivity, []string{actor.GetString("inbox")})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// create record of the accept activity in our db
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.AcceptType))
|
||||
record.Set("object", activity)
|
||||
record.Set("actor", object.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// send a notification to the followee
|
||||
notification := util.Notification{
|
||||
Type: util.NewFollower,
|
||||
Metadata: map[string]string{
|
||||
"follower": fmt.Sprintf("@%s@%s", actor.GetString("preferred_username"), actor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, object)
|
||||
|
||||
}
|
||||
|
||||
func ProcessAcceptActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
followActivity := activity.Object.(*pub.Activity)
|
||||
|
||||
follower, err := app.FindFirstRecordByData("activitypub_actors", "iri", followActivity.Actor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
follow, err := app.FindFirstRecordByFilter("follows", "follower={:follower} && followee={:followee}", dbx.Params{"follower": follower.Id, "followee": actor.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
follow.Set("status", "accepted")
|
||||
err = app.Save(follow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// err = util.SyncOutbox(app, actor)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
return nil
|
||||
}
|
||||
118
db/federation/like.go
Normal file
118
db/federation/like.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"pocketbase/util"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
// create outgoing follow activity
|
||||
func CreateLikeActivity(app core.App, like *core.Record) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
actor, err := app.FindRecordById("activitypub_actors", like.GetString("actor"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trail, err := app.FindRecordById("trails", like.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object := trail.GetString("iri")
|
||||
|
||||
if object == "" {
|
||||
// trail is local
|
||||
object = fmt.Sprintf("%s/api/v1/trail/%s", origin, trail.Id)
|
||||
}
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
activity := pub.LikeNew(pub.IRI(id), pub.IRI(object))
|
||||
activity.Actor = pub.IRI(actor.GetString("iri"))
|
||||
|
||||
err = PostActivity(app, actor, activity, []string{trailAuthor.GetString("inbox")})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.LikeType))
|
||||
record.Set("object", object)
|
||||
record.Set("actor", actor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
return app.Save(record)
|
||||
}
|
||||
|
||||
// process incoming like activity
|
||||
func ProcessLikeActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
trailId := path.Base(activity.Object.GetID().String())
|
||||
trail, err := app.FindRecordById("trails", trailId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !actor.GetBool("isLocal") {
|
||||
trailLikeCollection, err := app.FindCollectionByNameOrId("trail_like")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
likeRecord := core.NewRecord(trailLikeCollection)
|
||||
likeRecord.Set("trail", trail.Id)
|
||||
likeRecord.Set("actor", actor.Id)
|
||||
err = app.Save(likeRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// send a notification to the trail author
|
||||
notification := util.Notification{
|
||||
Type: util.TrailLike,
|
||||
Metadata: map[string]string{
|
||||
"trail_id": trail.Id,
|
||||
"trail_name": trail.GetString("name"),
|
||||
"trail_author": fmt.Sprintf("@%s", trailAuthor.GetString("preferred_username")),
|
||||
"liker": fmt.Sprintf("@%s@%s", actor.GetString("preferred_username"), actor.GetString("domain")),
|
||||
},
|
||||
Seen: false,
|
||||
Author: actor.Id,
|
||||
}
|
||||
return util.SendNotification(app, notification, trailAuthor)
|
||||
|
||||
}
|
||||
194
db/federation/undo.go
Normal file
194
db/federation/undo.go
Normal file
@@ -0,0 +1,194 @@
|
||||
package federation
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
pub "github.com/go-ap/activitypub"
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
"github.com/pocketbase/pocketbase/tools/security"
|
||||
)
|
||||
|
||||
// create outgoing follow activity
|
||||
func CreateUnfollowActivity(app core.App, follow *core.Record) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
follower := follow.GetString("follower")
|
||||
followee := follow.GetString("followee")
|
||||
|
||||
followerActor, err := app.FindRecordById("activitypub_actors", follower)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
followeeActor, err := app.FindRecordById("activitypub_actors", followee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// find the original follow activity
|
||||
followActivityRecord, err := app.FindFirstRecordByFilter("activitypub_activities", "actor={:actor}&&object={:object}&&type={:type}", dbx.Params{"actor": followerActor.GetString("iri"), "object": followeeActor.GetString("iri"), "type": string(pub.FollowType)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
followActivity := pub.FollowNew(pub.IRI(followActivityRecord.GetString("iri")), pub.IRI(followeeActor.GetString("iri")))
|
||||
followActivity.Actor = pub.IRI(followActivityRecord.GetString("actor"))
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.UndoType))
|
||||
record.Set("object", followActivity)
|
||||
record.Set("actor", followerActor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.UndoNew(pub.IRI(id), followActivity)
|
||||
activity.Actor = pub.IRI(followerActor.GetString("iri"))
|
||||
|
||||
return PostActivity(app, followerActor, activity, []string{followeeActor.GetString("inbox")})
|
||||
}
|
||||
|
||||
// create outgoing unlike activity
|
||||
func CreateUnlikeActivity(app core.App, like *core.Record) error {
|
||||
origin := os.Getenv("ORIGIN")
|
||||
if origin == "" {
|
||||
return fmt.Errorf("ORIGIN not set")
|
||||
}
|
||||
|
||||
actor, err := app.FindRecordById("activitypub_actors", like.GetString("actor"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trail, err := app.FindRecordById("trails", like.GetString("trail"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
trailAuthor, err := app.FindRecordById("activitypub_actors", trail.GetString("author"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
object := trail.GetString("iri")
|
||||
if object == "" {
|
||||
// trail is local
|
||||
object = fmt.Sprintf("%s/api/v1/trail/%s", origin, trail.Id)
|
||||
}
|
||||
|
||||
// find the original follow activity
|
||||
likeActivityRecord, err := app.FindFirstRecordByFilter("activitypub_activities", "actor={:actor}&&object={:object}&&type={:type}", dbx.Params{"actor": actor.GetString("iri"), "object": object, "type": string(pub.LikeType)})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
likeActivity := pub.LikeNew(pub.IRI(likeActivityRecord.GetString("iri")), pub.IRI(object))
|
||||
likeActivity.Actor = pub.IRI(likeActivityRecord.GetString("actor"))
|
||||
|
||||
collection, err := app.FindCollectionByNameOrId("activitypub_activities")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
recordId := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
id := fmt.Sprintf("%s/api/v1/activitypub/activity/%s", origin, recordId)
|
||||
|
||||
record := core.NewRecord(collection)
|
||||
record.Set("id", recordId)
|
||||
record.Set("iri", id)
|
||||
record.Set("type", string(pub.UndoType))
|
||||
record.Set("object", likeActivity)
|
||||
record.Set("actor", actor.GetString("iri"))
|
||||
record.Set("published", time.Now())
|
||||
|
||||
err = app.Save(record)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
activity := pub.UndoNew(pub.IRI(id), likeActivity)
|
||||
activity.Actor = pub.IRI(actor.GetString("iri"))
|
||||
|
||||
return PostActivity(app, actor, activity, []string{trailAuthor.GetString("inbox")})
|
||||
}
|
||||
|
||||
func ProcessUndoActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
|
||||
if activity.Object.GetType() == pub.FollowType {
|
||||
return processUnfollowActivity(app, actor, activity)
|
||||
} else if activity.Object.GetType() == pub.LikeType {
|
||||
return processUnlikeActivity(app, actor, activity)
|
||||
} else {
|
||||
return fmt.Errorf("unknown undo activity object type")
|
||||
}
|
||||
}
|
||||
|
||||
func processUnfollowActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
// this was a local follow
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
followActivity := activity.Object.(*pub.Activity)
|
||||
|
||||
followee, err := app.FindFirstRecordByData("activitypub_actors", "iri", followActivity.Object)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
follow, err := app.FindFirstRecordByFilter("follows", "follower={:follower} && followee={:followee}", dbx.Params{"follower": actor.Id, "followee": followee.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = app.Delete(follow)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processUnlikeActivity(app core.App, actor *core.Record, activity pub.Activity) error {
|
||||
if actor.GetBool("isLocal") {
|
||||
return nil
|
||||
}
|
||||
|
||||
likeActivity := activity.Object.(*pub.Activity)
|
||||
|
||||
trailId := path.Base(likeActivity.Object.GetID().String())
|
||||
trail, err := app.FindRecordById("trails", trailId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
like, err := app.FindFirstRecordByFilter("trail_like", "actor={:actor} && trail={:trail}", dbx.Params{"actor": actor.Id, "trail": trail.Id})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = app.Delete(like)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -11,9 +11,15 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650 // indirect
|
||||
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 // indirect
|
||||
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/gorilla/css v1.0.1 // indirect
|
||||
github.com/twpayne/go-geom v1.6.1 // indirect
|
||||
github.com/valyala/fastjson v1.6.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
)
|
||||
|
||||
@@ -26,6 +32,8 @@ require (
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/ganigeorgiev/fexpr v0.4.1 // indirect
|
||||
github.com/go-ap/activitypub v0.0.0-20250409143848-7113328b1f3d
|
||||
github.com/go-fed/httpsig v1.1.0
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
@@ -34,6 +42,7 @@ require (
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/microcosm-cc/bluemonday v1.0.27
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/spf13/cast v1.7.1
|
||||
|
||||
21
db/go.sum
21
db/go.sum
@@ -1,5 +1,7 @@
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
|
||||
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
|
||||
github.com/alecthomas/assert/v2 v2.10.0 h1:jjRCHsj6hBJhkmhznrCzoNpbA3zqy0fYiUcYZP/GkPY=
|
||||
github.com/alecthomas/assert/v2 v2.10.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||
@@ -9,6 +11,8 @@ github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer5
|
||||
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@@ -28,6 +32,14 @@ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3G
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/ganigeorgiev/fexpr v0.4.1 h1:hpUgbUEEWIZhSDBtf4M9aUNfQQ0BZkGRaMePy7Gcx5k=
|
||||
github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
|
||||
github.com/go-ap/activitypub v0.0.0-20250409143848-7113328b1f3d h1:IWrWGnmKzpHqginJ18ljKkty/X8glxM8Mg3pk6bkb8g=
|
||||
github.com/go-ap/activitypub v0.0.0-20250409143848-7113328b1f3d/go.mod h1:EUtZuXtHo4yKkTJmcbAZYW+X1G2poeT8icmBh24eq7o=
|
||||
github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650 h1:tlwla5IQUea0CuktkBd2FLDwVzts4OeTWPPkhQPSK5Q=
|
||||
github.com/go-ap/errors v0.0.0-20250409143711-5686c11ae650/go.mod h1:Vkh+Z3f24K8nMsJKXo1FHn5ebPsXvB/WDH5JRtYqdNo=
|
||||
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73 h1:GMKIYXyXPGIp+hYiWOhfqK4A023HdgisDT4YGgf99mw=
|
||||
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73/go.mod h1:jyveZeGw5LaADntW+UEsMjl3IlIwk+DxlYNsbofQkGA=
|
||||
github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
|
||||
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 h1:byhDUpfEwjsVQb1vBunvIjh2BHQ9ead57VkAEY4V+Es=
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.3.0/go.mod h1:2NKgrcHl3z6cJs+3Oo940FPRiTzuqKbvfrL2RxCj6Ew=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
@@ -45,6 +57,8 @@ github.com/google/pprof v0.0.0-20250315033105-103756e64e1d h1:tx51Lf+wdE+aavqH8T
|
||||
github.com/google/pprof v0.0.0-20250315033105-103756e64e1d/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
@@ -63,6 +77,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/meilisearch/meilisearch-go v0.29.0 h1:HZ9NEKN59USINQ/DXJge/aaXq8IrsKbXGTdAoBaaDz4=
|
||||
github.com/meilisearch/meilisearch-go v0.29.0/go.mod h1:2cRCAn4ddySUsFfNDLVPod/plRibQsJkXF/4gLhxbOk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
|
||||
github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
@@ -99,7 +115,10 @@ github.com/twpayne/go-gpx v1.5.0 h1:HvFSJ+0r0sbhOQ8mTvd0/n0FhcgjTFsKQGG6o7PV6G4=
|
||||
github.com/twpayne/go-gpx v1.5.0/go.mod h1:vjvu/125399qj6k+px2v2v8dm08DM4I4dFBJmHHt2TE=
|
||||
github.com/twpayne/go-polyline v1.1.1 h1:/tSF1BR7rN4HWj4XKqvRUNrCiYVMCvywxTFVofvDV0w=
|
||||
github.com/twpayne/go-polyline v1.1.1/go.mod h1:ybd9IWWivW/rlXPXuuckeKUyF3yrIim+iqA7kSl4NFY=
|
||||
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
|
||||
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
|
||||
golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
@@ -109,6 +128,7 @@ golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
|
||||
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
|
||||
golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
|
||||
@@ -117,6 +137,7 @@ golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT
|
||||
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
|
||||
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
|
||||
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
|
||||
@@ -33,6 +33,15 @@ func SyncKomoot(app core.App) error {
|
||||
}
|
||||
|
||||
userId := i.GetString("user")
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", userId)
|
||||
if err != nil {
|
||||
warning := fmt.Sprintf("no actor found for user: %s\n", userId)
|
||||
fmt.Print(warning)
|
||||
app.Logger().Warn(warning)
|
||||
continue
|
||||
}
|
||||
actorId := actor.Id
|
||||
|
||||
komootString := i.GetString("komoot")
|
||||
komootIntegration := KomootIntegration{
|
||||
Planned: true,
|
||||
@@ -71,7 +80,7 @@ func SyncKomoot(app core.App) error {
|
||||
continue
|
||||
}
|
||||
|
||||
hasNewTours, err = syncTrailWithTours(app, k, komootIntegration, userId, tours)
|
||||
hasNewTours, err = syncTrailWithTours(app, k, komootIntegration, userId, actorId, tours)
|
||||
if err != nil {
|
||||
warning := fmt.Sprintf("error syncing komoot tours with trails: %v\n", err)
|
||||
fmt.Print(warning)
|
||||
@@ -165,7 +174,7 @@ func (k *KomootApi) fetchTours(page int) ([]KomootTour, error) {
|
||||
}
|
||||
|
||||
func (k *KomootApi) fetchDetailedTour(tour KomootTour) (*DetailedKomootTour, error) {
|
||||
url := fmt.Sprintf("https://api.komoot.de/v007/tours/%d?_embedded=coordinates,way_types,surfaces,directions,participants,timeline,cover_images&directions=v2&fields=timeline&format=coordinate_array&timeline_highlights_fields=tips,recommenders", tour.ID)
|
||||
url := fmt.Sprintf("https://api.komoot.de/v007/tours/%d?_embedded=coordinates,way_types,surfaces,directions,participants,timeline,cover_images&directions=v2&fields=timeline&format=coordinate_array&timeline_highlights_fields=tips,recommenders&page=2", tour.ID)
|
||||
body, err := sendRequest(url, k.buildHeader())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -176,7 +185,7 @@ func (k *KomootApi) fetchDetailedTour(tour KomootTour) (*DetailedKomootTour, err
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func syncTrailWithTours(app core.App, k *KomootApi, i KomootIntegration, user string, tours []KomootTour) (bool, error) {
|
||||
func syncTrailWithTours(app core.App, k *KomootApi, i KomootIntegration, user string, actor string, tours []KomootTour) (bool, error) {
|
||||
hasNewTours := false
|
||||
for _, tour := range tours {
|
||||
trails, err := app.FindRecordsByFilter("trails", "external_id = {:id}", "", 1, 0, dbx.Params{"id": strconv.Itoa(int(tour.ID))})
|
||||
@@ -202,7 +211,7 @@ func syncTrailWithTours(app core.App, k *KomootApi, i KomootIntegration, user st
|
||||
app.Logger().Warn(fmt.Sprintf("Unable to create waypoints for tour '%s': %v", tour.Name, err))
|
||||
continue
|
||||
}
|
||||
err = createTrailFromTour(app, detailedTour, gpx, user, wpIds)
|
||||
err = createTrailFromTour(app, k, detailedTour, gpx, actor, wpIds)
|
||||
if err != nil {
|
||||
app.Logger().Warn(fmt.Sprintf("Unable to create trail for tour '%s': %v", tour.Name, err))
|
||||
continue
|
||||
@@ -212,27 +221,9 @@ func syncTrailWithTours(app core.App, k *KomootApi, i KomootIntegration, user st
|
||||
return hasNewTours, nil
|
||||
}
|
||||
|
||||
func createTrailFromTour(app core.App, detailedTour *DetailedKomootTour, gpx *filesystem.File, user string, wpIds []string) error {
|
||||
var summitLogRecord *core.Record
|
||||
if detailedTour.Type == "tour_recorded" {
|
||||
collection, err := app.FindCollectionByNameOrId("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
func createTrailFromTour(app core.App, k *KomootApi, detailedTour *DetailedKomootTour, gpx *filesystem.File, actor string, wpIds []string) error {
|
||||
trailid := security.RandomStringWithAlphabet(core.DefaultIdLength, core.DefaultIdAlphabet)
|
||||
|
||||
summitLogRecord = core.NewRecord(collection)
|
||||
summitLogRecord.Load(map[string]any{
|
||||
"distance": detailedTour.Distance,
|
||||
"elevation_gain": detailedTour.ElevationUp,
|
||||
"elevation_loss": detailedTour.ElevationDown,
|
||||
"duration": detailedTour.Duration,
|
||||
"date": detailedTour.Date,
|
||||
"author": user,
|
||||
})
|
||||
if err := app.Save(summitLogRecord); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
collection, err := app.FindCollectionByNameOrId("trails")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -259,7 +250,7 @@ func createTrailFromTour(app core.App, detailedTour *DetailedKomootTour, gpx *fi
|
||||
|
||||
var photos []*filesystem.File
|
||||
if len(detailedTour.Embedded.CoverImages.Embedded.Items) > 0 {
|
||||
photos, err = fetchRoutePhotos(detailedTour)
|
||||
photos, err = fetchRoutePhotos(k, detailedTour)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -277,12 +268,13 @@ func createTrailFromTour(app core.App, detailedTour *DetailedKomootTour, gpx *fi
|
||||
}
|
||||
|
||||
record.Load(map[string]any{
|
||||
"id": trailid,
|
||||
"name": detailedTour.Name,
|
||||
"public": detailedTour.Status == "public",
|
||||
"distance": detailedTour.Distance,
|
||||
"elevation_gain": detailedTour.ElevationUp,
|
||||
"elevation_loss": detailedTour.ElevationDown,
|
||||
"duration": detailedTour.Duration / 60,
|
||||
"duration": detailedTour.Duration,
|
||||
"date": detailedTour.Date,
|
||||
"external_provider": "komoot",
|
||||
"external_id": strconv.Itoa(detailedTour.ID),
|
||||
@@ -291,12 +283,9 @@ func createTrailFromTour(app core.App, detailedTour *DetailedKomootTour, gpx *fi
|
||||
"difficulty": diffculty,
|
||||
"category": categoryId,
|
||||
"waypoints": wpIds,
|
||||
"author": user,
|
||||
"author": actor,
|
||||
})
|
||||
|
||||
if summitLogRecord != nil {
|
||||
record.Set("summit_logs", summitLogRecord.Id)
|
||||
}
|
||||
if photos != nil {
|
||||
record.Set("photos", photos)
|
||||
}
|
||||
@@ -308,6 +297,27 @@ func createTrailFromTour(app core.App, detailedTour *DetailedKomootTour, gpx *fi
|
||||
return err
|
||||
}
|
||||
|
||||
if detailedTour.Type == "tour_recorded" {
|
||||
collection, err := app.FindCollectionByNameOrId("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
summitLogRecord := core.NewRecord(collection)
|
||||
summitLogRecord.Load(map[string]any{
|
||||
"distance": detailedTour.Distance,
|
||||
"elevation_gain": detailedTour.ElevationUp,
|
||||
"elevation_loss": detailedTour.ElevationDown,
|
||||
"duration": detailedTour.Duration,
|
||||
"date": detailedTour.Date,
|
||||
"author": actor,
|
||||
"trail": trailid,
|
||||
})
|
||||
if err := app.Save(summitLogRecord); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -365,11 +375,22 @@ func createWaypointsFromTour(app core.App, tour *DetailedKomootTour, user string
|
||||
return wpIds, nil
|
||||
}
|
||||
|
||||
func fetchRoutePhotos(tour *DetailedKomootTour) ([]*filesystem.File, error) {
|
||||
func fetchRoutePhotos(k *KomootApi, tour *DetailedKomootTour) ([]*filesystem.File, error) {
|
||||
url := fmt.Sprintf("https://api.komoot.de/v007/tours/%d/cover_images/", tour.ID)
|
||||
body, err := sendRequest(url, k.buildHeader())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
photos := make([]*filesystem.File, len(tour.Embedded.CoverImages.Embedded.Items))
|
||||
var data *CoverImages
|
||||
err = json.Unmarshal(body, &data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, img := range tour.Embedded.CoverImages.Embedded.Items {
|
||||
photos := make([]*filesystem.File, data.Page.TotalElements)
|
||||
|
||||
for i, img := range data.Embedded.Items {
|
||||
photo, err := fetchPhoto(img.Src, "", "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -36,9 +36,18 @@ func SyncStrava(app core.App) error {
|
||||
}
|
||||
|
||||
userId := i.GetString("user")
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", userId)
|
||||
if err != nil {
|
||||
warning := fmt.Sprintf("no actor found for user: %s\n", userId)
|
||||
fmt.Print(warning)
|
||||
app.Logger().Warn(warning)
|
||||
continue
|
||||
}
|
||||
actorId := actor.Id
|
||||
|
||||
stravaString := i.GetString("strava")
|
||||
var stravaIntegration StravaIntegration
|
||||
err := json.Unmarshal([]byte(stravaString), &stravaIntegration)
|
||||
err = json.Unmarshal([]byte(stravaString), &stravaIntegration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -103,7 +112,7 @@ func SyncStrava(app core.App) error {
|
||||
app.Logger().Warn(warning)
|
||||
break
|
||||
}
|
||||
hasNewRoutes, err = syncTrailsWithRoutes(app, r.AccessToken, userId, routes)
|
||||
hasNewRoutes, err = syncTrailsWithRoutes(app, r.AccessToken, userId, actorId, routes)
|
||||
if err != nil {
|
||||
warning := fmt.Sprintf("error syncing strava routes with trails: %v\n", err)
|
||||
fmt.Print(warning)
|
||||
@@ -124,7 +133,7 @@ func SyncStrava(app core.App) error {
|
||||
app.Logger().Warn(warning)
|
||||
break
|
||||
}
|
||||
hasNewActivities, err = syncTrailsWithActivities(app, r.AccessToken, userId, activities)
|
||||
hasNewActivities, err = syncTrailsWithActivities(app, r.AccessToken, userId, actorId, activities)
|
||||
if err != nil {
|
||||
warning := fmt.Sprintf("error syncing strava activities with trails: %v", err)
|
||||
fmt.Print(warning)
|
||||
@@ -226,7 +235,7 @@ func fetchStravaActivities(accessToken string, page int) ([]StravaActivity, erro
|
||||
return activities, nil
|
||||
}
|
||||
|
||||
func syncTrailsWithRoutes(app core.App, accessToken string, user string, routes []StravaRoute) (bool, error) {
|
||||
func syncTrailsWithRoutes(app core.App, accessToken string, user string, actor string, routes []StravaRoute) (bool, error) {
|
||||
hasNewRoutes := false
|
||||
for _, route := range routes {
|
||||
trails, err := app.FindRecordsByFilter("trails", "external_id = {:id}", "", 1, 0, dbx.Params{"id": route.IDStr})
|
||||
@@ -247,7 +256,7 @@ func syncTrailsWithRoutes(app core.App, accessToken string, user string, routes
|
||||
app.Logger().Warn(fmt.Sprintf("Unable to create waypoints for route '%s': %v", route.Name, err))
|
||||
continue
|
||||
}
|
||||
err = createTrailFromRoute(app, route, gpx, user, wpIds)
|
||||
err = createTrailFromRoute(app, route, gpx, actor, wpIds)
|
||||
if err != nil {
|
||||
app.Logger().Warn(fmt.Sprintf("Unable to create trail for route '%s': %v", route.Name, err))
|
||||
continue
|
||||
@@ -296,7 +305,7 @@ func fetchRouteGPX(route StravaRoute, accessToken string) (*filesystem.File, err
|
||||
return gpxFile, nil
|
||||
}
|
||||
|
||||
func createTrailFromRoute(app core.App, route StravaRoute, gpx *filesystem.File, user string, wpIds []string) error {
|
||||
func createTrailFromRoute(app core.App, route StravaRoute, gpx *filesystem.File, actor string, wpIds []string) error {
|
||||
collection, err := app.FindCollectionByNameOrId("trails")
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -333,7 +342,7 @@ func createTrailFromRoute(app core.App, route StravaRoute, gpx *filesystem.File,
|
||||
"public": !route.Private,
|
||||
"distance": route.Distance,
|
||||
"elevation_gain": route.ElevationGain,
|
||||
"duration": route.EstimatedMovingTime / 60,
|
||||
"duration": route.EstimatedMovingTime,
|
||||
"date": time.Unix(int64(route.Timestamp), 0),
|
||||
"external_provider": "strava",
|
||||
"external_id": route.IDStr,
|
||||
@@ -342,7 +351,7 @@ func createTrailFromRoute(app core.App, route StravaRoute, gpx *filesystem.File,
|
||||
"waypoints": wpIds,
|
||||
"difficulty": "easy",
|
||||
"category": category,
|
||||
"author": user,
|
||||
"author": actor,
|
||||
})
|
||||
|
||||
if gpx != nil {
|
||||
@@ -383,7 +392,7 @@ func createWaypointsFromRoute(app core.App, route StravaRoute, user string) ([]s
|
||||
return wpIds, nil
|
||||
}
|
||||
|
||||
func syncTrailsWithActivities(app core.App, accessToken string, user string, activities []StravaActivity) (bool, error) {
|
||||
func syncTrailsWithActivities(app core.App, accessToken string, user string, actor string, activities []StravaActivity) (bool, error) {
|
||||
hasNewActivites := false
|
||||
for _, activity := range activities {
|
||||
trails, err := app.FindRecordsByFilter("trails", "external_id = {:id}", "", 1, 0, dbx.Params{"id": strconv.Itoa(int(activity.ID))})
|
||||
@@ -404,7 +413,7 @@ func syncTrailsWithActivities(app core.App, accessToken string, user string, act
|
||||
app.Logger().Warn(fmt.Sprintf("Unable to fetch GPX for activity '%s': %v", activity.Name, err))
|
||||
continue
|
||||
}
|
||||
err = createTrailFromActivity(app, detailedActivity, gpx, user)
|
||||
err = createTrailFromActivity(app, detailedActivity, gpx, actor)
|
||||
if err != nil {
|
||||
app.Logger().Warn(fmt.Sprintf("Unable to create trail from activity '%s': %v", activity.Name, err))
|
||||
continue
|
||||
@@ -514,7 +523,7 @@ func createTrailFromActivity(app core.App, activity *DetailedStravaActivity, gpx
|
||||
"public": !activity.Private,
|
||||
"distance": activity.Distance,
|
||||
"elevation_gain": activity.TotalElevationGain,
|
||||
"duration": activity.ElapsedTime / 60,
|
||||
"duration": activity.ElapsedTime,
|
||||
"date": activity.StartDate,
|
||||
"external_provider": "strava",
|
||||
"external_id": activity.ID,
|
||||
|
||||
792
db/main.go
792
db/main.go
File diff suppressed because it is too large
Load Diff
102
db/migrations/1747061255_deleted_follow_counts.go
Normal file
102
db/migrations/1747061255_deleted_follow_counts.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("j6w72f0kb5ivd7x")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return app.Delete(collection)
|
||||
}, func(app core.App) error {
|
||||
jsonData := `{
|
||||
"createRule": null,
|
||||
"deleteRule": null,
|
||||
"fields": [
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text3208210256",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "id",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": true,
|
||||
"required": true,
|
||||
"system": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation1148540665",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "actor",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
},
|
||||
{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "_clone_kce8",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2215181735",
|
||||
"maxSize": 1,
|
||||
"name": "followers",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json1908379107",
|
||||
"maxSize": 1,
|
||||
"name": "following",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}
|
||||
],
|
||||
"id": "j6w72f0kb5ivd7x",
|
||||
"indexes": [],
|
||||
"listRule": "@request.auth.id = user || (@collection.users_anonymous.id ?= user && @collection.users_anonymous.private ?= false)",
|
||||
"name": "follow_counts",
|
||||
"system": false,
|
||||
"type": "view",
|
||||
"updateRule": null,
|
||||
"viewQuery": "SELECT \n (ROW_NUMBER() OVER()) as id,\n activitypub_actors.id as actor,\n activitypub_actors.user as user,\n COALESCE(followers.count, 0) AS followers,\n COALESCE(following.count, 0) AS following\nFROM activitypub_actors\nLEFT JOIN (\n SELECT followee AS actor_id, COUNT(*) AS count\n FROM follows\n GROUP BY followee\n) AS followers ON activitypub_actors.id = followers.actor_id\nLEFT JOIN (\n SELECT follower AS actor_id, COUNT(*) AS count\n FROM follows\n GROUP BY follower\n) AS following ON activitypub_actors.id = following.actor_id",
|
||||
"viewRule": "@request.auth.id = user || (@collection.users_anonymous.id ?= user && @collection.users_anonymous.private ?= false)"
|
||||
}`
|
||||
|
||||
collection := &core.Collection{}
|
||||
if err := json.Unmarshal([]byte(jsonData), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
186
db/migrations/1747061256_deleted_activities.go
Normal file
186
db/migrations/1747061256_deleted_activities.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("t9lphichi5xwyeu")
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return app.Delete(collection)
|
||||
}, func(app core.App) error {
|
||||
jsonData := `{
|
||||
"createRule": null,
|
||||
"deleteRule": null,
|
||||
"fields": [
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text3208210256",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "id",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": true,
|
||||
"required": true,
|
||||
"system": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2310347867",
|
||||
"maxSize": 1,
|
||||
"name": "trail_id",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2862495610",
|
||||
"maxSize": 1,
|
||||
"name": "date",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json1579384326",
|
||||
"maxSize": 1,
|
||||
"name": "name",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json1843675174",
|
||||
"maxSize": 1,
|
||||
"name": "description",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3275261007",
|
||||
"maxSize": 1,
|
||||
"name": "gpx",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3182418120",
|
||||
"maxSize": 1,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json142008537",
|
||||
"maxSize": 1,
|
||||
"name": "photos",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json479369857",
|
||||
"maxSize": 1,
|
||||
"name": "distance",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2254405824",
|
||||
"maxSize": 1,
|
||||
"name": "duration",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3015100073",
|
||||
"maxSize": 1,
|
||||
"name": "elevation_gain",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3171089056",
|
||||
"maxSize": 1,
|
||||
"name": "elevation_loss",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2990389176",
|
||||
"maxSize": 1,
|
||||
"name": "created",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2363381545",
|
||||
"maxSize": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}
|
||||
],
|
||||
"id": "t9lphichi5xwyeu",
|
||||
"indexes": [],
|
||||
"listRule": "(@collection.users_anonymous.id ?= author && @collection.users_anonymous.private ?= false\n&&\n@collection.trails.id ?= trail_id && \n (\n @collection.trails.author ?= @request.auth.id ||\n @collection.trails.public ?= true || \n (@request.auth.id != \"\" && @collection.trails.trail_share_via_trail.user ?= @request.auth.id)\n )) && @request.auth.id = author",
|
||||
"name": "activities",
|
||||
"system": false,
|
||||
"type": "view",
|
||||
"updateRule": null,
|
||||
"viewQuery": "SELECT id,trail_id,date,name,description,gpx,author,photos,distance,duration,elevation_gain,elevation_loss,created,type \nFROM (\n SELECT summit_logs.id,trails.id as trail_id,summit_logs.date,trails.name,text as description,summit_logs.gpx,summit_logs.author,summit_logs.photos,summit_logs.distance,summit_logs.duration,summit_logs.elevation_gain,summit_logs.elevation_loss,summit_logs.created,\"summit_log\" as type \n FROM summit_logs\n JOIN trails ON summit_logs.id IN (\n SELECT value\n FROM json_each(trails.summit_logs)\n )\n UNION\n SELECT id,id as trail_id,date,name,description,gpx,author,photos,distance,duration,elevation_gain,elevation_loss,created,\"trail\" as type \n FROM trails\n)\nORDER BY created DESC",
|
||||
"viewRule": "(@collection.users_anonymous.id ?= author && @collection.users_anonymous.private ?= false\n&&\n@collection.trails.id ?= trail_id && \n (\n @collection.trails.author ?= @request.auth.id ||\n @collection.trails.public ?= true || \n (@request.auth.id != \"\" && @collection.trails.trail_share_via_trail.user ?= @request.auth.id)\n )) && @request.auth.id = author"
|
||||
}`
|
||||
|
||||
collection := &core.Collection{}
|
||||
if err := json.Unmarshal([]byte(jsonData), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
285
db/migrations/1747061257_created_activitypub_actors.go
Normal file
285
db/migrations/1747061257_created_activitypub_actors.go
Normal file
@@ -0,0 +1,285 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
jsonData := `[
|
||||
{
|
||||
"id": "pbc_1295301207",
|
||||
"listRule": "",
|
||||
"viewRule": "",
|
||||
"createRule": null,
|
||||
"updateRule": null,
|
||||
"deleteRule": null,
|
||||
"name": "activitypub_actors",
|
||||
"type": "base",
|
||||
"fields": [
|
||||
{
|
||||
"autogeneratePattern": "[a-z0-9]{15}",
|
||||
"hidden": false,
|
||||
"id": "text3208210256",
|
||||
"max": 15,
|
||||
"min": 15,
|
||||
"name": "id",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": true,
|
||||
"required": true,
|
||||
"system": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text4166911607",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "username",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text4002953752",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "preferred_username",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text2812878347",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "domain",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text3458754147",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "summary",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "number1386272118",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "followerCount",
|
||||
"onlyInt": true,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "number3430500629",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "followingCount",
|
||||
"onlyInt": true,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "date1748787223",
|
||||
"max": "",
|
||||
"min": "",
|
||||
"name": "published",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url126331327",
|
||||
"name": "iri",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url2115105593",
|
||||
"name": "inbox",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url1793578352",
|
||||
"name": "outbox",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url1704208859",
|
||||
"name": "icon",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url2215181735",
|
||||
"name": "followers",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url1908379107",
|
||||
"name": "following",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "bool2193750486",
|
||||
"name": "isLocal",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text1727648867",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "public_key",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": true,
|
||||
"id": "text4160324774",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "private_key",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "relation2375276105",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "date2062531289",
|
||||
"max": "",
|
||||
"min": "",
|
||||
"name": "last_fetched",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "autodate2990389176",
|
||||
"name": "created",
|
||||
"onCreate": true,
|
||||
"onUpdate": false,
|
||||
"presentable": false,
|
||||
"system": false,
|
||||
"type": "autodate"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "autodate3332085495",
|
||||
"name": "updated",
|
||||
"onCreate": true,
|
||||
"onUpdate": true,
|
||||
"presentable": false,
|
||||
"system": false,
|
||||
"type": "autodate"
|
||||
}
|
||||
],
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX ` + "`idx_rpT7QJwWTm` ON `activitypub_actors` (`iri`)" + `"
|
||||
],
|
||||
"system": false
|
||||
}
|
||||
]`
|
||||
|
||||
return app.ImportCollectionsByMarshaledJSON([]byte(jsonData), false)
|
||||
}, func(app core.App) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
156
db/migrations/1747061258_created_activitypub_activities.go
Normal file
156
db/migrations/1747061258_created_activitypub_activities.go
Normal file
@@ -0,0 +1,156 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
jsonData := `[
|
||||
{
|
||||
"id": "pbc_3752774184",
|
||||
"listRule": "",
|
||||
"viewRule": "",
|
||||
"createRule": null,
|
||||
"updateRule": null,
|
||||
"deleteRule": null,
|
||||
"name": "activitypub_activities",
|
||||
"type": "base",
|
||||
"fields": [
|
||||
{
|
||||
"autogeneratePattern": "[a-z0-9]{15}",
|
||||
"hidden": false,
|
||||
"id": "text3208210256",
|
||||
"max": 15,
|
||||
"min": 15,
|
||||
"name": "id",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": true,
|
||||
"required": true,
|
||||
"system": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"exceptDomains": [],
|
||||
"hidden": false,
|
||||
"id": "url2434853685",
|
||||
"name": "iri",
|
||||
"onlyDomains": [],
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text2363381545",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "type",
|
||||
"pattern": "",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3616002756",
|
||||
"maxSize": 0,
|
||||
"name": "to",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3685882489",
|
||||
"maxSize": 0,
|
||||
"name": "cc",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2893285722",
|
||||
"maxSize": 0,
|
||||
"name": "object",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"exceptDomains": [],
|
||||
"hidden": false,
|
||||
"id": "url1148540665",
|
||||
"name": "actor",
|
||||
"onlyDomains": [],
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "date1748787223",
|
||||
"max": "",
|
||||
"min": "",
|
||||
"name": "published",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "date"
|
||||
},
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text1653163849",
|
||||
"max": 15,
|
||||
"min": 15,
|
||||
"name": "relation",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "autodate2990389176",
|
||||
"name": "created",
|
||||
"onCreate": true,
|
||||
"onUpdate": false,
|
||||
"presentable": false,
|
||||
"system": false,
|
||||
"type": "autodate"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "autodate3332085495",
|
||||
"name": "updated",
|
||||
"onCreate": true,
|
||||
"onUpdate": true,
|
||||
"presentable": false,
|
||||
"system": false,
|
||||
"type": "autodate"
|
||||
}
|
||||
],
|
||||
"indexes": [],
|
||||
"system": false
|
||||
}
|
||||
]`
|
||||
|
||||
return app.ImportCollectionsByMarshaledJSON([]byte(jsonData), false)
|
||||
}, func(app core.App) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
30
db/migrations/1747061259_seed_actors.go
Normal file
30
db/migrations/1747061259_seed_actors.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"pocketbase/util"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
users, err := app.FindAllRecords("users")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
_, err = util.ActorFromUser(app, u)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
78
db/migrations/1747061260_trails_add_new_author.go
Normal file
78
db/migrations/1747061260_trails_add_new_author.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(15, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation3182418120",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(16, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "1utgul91",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation3182418120")
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(15, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "1utgul91",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
33
db/migrations/1747061261_set_trail_authors.go
Normal file
33
db/migrations/1747061261_set_trail_authors.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
trails, err := app.FindAllRecords("trails")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, t := range trails {
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", t.GetString("user"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
t.Set("author", actor.Id)
|
||||
err = app.UnsafeWithoutHooks().Save(t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
78
db/migrations/1747061262_comments_add_new_author.go
Normal file
78
db/migrations/1747061262_comments_add_new_author.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("comments")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation3182418120",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(16, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "7lwo1mxx",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("comments")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation3182418120")
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(15, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "7lwo1mxx",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
33
db/migrations/1747061263_set_comment_authors.go
Normal file
33
db/migrations/1747061263_set_comment_authors.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
comments, err := app.FindAllRecords("comments")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, c := range comments {
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", c.GetString("user"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
c.Set("author", actor.Id)
|
||||
err = app.UnsafeWithoutHooks().Save(c)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
78
db/migrations/1747061264_summit_logs_add_new_author.go
Normal file
78
db/migrations/1747061264_summit_logs_add_new_author.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(9, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation3182418120",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(16, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "r0mj3tkr",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation3182418120")
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(15, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "r0mj3tkr",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
46
db/migrations/1747061265_set_summit_log_authors.go
Normal file
46
db/migrations/1747061265_set_summit_log_authors.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
logs, err := app.FindAllRecords("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, l := range logs {
|
||||
if l.GetString("user") == "" {
|
||||
trail, err := app.FindFirstRecordByFilter("trails", "summit_logs ?~ {:id}", dbx.Params{"id": l.Id})
|
||||
if err != nil {
|
||||
// orphaned
|
||||
err = app.UnsafeWithoutHooks().Delete(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
l.Set("user", trail.GetString("user"))
|
||||
}
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", l.GetString("user"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
l.Set("author", actor.Id)
|
||||
err = app.UnsafeWithoutHooks().Save(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
55
db/migrations/1747061266_migrate_ms_token.go
Normal file
55
db/migrations/1747061266_migrate_ms_token.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"os"
|
||||
"pocketbase/util"
|
||||
|
||||
"github.com/meilisearch/meilisearch-go"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
client := meilisearch.New(os.Getenv("MEILI_URL"), meilisearch.WithAPIKey(os.Getenv("MEILI_MASTER_KEY")))
|
||||
|
||||
m.Register(func(app core.App) error {
|
||||
|
||||
users, err := app.FindAllRecords("users")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, u := range users {
|
||||
userId := u.Id
|
||||
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
searchRules := map[string]interface{}{
|
||||
"lists": map[string]string{
|
||||
"filter": "public = true OR author = " + actor.Id + " OR shares = " + userId,
|
||||
},
|
||||
"trails": map[string]string{
|
||||
"filter": "public = true OR author = " + actor.Id + " OR shares = " + userId,
|
||||
},
|
||||
}
|
||||
|
||||
token, err := util.GenerateMeilisearchToken(searchRules, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Set("token", token)
|
||||
if err := app.Save(u); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
44
db/migrations/1747061267_summit_logs_add_trail_field.go
Normal file
44
db/migrations/1747061267_summit_logs_add_trail_field.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(10, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "e864strfxo14pm4",
|
||||
"hidden": false,
|
||||
"id": "relation2993194383",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "trail",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation2993194383")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
34
db/migrations/1747061268_migrate_summit_log_trails.go
Normal file
34
db/migrations/1747061268_migrate_summit_log_trails.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/dbx"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
logs, err := app.FindAllRecords("summit_logs")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, l := range logs {
|
||||
trail, err := app.FindFirstRecordByFilter("trails", "summit_logs ?~ {:id}", dbx.Params{"id": l.Id})
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
l.Set("trail", trail.Id)
|
||||
err = app.UnsafeWithoutHooks().Save(l)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
44
db/migrations/1747061269_trails_remove_summit_log_field.go
Normal file
44
db/migrations/1747061269_trails_remove_summit_log_field.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("e1lwowvd")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(17, []byte(`{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "dd2l9a4vxpy2ni8",
|
||||
"hidden": false,
|
||||
"id": "e1lwowvd",
|
||||
"maxSelect": 2147483647,
|
||||
"minSelect": 0,
|
||||
"name": "summit_logs",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
150
db/migrations/1747061270_follows_add_new_f_f.go
Normal file
150
db/migrations/1747061270_follows_add_new_f_f.go
Normal file
@@ -0,0 +1,150 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "in1traur",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "old_follower",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "wxwomfd5",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "old_followee",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "select2063623452",
|
||||
"maxSelect": 1,
|
||||
"name": "status",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"pending",
|
||||
"accepted"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation3117812038",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "follower",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation973442177",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "followee",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "in1traur",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "follower",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "wxwomfd5",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "followee",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation3117812038")
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation973442177")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
60
db/migrations/1747061271_migrate_follows.go
Normal file
60
db/migrations/1747061271_migrate_follows.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
follows, err := app.FindAllRecords("follows")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
seen := map[string]string{}
|
||||
for _, f := range follows {
|
||||
oldFollower := f.GetString("old_follower")
|
||||
oldFollowee := f.GetString("old_followee")
|
||||
|
||||
if oldFollowee == "" || oldFollower == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
seenFollowee, ok := seen[oldFollower]
|
||||
if ok && seenFollowee == oldFollowee {
|
||||
err = app.Delete(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
seen[oldFollower] = oldFollowee
|
||||
|
||||
followerActor, err := app.FindFirstRecordByData("activitypub_actors", "user", oldFollower)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
followeeActor, err := app.FindFirstRecordByData("activitypub_actors", "user", oldFollowee)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f.Set("follower", followerActor.Id)
|
||||
f.Set("followee", followeeActor.Id)
|
||||
f.Set("status", "accepted")
|
||||
|
||||
err = app.UnsafeWithoutHooks().Save(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
1159
db/migrations/1747064968_collections_snapshot.go
Normal file
1159
db/migrations/1747064968_collections_snapshot.go
Normal file
File diff suppressed because it is too large
Load Diff
44
db/migrations/1747066702_updated_comments.go
Normal file
44
db/migrations/1747066702_updated_comments.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("7lwo1mxx")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "7lwo1mxx",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1747066720_updated_summit_logs.go
Normal file
44
db/migrations/1747066720_updated_summit_logs.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("r0mj3tkr")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(13, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "r0mj3tkr",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1747066741_updated_trails.go
Normal file
44
db/migrations/1747066741_updated_trails.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("1utgul91")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(24, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "1utgul91",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
26
db/migrations/1747066742_updated_follows.go
Normal file
26
db/migrations/1747066742_updated_follows.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// // remove field
|
||||
collection.Fields.RemoveById("in1traur")
|
||||
|
||||
// // remove field
|
||||
collection.Fields.RemoveById("wxwomfd5")
|
||||
|
||||
return app.Save(collection)
|
||||
|
||||
}, func(app core.App) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
186
db/migrations/1747236775_created_timeline.go
Normal file
186
db/migrations/1747236775_created_timeline.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
jsonData := `{
|
||||
"createRule": null,
|
||||
"deleteRule": null,
|
||||
"fields": [
|
||||
{
|
||||
"autogeneratePattern": "",
|
||||
"hidden": false,
|
||||
"id": "text3208210256",
|
||||
"max": 0,
|
||||
"min": 0,
|
||||
"name": "id",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": true,
|
||||
"required": true,
|
||||
"system": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2310347867",
|
||||
"maxSize": 1,
|
||||
"name": "trail_id",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2862495610",
|
||||
"maxSize": 1,
|
||||
"name": "date",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json1579384326",
|
||||
"maxSize": 1,
|
||||
"name": "name",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json1843675174",
|
||||
"maxSize": 1,
|
||||
"name": "description",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3275261007",
|
||||
"maxSize": 1,
|
||||
"name": "gpx",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3182418120",
|
||||
"maxSize": 1,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json142008537",
|
||||
"maxSize": 1,
|
||||
"name": "photos",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json479369857",
|
||||
"maxSize": 1,
|
||||
"name": "distance",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2254405824",
|
||||
"maxSize": 1,
|
||||
"name": "duration",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3015100073",
|
||||
"maxSize": 1,
|
||||
"name": "elevation_gain",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json3171089056",
|
||||
"maxSize": 1,
|
||||
"name": "elevation_loss",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2990389176",
|
||||
"maxSize": 1,
|
||||
"name": "created",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "json2363381545",
|
||||
"maxSize": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}
|
||||
],
|
||||
"id": "pbc_468398817",
|
||||
"indexes": [],
|
||||
"listRule": "@collection.trails.id ?= trail_id && @collection.trails.public ?= true",
|
||||
"name": "timeline",
|
||||
"system": false,
|
||||
"type": "view",
|
||||
"updateRule": null,
|
||||
"viewQuery": "-- database: /Users/christianbeutel/Documents/svelte/wanderer/db/pb_data/data.db\nSELECT\n (ROW_NUMBER() OVER ()) as id,\n trail_id,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.trail as trail_id,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id as trail_id,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n",
|
||||
"viewRule": "@collection.trails.id ?= trail_id && @collection.trails.public ?= true"
|
||||
}`
|
||||
|
||||
collection := &core.Collection{}
|
||||
if err := json.Unmarshal([]byte(jsonData), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Delete(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747242599_updated_timeline.go
Normal file
40
db/migrations/1747242599_updated_timeline.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n (ROW_NUMBER() OVER ()) as id,\n trail_id,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.trail as trail_id,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id as trail_id,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "-- database: /Users/christianbeutel/Documents/svelte/wanderer/db/pb_data/data.db\nSELECT\n (ROW_NUMBER() OVER ()) as id,\n trail_id,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.trail as trail_id,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id as trail_id,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747300536_updated_timeline.go
Normal file
40
db/migrations/1747300536_updated_timeline.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n (ROW_NUMBER() OVER ()) as id,\n trail_id,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.trail as trail_id,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id as trail_id,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
43
db/migrations/1747312289_updated_comments.go
Normal file
43
db/migrations/1747312289_updated_comments.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("fhgxdiam")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "fhgxdiam",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "rating",
|
||||
"onlyInt": false,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1747381400_updated_trails.go
Normal file
42
db/migrations/1747381400_updated_trails.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(22, []byte(`{
|
||||
"exceptDomains": [],
|
||||
"hidden": false,
|
||||
"id": "url1760183548",
|
||||
"name": "iri",
|
||||
"onlyDomains": [],
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("url1760183548")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747382660_updated_trails.go
Normal file
40
db/migrations/1747382660_updated_trails.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (@request.body.author.user = @request.auth.id || author.isLocal = false)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (@request.body.author.user = @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747383776_updated_trails.go
Normal file
40
db/migrations/1747383776_updated_trails.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && trail_share_via_trail.trail = id && trail_share_via_trail.user ?= @request.auth.id && trail_share_via_trail.permission = \"edit\") || (@request.auth.id != \"\" && author.isLocal = false)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && trail_share_via_trail.trail = id && trail_share_via_trail.user ?= @request.auth.id && trail_share_via_trail.permission = \"edit\")"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1747499980_updated_comments.go
Normal file
42
db/migrations/1747499980_updated_comments.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(4, []byte(`{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url2434853685",
|
||||
"name": "iri",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("url2434853685")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1747554117_updated_summit_logs.go
Normal file
42
db/migrations/1747554117_updated_summit_logs.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(11, []byte(`{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url2434853685",
|
||||
"name": "iri",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("url2434853685")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747554570_updated_summit_logs.go
Normal file
40
db/migrations/1747554570_updated_summit_logs.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (trail.author.user = @request.auth.id || trail.public = true)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\""
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
78
db/migrations/1747674856_updated_lists.go
Normal file
78
db/migrations/1747674856_updated_lists.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(5, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation3182418120",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "kwm6zdet",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation3182418120")
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(5, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "kwm6zdet",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
33
db/migrations/1747674913_set_list_authors.go
Normal file
33
db/migrations/1747674913_set_list_authors.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
lists, err := app.FindAllRecords("lists")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, l := range lists {
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", l.GetString("user"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
l.Set("author", actor.Id)
|
||||
err = app.UnsafeWithoutHooks().Save(l)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
44
db/migrations/1747675001_updated_lists.go
Normal file
44
db/migrations/1747675001_updated_lists.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("kwm6zdet")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "kwm6zdet",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
48
db/migrations/1747676287_updated_lists.go
Normal file
48
db/migrations/1747676287_updated_lists.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (@request.body.author.user = @request.auth.id)",
|
||||
"deleteRule": "author.user = @request.auth.id ",
|
||||
"listRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.user ?= @request.auth.id)",
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && list_share_via_list.list = id && list_share_via_list.user ?= @request.auth.id && list_share_via_list.permission = \"edit\")",
|
||||
"viewRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (@request.body.author = @request.auth.id)",
|
||||
"deleteRule": "author = @request.auth.id ",
|
||||
"listRule": "author = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.user ?= @request.auth.id)",
|
||||
"updateRule": "author = @request.auth.id || (@request.auth.id != \"\" && list_share_via_list.list = id && list_share_via_list.user ?= @request.auth.id && list_share_via_list.permission = \"edit\")",
|
||||
"viewRule": "author = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1747683009_updated_lists.go
Normal file
42
db/migrations/1747683009_updated_lists.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(7, []byte(`{
|
||||
"exceptDomains": null,
|
||||
"hidden": false,
|
||||
"id": "url2434853685",
|
||||
"name": "iri",
|
||||
"onlyDomains": null,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "url"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("url2434853685")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747683368_updated_lists.go
Normal file
40
db/migrations/1747683368_updated_lists.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (@request.body.author.user = @request.auth.id || author.isLocal = false)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (@request.body.author.user = @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1747683707_updated_lists.go
Normal file
40
db/migrations/1747683707_updated_lists.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && list_share_via_list.list = id && list_share_via_list.user ?= @request.auth.id && list_share_via_list.permission = \"edit\") || (@request.auth.id != \"\" && author.isLocal = false)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && list_share_via_list.list = id && list_share_via_list.user ?= @request.auth.id && list_share_via_list.permission = \"edit\")"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
57
db/migrations/1747945195_updated_timeline.go
Normal file
57
db/migrations/1747945195_updated_timeline.go
Normal file
@@ -0,0 +1,57 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n iri,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n trails.iri,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n trails.iri,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "json2434853685",
|
||||
"maxSize": 1,
|
||||
"name": "iri",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("json2434853685")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1747946749_updated_trails.go
Normal file
42
db/migrations/1747946749_updated_trails.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX ` + "`" + `idx_6tD5RqfVk2` + "`" + ` ON ` + "`" + `trails` + "`" + ` (` + "`" + `iri` + "`" + `)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": []
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1747946778_updated_lists.go
Normal file
42
db/migrations/1747946778_updated_lists.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX ` + "`" + `idx_hLtEU5XGWL` + "`" + ` ON ` + "`" + `lists` + "`" + ` (` + "`" + `iri` + "`" + `)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": []
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
108
db/migrations/1747952550_updated_timeline.go
Normal file
108
db/migrations/1747952550_updated_timeline.go
Normal file
@@ -0,0 +1,108 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n trail_author_username,\n trail_author_domain,\n trail_iri,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n tapa.username as trail_author_username,\n tapa.domain as trail_author_domain,\n trails.iri as trail_iri,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n sapa.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors sapa ON sapa.id = summit_logs.author\n JOIN activitypub_actors tapa ON tapa.id = trails.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n activitypub_actors.username as trail_author_username,\n activitypub_actors.domain as trail_author_domain,\n trails.iri as trail_iri,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("json2434853685")
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "json3184124860",
|
||||
"maxSize": 1,
|
||||
"name": "trail_author_username",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "json2887874732",
|
||||
"maxSize": 1,
|
||||
"name": "trail_author_domain",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(4, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "json113557190",
|
||||
"maxSize": 1,
|
||||
"name": "trail_iri",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n iri,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n trails.iri,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n activitypub_actors.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors ON activitypub_actors.id = summit_logs.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n trails.iri,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "json2434853685",
|
||||
"maxSize": 1,
|
||||
"name": "iri",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "json"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("json3184124860")
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("json2887874732")
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("json113557190")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
104
db/migrations/1747995473_updated_notifications.go
Normal file
104
db/migrations/1747995473_updated_notifications.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("tmghd4vo")
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("exqo1whj")
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(4, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation1745156937",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "recipient",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(5, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation3182418120",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(4, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "tmghd4vo",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "recipient",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(5, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "exqo1whj",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "author",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation1745156937")
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation3182418120")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1747996502_updated_notifications.go
Normal file
44
db/migrations/1747996502_updated_notifications.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "@request.auth.id = recipient.user",
|
||||
"updateRule": "@request.auth.id = recipient.user && (@request.body.type = null||@request.body.type = type) && (@request.body.metadata = null||@request.body.metadata = metadata) && (@request.body.recipient = null||@request.body.recipient = recipient) && (@request.body.author = null||@request.body.author = author) && @request.body.seen = true",
|
||||
"viewRule": "@request.auth.id = recipient.user"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "@request.auth.id = recipient",
|
||||
"updateRule": "@request.auth.id = recipient && (@request.body.type = null||@request.body.type = type) && (@request.body.metadata = null||@request.body.metadata = metadata) && (@request.body.recipient = null||@request.body.recipient = recipient) && (@request.body.author = null||@request.body.author = author) && @request.body.seen = true",
|
||||
"viewRule": "@request.auth.id = recipient"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
67
db/migrations/1747999298_updated_notifications.go
Normal file
67
db/migrations/1747999298_updated_notifications.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"trail_create",
|
||||
"list_create",
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1748002661_updated_follows.go
Normal file
42
db/migrations/1748002661_updated_follows.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX `+"`"+`idx_oM5KTHL3Lf`+"`"+` ON `+"`"+`follows`+"`"+` (\n `+"`"+`follower`+"`"+`,\n `+"`"+`followee`+"`"+`\n)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": []
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1748003743_updated_summit_logs.go
Normal file
42
db/migrations/1748003743_updated_summit_logs.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.trail ?= @request.auth.id)",
|
||||
"viewRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.trail ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || \ntrail.trail_share_via_trail.user = @request.auth.id",
|
||||
"viewRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || \ntrail.trail_share_via_trail.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1748084027_updated_follows.go
Normal file
42
db/migrations/1748084027_updated_follows.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "",
|
||||
"viewRule": ""
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("8obn1ukumze565i")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "@request.auth.id = follower.user.id || @request.auth.id = followee.user.id",
|
||||
"viewRule": "@request.auth.id = follower.user.id || @request.auth.id = followee.user.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1749553104_updated_trail_share.go
Normal file
44
db/migrations/1749553104_updated_trail_share.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1mns8mlal6uf9ku")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation2375276105",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "actor",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1mns8mlal6uf9ku")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation2375276105")
|
||||
|
||||
return app.UnsafeWithoutHooks().Save(collection)
|
||||
})
|
||||
}
|
||||
31
db/migrations/1749553105_migrate_trail_share.go
Normal file
31
db/migrations/1749553105_migrate_trail_share.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
shares, err := app.FindAllRecords("trail_share")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range shares {
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", s.GetString("user"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
s.Set("actor", actor.Id)
|
||||
err = app.Save(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
80
db/migrations/1749554811_updated_trails_filter.go
Normal file
80
db/migrations/1749554811_updated_trails_filter.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("4wbv9tz5zjdrjh1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT activitypub_actors.id, activitypub_actors.user, COALESCE(printf(\"%.2f\", MAX(trails.distance)), 0) AS max_distance,\n COALESCE(printf(\"%.2f\", MAX(trails.elevation_gain)), 0) AS max_elevation_gain, \n COALESCE(printf(\"%.2f\", MAX(trails.elevation_loss)), 0) AS max_elevation_loss, \n COALESCE(printf(\"%.2f\", MAX(trails.duration)), 0) AS max_duration, \n COALESCE(printf(\"%.2f\", MIN(trails.distance)), 0) AS min_distance, \n COALESCE(printf(\"%.2f\", MIN(trails.elevation_gain)), 0) AS min_elevation_gain, \n COALESCE(printf(\"%.2f\", MIN(trails.elevation_loss)), 0) AS min_elevation_loss, \n COALESCE(printf(\"%.2f\", MIN(trails.duration)), 0) AS min_duration \nFROM activitypub_actors \n LEFT JOIN trails ON \n activitypub_actors.id = trails.author OR \n trails.public = 1 OR \n EXISTS (\n SELECT 1 \n FROM trail_share \n WHERE trail_share.trail = trails.id \n AND trail_share.actor = activitypub_actors.id\n ) GROUP BY activitypub_actors.id;"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("_clone_U0cX")
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "_clone_rnMQ",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("4wbv9tz5zjdrjh1")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT activitypub_actors.id, activitypub_actors.user, COALESCE(printf(\"%.2f\", MAX(trails.distance)), 0) AS max_distance,\n COALESCE(printf(\"%.2f\", MAX(trails.elevation_gain)), 0) AS max_elevation_gain, \n COALESCE(printf(\"%.2f\", MAX(trails.elevation_loss)), 0) AS max_elevation_loss, \n COALESCE(printf(\"%.2f\", MAX(trails.duration)), 0) AS max_duration, \n COALESCE(printf(\"%.2f\", MIN(trails.distance)), 0) AS min_distance, \n COALESCE(printf(\"%.2f\", MIN(trails.elevation_gain)), 0) AS min_elevation_gain, \n COALESCE(printf(\"%.2f\", MIN(trails.elevation_loss)), 0) AS min_elevation_loss, \n COALESCE(printf(\"%.2f\", MIN(trails.duration)), 0) AS min_duration \nFROM activitypub_actors \n LEFT JOIN trails ON \n activitypub_actors.id = trails.author OR \n trails.public = 1 OR \n EXISTS (\n SELECT 1 \n FROM trail_share \n WHERE trail_share.trail = trails.id \n AND trail_share.user = activitypub_actors.user\n ) GROUP BY activitypub_actors.id;"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "_clone_U0cX",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("_clone_rnMQ")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
80
db/migrations/1749554826_updated_trails_bounding_box.go
Normal file
80
db/migrations/1749554826_updated_trails_bounding_box.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("urytyc428mwlbqq")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT \n activitypub_actors.id, activitypub_actors.user, \n COALESCE(MAX(trails.lat), 0) AS max_lat, \n COALESCE(MAX(trails.lon), 0) AS max_lon, \n COALESCE(MIN(trails.lat), 0) AS min_lat, \n COALESCE(MIN(trails.lon), 0) AS min_lon \nFROM activitypub_actors \nLEFT JOIN trails \n ON activitypub_actors.id = trails.author \n OR trails.public = TRUE \n OR EXISTS (\n SELECT 1 \n FROM trail_share \n WHERE trail_share.trail = trails.id \n AND trail_share.actor = activitypub_actors.id\n ) \nGROUP BY activitypub_actors.id;"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("_clone_2GUq")
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "_clone_4wMO",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("urytyc428mwlbqq")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT \n activitypub_actors.id, activitypub_actors.user, \n COALESCE(MAX(trails.lat), 0) AS max_lat, \n COALESCE(MAX(trails.lon), 0) AS max_lon, \n COALESCE(MIN(trails.lat), 0) AS min_lat, \n COALESCE(MIN(trails.lon), 0) AS min_lon \nFROM activitypub_actors \nLEFT JOIN trails \n ON activitypub_actors.id = trails.author \n OR trails.public = TRUE \n OR EXISTS (\n SELECT 1 \n FROM trail_share \n WHERE trail_share.trail = trails.id \n AND trail_share.user = activitypub_actors.id\n ) \nGROUP BY activitypub_actors.id;"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "_clone_2GUq",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("_clone_4wMO")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1749554910_updated_waypoints.go
Normal file
42
db/migrations/1749554910_updated_waypoints.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("goeo2ubp103rzp9")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "author = @request.auth.id || trails_via_waypoints.author.user ?= @request.auth.id || trails_via_waypoints.public ?= true || \n(@collection.trail_share.trail.id ?= trails_via_waypoints.id && @collection.trail_share.actor.user ?= @request.auth.id)",
|
||||
"viewRule": "author = @request.auth.id || trails_via_waypoints.author.user ?= @request.auth.id || trails_via_waypoints.public ?= true || \n(@collection.trail_share.trail.id ?= trails_via_waypoints.id && @collection.trail_share.actor.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("goeo2ubp103rzp9")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "author = @request.auth.id || trails_via_waypoints.author.user ?= @request.auth.id || trails_via_waypoints.public ?= true || \n(@collection.trail_share.trail.id ?= trails_via_waypoints.id && @collection.trail_share.user ?= @request.auth.id)",
|
||||
"viewRule": "author = @request.auth.id || trails_via_waypoints.author.user ?= @request.auth.id || trails_via_waypoints.public ?= true || \n(@collection.trail_share.trail.id ?= trails_via_waypoints.id && @collection.trail_share.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1749554952_updated_trails.go
Normal file
44
db/migrations/1749554952_updated_trails.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && trail_share_via_trail.actor.user ?= @request.auth.id)",
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && trail_share_via_trail.trail = id && trail_share_via_trail.actor.user ?= @request.auth.id && trail_share_via_trail.permission = \"edit\") || (@request.auth.id != \"\" && author.isLocal = false)",
|
||||
"viewRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && trail_share_via_trail.actor.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && trail_share_via_trail.user ?= @request.auth.id)",
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && trail_share_via_trail.trail = id && trail_share_via_trail.user ?= @request.auth.id && trail_share_via_trail.permission = \"edit\") || (@request.auth.id != \"\" && author.isLocal = false)",
|
||||
"viewRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && trail_share_via_trail.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1749555128_updated_summit_logs.go
Normal file
42
db/migrations/1749555128_updated_summit_logs.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.actor.user ?= @request.auth.id)",
|
||||
"viewRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.actor.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.trail ?= @request.auth.id)",
|
||||
"viewRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.trail ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1749555173_updated_comments.go
Normal file
44
db/migrations/1749555173_updated_comments.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id)",
|
||||
"listRule": "((@request.auth.id != \"\" && trail.author.user = @request.auth.id) || trail.public = true) || author = @request.auth.id || trail.trail_share_via_trail.actor.user ?= @request.auth.id",
|
||||
"viewRule": "((@request.auth.id != \"\" && trail.author.user = @request.auth.id) || trail.public = true) || author = @request.auth.id || trail.trail_share_via_trail.actor.user ?= @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.user ?= @request.auth.id)",
|
||||
"listRule": "((@request.auth.id != \"\" && trail.author.user = @request.auth.id) || trail.public = true) || author = @request.auth.id || trail.trail_share_via_trail.user ?= @request.auth.id",
|
||||
"viewRule": "((@request.auth.id != \"\" && trail.author.user = @request.auth.id) || trail.public = true) || author = @request.auth.id || trail.trail_share_via_trail.user ?= @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
62
db/migrations/1749555613_updated_trail_share.go
Normal file
62
db/migrations/1749555613_updated_trail_share.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1mns8mlal6uf9ku")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "trail.author.user = @request.auth.id || actor.user = @request.auth.id",
|
||||
"viewRule": "trail.author.user = @request.auth.id || actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("yyzimwee")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1mns8mlal6uf9ku")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "trail.author.user = @request.auth.id || user = @request.auth.id",
|
||||
"viewRule": "trail.author.user = @request.auth.id || user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "yyzimwee",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
55
db/migrations/1749555614_migrate_ms_token.go
Normal file
55
db/migrations/1749555614_migrate_ms_token.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"os"
|
||||
"pocketbase/util"
|
||||
|
||||
"github.com/meilisearch/meilisearch-go"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
client := meilisearch.New(os.Getenv("MEILI_URL"), meilisearch.WithAPIKey(os.Getenv("MEILI_MASTER_KEY")))
|
||||
|
||||
m.Register(func(app core.App) error {
|
||||
|
||||
users, err := app.FindAllRecords("users")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, u := range users {
|
||||
userId := u.Id
|
||||
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
searchRules := map[string]interface{}{
|
||||
"lists": map[string]string{
|
||||
"filter": "public = true OR author = " + actor.Id + " OR shares = " + actor.Id,
|
||||
},
|
||||
"trails": map[string]string{
|
||||
"filter": "public = true OR author = " + actor.Id + " OR shares = " + actor.Id,
|
||||
},
|
||||
}
|
||||
|
||||
token, err := util.GenerateMeilisearchToken(searchRules, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u.Set("token", token)
|
||||
if err := app.Save(u); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
// add down queries...
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
62
db/migrations/1749566277_updated_list_share.go
Normal file
62
db/migrations/1749566277_updated_list_share.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1kot7t9na3hi0gl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "list.author = @request.auth.id || actor.user = @request.auth.id",
|
||||
"viewRule": "list.author = @request.auth.id || actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation1148540665",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "actor",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1kot7t9na3hi0gl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "list.author = @request.auth.id || user = @request.auth.id",
|
||||
"viewRule": "list.author = @request.auth.id || user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("relation1148540665")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
31
db/migrations/1749566278_migrate_list_share.go
Normal file
31
db/migrations/1749566278_migrate_list_share.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
shares, err := app.FindAllRecords("list_share")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range shares {
|
||||
actor, err := app.FindFirstRecordByData("activitypub_actors", "user", s.GetString("user"))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
s.Set("actor", actor.Id)
|
||||
err = app.Save(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
44
db/migrations/1749566445_updated_lists.go
Normal file
44
db/migrations/1749566445_updated_lists.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.actor.user ?= @request.auth.id)",
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && list_share_via_list.list = id && list_share_via_list.actor.user ?= @request.auth.id && list_share_via_list.permission = \"edit\") || (@request.auth.id != \"\" && author.isLocal = false)",
|
||||
"viewRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.actor.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.user ?= @request.auth.id)",
|
||||
"updateRule": "author.user = @request.auth.id || (@request.auth.id != \"\" && list_share_via_list.list = id && list_share_via_list.user ?= @request.auth.id && list_share_via_list.permission = \"edit\") || (@request.auth.id != \"\" && author.isLocal = false)",
|
||||
"viewRule": "author.user = @request.auth.id || public = true || (@request.auth.id != \"\" && list_share_via_list.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1749566456_updated_list_share.go
Normal file
44
db/migrations/1749566456_updated_list_share.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1kot7t9na3hi0gl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("mix12kkh")
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1kot7t9na3hi0gl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "_pb_users_auth_",
|
||||
"hidden": false,
|
||||
"id": "mix12kkh",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "user",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
48
db/migrations/1749566852_updated_list_share.go
Normal file
48
db/migrations/1749566852_updated_list_share.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1kot7t9na3hi0gl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "list.author.user = @request.auth.id",
|
||||
"deleteRule": "list.author.user = @request.auth.id",
|
||||
"listRule": "list.author.user = @request.auth.id || actor.user = @request.auth.id",
|
||||
"updateRule": "list.author.user = @request.auth.id",
|
||||
"viewRule": "list.author.user = @request.auth.id || actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("1kot7t9na3hi0gl")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "list.author = @request.auth.id",
|
||||
"deleteRule": "list.author = @request.auth.id",
|
||||
"listRule": "list.author = @request.auth.id || actor.user = @request.auth.id",
|
||||
"updateRule": "list.author = @request.auth.id",
|
||||
"viewRule": "list.author = @request.auth.id || actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1749650389_updated_summit_logs.go
Normal file
40
db/migrations/1749650389_updated_summit_logs.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "@request.auth.id != \"\" && (trail.author.user = @request.auth.id || trail.public = true)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1749650422_updated_summit_logs.go
Normal file
42
db/migrations/1749650422_updated_summit_logs.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id",
|
||||
"viewRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.actor.user ?= @request.auth.id)",
|
||||
"viewRule": "(@request.auth.id != \"\" && (author.user = @request.auth.id || trail.author.user = @request.auth.id)) || trail.public = true || (@collection.trail_share.trail ?= trail && @collection.trail_share.actor.user ?= @request.auth.id)"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
103
db/migrations/1749717023_created_trail_like.go
Normal file
103
db/migrations/1749717023_created_trail_like.go
Normal file
@@ -0,0 +1,103 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
jsonData := `{
|
||||
"createRule": null,
|
||||
"deleteRule": null,
|
||||
"fields": [
|
||||
{
|
||||
"autogeneratePattern": "[a-z0-9]{15}",
|
||||
"hidden": false,
|
||||
"id": "text3208210256",
|
||||
"max": 15,
|
||||
"min": 15,
|
||||
"name": "id",
|
||||
"pattern": "^[a-z0-9]+$",
|
||||
"presentable": false,
|
||||
"primaryKey": true,
|
||||
"required": true,
|
||||
"system": true,
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "e864strfxo14pm4",
|
||||
"hidden": false,
|
||||
"id": "relation2993194383",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "trail",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
},
|
||||
{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "pbc_1295301207",
|
||||
"hidden": false,
|
||||
"id": "relation1148540665",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "actor",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "autodate2990389176",
|
||||
"name": "created",
|
||||
"onCreate": true,
|
||||
"onUpdate": false,
|
||||
"presentable": false,
|
||||
"system": false,
|
||||
"type": "autodate"
|
||||
},
|
||||
{
|
||||
"hidden": false,
|
||||
"id": "autodate3332085495",
|
||||
"name": "updated",
|
||||
"onCreate": true,
|
||||
"onUpdate": true,
|
||||
"presentable": false,
|
||||
"system": false,
|
||||
"type": "autodate"
|
||||
}
|
||||
],
|
||||
"id": "pbc_1995454416",
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX ` + "`" + `idx_ywIkmeaSFo` + "`" + ` ON ` + "`" + `trail_like` + "`" + ` (\n ` + "`" + `trail` + "`" + `,\n ` + "`" + `actor` + "`" + `\n)"
|
||||
],
|
||||
"listRule": null,
|
||||
"name": "trail_like",
|
||||
"system": false,
|
||||
"type": "base",
|
||||
"updateRule": null,
|
||||
"viewRule": null
|
||||
}`
|
||||
|
||||
collection := &core.Collection{}
|
||||
if err := json.Unmarshal([]byte(jsonData), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1995454416")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Delete(collection)
|
||||
})
|
||||
}
|
||||
46
db/migrations/1749717428_updated_trail_like.go
Normal file
46
db/migrations/1749717428_updated_trail_like.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1995454416")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": "trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id || actor.user = @request.auth.id",
|
||||
"deleteRule": "actor.user = @request.auth.id",
|
||||
"listRule": "trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id || actor.user = @request.auth.id",
|
||||
"viewRule": "trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id || actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1995454416")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"createRule": null,
|
||||
"deleteRule": null,
|
||||
"listRule": null,
|
||||
"viewRule": null
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1749831369_update_sortable_attributes.go
Normal file
42
db/migrations/1749831369_update_sortable_attributes.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/meilisearch/meilisearch-go"
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
client := meilisearch.New(os.Getenv("MEILI_URL"), meilisearch.WithAPIKey(os.Getenv("MEILI_MASTER_KEY")))
|
||||
|
||||
m.Register(func(app core.App) error {
|
||||
|
||||
_, err := client.Index("trails").UpdateSortableAttributes(&[]string{
|
||||
"created", "date", "difficulty", "distance", "elevation_gain", "elevation_loss", "name", "duration", "author", "like_count",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = client.Index("trails").UpdateFilterableAttributes(&[]string{
|
||||
"_geo", "author", "category", "completed", "date", "difficulty", "distance", "elevation_gain", "elevation_loss", "public", "shares", "tags", "likes",
|
||||
})
|
||||
|
||||
return err
|
||||
}, func(app core.App) error {
|
||||
_, err := client.Index("trails").UpdateSortableAttributes(&[]string{
|
||||
"created", "date", "difficulty", "distance", "elevation_gain", "elevation_loss", "name", "duration", "author",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = client.Index("trails").UpdateFilterableAttributes(&[]string{
|
||||
"_geo", "author", "category", "completed", "date", "difficulty", "distance", "elevation_gain", "elevation_loss", "public", "shares", "tags",
|
||||
})
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
67
db/migrations/1749836174_updated_notifications.go
Normal file
67
db/migrations/1749836174_updated_notifications.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create",
|
||||
"trail_like"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
43
db/migrations/1749837201_updated_trails.go
Normal file
43
db/migrations/1749837201_updated_trails.go
Normal file
@@ -0,0 +1,43 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// add field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(23, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "number851275141",
|
||||
"max": null,
|
||||
"min": 0,
|
||||
"name": "like_count",
|
||||
"onlyInt": true,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove field
|
||||
collection.Fields.RemoveById("number851275141")
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
40
db/migrations/1749837751_updated_trail_like.go
Normal file
40
db/migrations/1749837751_updated_trail_like.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1995454416")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewRule": "actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1995454416")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewRule": "trail.author.user = @request.auth.id || trail.public = true || trail.trail_share_via_trail.actor.user ?= @request.auth.id || actor.user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
82
db/migrations/1749894936_updated_trails.go
Normal file
82
db/migrations/1749894936_updated_trails.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(11, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "aqbpyawe",
|
||||
"maxSelect": 99,
|
||||
"maxSize": 20971520,
|
||||
"mimeTypes": [
|
||||
"image/jpeg",
|
||||
"image/vnd.mozilla.apng",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
"image/svg+xml",
|
||||
"image/heic",
|
||||
"video/mp4",
|
||||
"video/webm",
|
||||
"video/ogg"
|
||||
],
|
||||
"name": "photos",
|
||||
"presentable": false,
|
||||
"protected": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"thumbs": [
|
||||
"600x0"
|
||||
],
|
||||
"type": "file"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(11, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "aqbpyawe",
|
||||
"maxSelect": 99,
|
||||
"maxSize": 20971520,
|
||||
"mimeTypes": [
|
||||
"image/jpeg",
|
||||
"image/vnd.mozilla.apng",
|
||||
"image/png",
|
||||
"image/webp",
|
||||
"image/svg+xml",
|
||||
"image/heic",
|
||||
"video/mp4",
|
||||
"video/webm",
|
||||
"video/ogg"
|
||||
],
|
||||
"name": "photos",
|
||||
"presentable": false,
|
||||
"protected": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"thumbs": [],
|
||||
"type": "file"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1749902683_updated_activitypub_actors.go
Normal file
42
db/migrations/1749902683_updated_activitypub_actors.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1295301207")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "user.settings_via_user.privacy.account != 'private' || user = @request.auth.id",
|
||||
"viewRule": "user.settings_via_user.privacy.account != 'private' || user = @request.auth.id"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1295301207")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"listRule": "",
|
||||
"viewRule": ""
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1750259236_updated_comments.go
Normal file
42
db/migrations/1750259236_updated_comments.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX ` + "`" + `idx_4T3m08OsP1` + "`" + ` ON ` + "`" + `comments` + "`" + ` (` + "`" + `iri` + "`" + `) WHERE iri IS NOT NULL AND iri != \"\";"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("lf06qip3f4d11yk")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": []
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1750259275_updated_lists.go
Normal file
44
db/migrations/1750259275_updated_lists.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX ` + "`" + `idx_hLtEU5XGWL` + "`" + ` ON ` + "`" + `lists` + "`" + ` (` + "`" + `iri` + "`" + `) WHERE iri IS NOT NULL AND iri != \"\";"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("r6gu2ajyidy1x69")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX ` + "`" + `idx_hLtEU5XGWL` + "`" + ` ON ` + "`" + `lists` + "`" + ` (` + "`" + `iri` + "`" + `)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
42
db/migrations/1750259298_updated_summit_logs.go
Normal file
42
db/migrations/1750259298_updated_summit_logs.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX ` + "`" + `idx_iSbmEqYXbV` + "`" + ` ON ` + "`" + `summit_logs` + "`" + ` (` + "`" + `iri` + "`" + `) WHERE iri IS NOT NULL AND iri != \"\";"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("dd2l9a4vxpy2ni8")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": []
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
44
db/migrations/1750259324_updated_trails.go
Normal file
44
db/migrations/1750259324_updated_trails.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE UNIQUE INDEX ` + "`" + `idx_6tD5RqfVk2` + "`" + ` ON ` + "`" + `trails` + "`" + ` (` + "`" + `iri` + "`" + `) WHERE iri IS NOT NULL AND iri != \"\";"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("e864strfxo14pm4")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX ` + "`" + `idx_6tD5RqfVk2` + "`" + ` ON ` + "`" + `trails` + "`" + ` (` + "`" + `iri` + "`" + `)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
70
db/migrations/1750264310_updated_notifications.go
Normal file
70
db/migrations/1750264310_updated_notifications.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create",
|
||||
"trail_like",
|
||||
"comment_mention",
|
||||
"trail_mention"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create",
|
||||
"trail_like"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
73
db/migrations/1750267445_updated_notifications.go
Normal file
73
db/migrations/1750267445_updated_notifications.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create",
|
||||
"trail_like",
|
||||
"comment_mention",
|
||||
"trail_mention",
|
||||
"summit_log_mention"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("khrcci2uqknny8h")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update field
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "b57prsbu",
|
||||
"maxSelect": 1,
|
||||
"name": "type",
|
||||
"presentable": false,
|
||||
"required": true,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"new_follower",
|
||||
"trail_comment",
|
||||
"trail_share",
|
||||
"list_share",
|
||||
"summit_log_create",
|
||||
"trail_like",
|
||||
"comment_mention",
|
||||
"trail_mention"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
58
db/migrations/1750774093_swap_preferred_username.go
Normal file
58
db/migrations/1750774093_swap_preferred_username.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
actors, err := app.FindAllRecords("activitypub_actors")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, a := range actors {
|
||||
if !a.GetBool("isLocal") {
|
||||
continue
|
||||
}
|
||||
|
||||
username := a.GetString("username")
|
||||
preferredUsername := a.GetString("preferred_username")
|
||||
|
||||
a.Set("username", preferredUsername)
|
||||
a.Set("preferred_username", username)
|
||||
|
||||
err = app.Save(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}, func(app core.App) error {
|
||||
actors, err := app.FindAllRecords("activitypub_actors")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, a := range actors {
|
||||
if !a.GetBool("isLocal") {
|
||||
continue
|
||||
}
|
||||
|
||||
username := a.GetString("username")
|
||||
preferredUsername := a.GetString("preferred_username")
|
||||
|
||||
a.Set("username", preferredUsername)
|
||||
a.Set("preferred_username", username)
|
||||
|
||||
err = app.Save(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
40
db/migrations/1750780092_updated_timeline.go
Normal file
40
db/migrations/1750780092_updated_timeline.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
|
||||
func init() {
|
||||
m.Register(func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n trail_author_username,\n trail_author_domain,\n trail_iri,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n tapa.preferred_username as trail_author_username,\n tapa.domain as trail_author_domain,\n trails.iri as trail_iri,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n sapa.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors sapa ON sapa.id = summit_logs.author\n JOIN activitypub_actors tapa ON tapa.id = trails.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n activitypub_actors.preferred_username as trail_author_username,\n activitypub_actors.domain as trail_author_domain,\n trails.iri as trail_iri,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
}, func(app core.App) error {
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_468398817")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// update collection data
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"viewQuery": "SELECT\n id,\n trail_id,\n trail_author_username,\n trail_author_domain,\n trail_iri,\n date,\n name,\n description,\n gpx,\n author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n created,\n type\nFROM\n (\n SELECT\n summit_logs.id,\n summit_logs.trail as trail_id,\n tapa.username as trail_author_username,\n tapa.domain as trail_author_domain,\n trails.iri as trail_iri,\n summit_logs.date,\n trails.name,\n text as description,\n summit_logs.gpx,\n sapa.iri as author,\n summit_logs.photos,\n summit_logs.distance,\n summit_logs.duration,\n summit_logs.elevation_gain,\n summit_logs.elevation_loss,\n summit_logs.created,\n \"summit_log\" as type\n FROM\n summit_logs\n JOIN trails ON summit_logs.trail = trails.id\n JOIN activitypub_actors sapa ON sapa.id = summit_logs.author\n JOIN activitypub_actors tapa ON tapa.id = trails.author\n UNION\n SELECT\n trails.id,\n trails.id as trail_id,\n activitypub_actors.username as trail_author_username,\n activitypub_actors.domain as trail_author_domain,\n trails.iri as trail_iri,\n date,\n trails.name,\n description,\n gpx,\n activitypub_actors.iri as author,\n photos,\n distance,\n duration,\n elevation_gain,\n elevation_loss,\n trails.created,\n \"trail\" as type\n FROM\n trails\n JOIN activitypub_actors ON activitypub_actors.id = trails.author\n )\nORDER BY\n created DESC;\n"
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return app.Save(collection)
|
||||
})
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user