···2727 Links []string `json:"links,omitempty" cborgen:"links,omitempty"`
2828 // location: Free-form location text.
2929 Location *string `json:"location,omitempty" cborgen:"location,omitempty"`
3030- // pinnedRepositories: Any ATURI, it is up to appviews to validate these fields.
3131- PinnedRepositories []string `json:"pinnedRepositories,omitempty" cborgen:"pinnedRepositories,omitempty"`
3232- PinnedRepositoryDids []string `json:"pinnedRepositoryDids,omitempty" cborgen:"pinnedRepositoryDids,omitempty"`
3030+ // pinnedRepositories: Pinned repositories. Values are repo DIDs for repos that have them, or AT-URIs for legacy repos.
3131+ PinnedRepositories []string `json:"pinnedRepositories,omitempty" cborgen:"pinnedRepositories,omitempty"`
3332 // preferredHandle: A handle the user prefers to be displayed as.
3433 PreferredHandle *string `json:"preferredHandle,omitempty" cborgen:"preferredHandle,omitempty"`
3534 // pronouns: Preferred gender pronouns.
+2-82
api/tangled/cbor_gen.go
···2626 }
27272828 cw := cbg.NewCborWriter(w)
2929- fieldCount := 11
2929+ fieldCount := 10
30303131 if t.Avatar == nil {
3232 fieldCount--
···4545 }
46464747 if t.PinnedRepositories == nil {
4848- fieldCount--
4949- }
5050-5151- if t.PinnedRepositoryDids == nil {
5248 fieldCount--
5349 }
5450···344340 return err
345341 }
346342 for _, v := range t.PinnedRepositories {
347347- if len(v) > 1000000 {
348348- return xerrors.Errorf("Value in field v was too long")
349349- }
350350-351351- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
352352- return err
353353- }
354354- if _, err := cw.WriteString(string(v)); err != nil {
355355- return err
356356- }
357357-358358- }
359359- }
360360-361361- // t.PinnedRepositoryDids ([]string) (slice)
362362- if t.PinnedRepositoryDids != nil {
363363-364364- if len("pinnedRepositoryDids") > 1000000 {
365365- return xerrors.Errorf("Value in field \"pinnedRepositoryDids\" was too long")
366366- }
367367-368368- if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("pinnedRepositoryDids"))); err != nil {
369369- return err
370370- }
371371- if _, err := cw.WriteString(string("pinnedRepositoryDids")); err != nil {
372372- return err
373373- }
374374-375375- if len(t.PinnedRepositoryDids) > 8192 {
376376- return xerrors.Errorf("Slice value in field t.PinnedRepositoryDids was too long")
377377- }
378378-379379- if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.PinnedRepositoryDids))); err != nil {
380380- return err
381381- }
382382- for _, v := range t.PinnedRepositoryDids {
383343 if len(v) > 1000000 {
384344 return xerrors.Errorf("Value in field v was too long")
385345 }
···421381422382 n := extra
423383424424- nameBuf := make([]byte, 20)
384384+ nameBuf := make([]byte, 18)
425385 for i := uint64(0); i < n; i++ {
426386 nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
427387 if err != nil {
···686646 }
687647688648 t.PinnedRepositories[i] = string(sval)
689689- }
690690-691691- }
692692- }
693693- // t.PinnedRepositoryDids ([]string) (slice)
694694- case "pinnedRepositoryDids":
695695-696696- maj, extra, err = cr.ReadHeader()
697697- if err != nil {
698698- return err
699699- }
700700-701701- if extra > 8192 {
702702- return fmt.Errorf("t.PinnedRepositoryDids: array too large (%d)", extra)
703703- }
704704-705705- if maj != cbg.MajArray {
706706- return fmt.Errorf("expected cbor array")
707707- }
708708-709709- if extra > 0 {
710710- t.PinnedRepositoryDids = make([]string, extra)
711711- }
712712-713713- for i := 0; i < int(extra); i++ {
714714- {
715715- var maj byte
716716- var extra uint64
717717- var err error
718718- _ = maj
719719- _ = extra
720720- _ = err
721721-722722- {
723723- sval, err := cbg.ReadStringWithMax(cr, 1000000)
724724- if err != nil {
725725- return err
726726- }
727727-728728- t.PinnedRepositoryDids[i] = string(sval)
729649 }
730650731651 }
+34
appview/db/db.go
···13341334 return err
13351335 })
1336133613371337+ conn.ExecContext(ctx, "pragma foreign_keys = off;")
13381338+ orm.RunMigration(conn, logger, "drop-pinned-repos-at-uri-fk", func(tx *sql.Tx) error {
13391339+ _, err := tx.Exec(`
13401340+ create table if not exists profile_pinned_repositories_new (
13411341+ id integer primary key autoincrement,
13421342+ did text not null,
13431343+ pin text not null,
13441344+13451345+ unique(did, pin),
13461346+ foreign key (did) references profile(did) on delete cascade
13471347+ );
13481348+13491349+ insert into profile_pinned_repositories_new (id, did, pin)
13501350+ select id, did, at_uri from profile_pinned_repositories;
13511351+13521352+ drop table profile_pinned_repositories;
13531353+13541354+ alter table profile_pinned_repositories_new rename to profile_pinned_repositories;
13551355+ `)
13561356+ return err
13571357+ })
13581358+ conn.ExecContext(ctx, "pragma foreign_keys = on;")
13591359+13601360+ orm.RunMigration(conn, logger, "reset-profile-pin-rewrites", func(tx *sql.Tx) error {
13611361+ _, err := tx.Exec(`
13621362+ update pds_rewrite_status
13631363+ set status = 'pending',
13641364+ updated_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now')
13651365+ where record_nsid = 'sh.tangled.actor.profile'
13661366+ and status = 'done'
13671367+ `)
13681368+ return err
13691369+ })
13701370+13371371 return &DB{
13381372 db,
13391373 logger,
+16-16
appview/db/profile.go
···220220 }
221221222222 _, err := tx.Exec(
223223- `insert into profile_pinned_repositories (did, at_uri) values (?, ?)`,
223223+ `insert into profile_pinned_repositories (did, pin) values (?, ?)`,
224224 profile.Did,
225225 pin,
226226 )
···328328 idxs[did] = idx + 1
329329 }
330330331331- pinsQuery := fmt.Sprintf("select at_uri, did from profile_pinned_repositories where did in (%s)", inClause)
331331+ pinsQuery := fmt.Sprintf("select pin, did from profile_pinned_repositories where did in (%s)", inClause)
332332 rows, err = e.Query(pinsQuery, args...)
333333 if err != nil {
334334 return nil, err
···340340 idxs[did] = 0
341341 }
342342 for rows.Next() {
343343- var link syntax.ATURI
343343+ var pin string
344344 var did string
345345- if err = rows.Scan(&link, &did); err != nil {
345345+ if err = rows.Scan(&pin, &did); err != nil {
346346 return nil, err
347347 }
348348349349 idx := idxs[did]
350350- profileMap[did].PinnedRepos[idx] = link
350350+ profileMap[did].PinnedRepos[idx] = pin
351351 idxs[did] = idx + 1
352352 }
353353···435435 i++
436436 }
437437438438- rows, err = e.Query(`select at_uri from profile_pinned_repositories where did = ?`, did)
438438+ rows, err = e.Query(`select pin from profile_pinned_repositories where did = ?`, did)
439439 if err != nil {
440440 return nil, err
441441 }
···524524 return err
525525 }
526526527527- // ensure all pinned repos are either own repos or collaborating repos
528527 repos, err := GetRepos(e, orm.FilterEq("did", profile.Did))
529528 if err != nil {
530529 log.Printf("getting repos for %s: %s", profile.Did, err)
···535534 log.Printf("getting collaborating repos for %s: %s", profile.Did, err)
536535 }
537536538538- var validRepos []syntax.ATURI
539539- for _, r := range repos {
540540- validRepos = append(validRepos, r.RepoAt())
541541- }
542542- for _, r := range collaboratingRepos {
543543- validRepos = append(validRepos, r.RepoAt())
544544- }
537537+ // ensure all pinned repos are either own repos or collaborating repos
538538+ allRepos := append(repos, collaboratingRepos...)
545539546540 for _, pinned := range profile.PinnedRepos {
547541 if pinned == "" {
548542 continue
549543 }
550550- if !slices.Contains(validRepos, pinned) {
551551- return fmt.Errorf("Invalid pinned repo: `%s, does not belong to own or collaborating repos", pinned)
544544+ matched := slices.ContainsFunc(allRepos, func(r models.Repo) bool {
545545+ if strings.HasPrefix(pinned, "did:") {
546546+ return pinned == r.RepoDid
547547+ }
548548+ return pinned == string(r.RepoAt())
549549+ })
550550+ if !matched {
551551+ return fmt.Errorf("Invalid pinned repo: `%s`, does not belong to own or collaborating repos", pinned)
552552 }
553553 }
554554
+1-1
appview/db/repos.go
···630630 }
631631632632 profileRows, err := tx.Query(
633633- `SELECT DISTINCT did FROM profile_pinned_repositories WHERE at_uri = ?`,
633633+ `SELECT DISTINCT did FROM profile_pinned_repositories WHERE pin = ?`,
634634 repoAtUri,
635635 )
636636 if err != nil {
+2-2
appview/ingester.go
···364364 }
365365 }
366366367367- var pinned [6]syntax.ATURI
367367+ var pinned [6]string
368368 for i, r := range record.PinnedRepositories {
369369 if i < 6 {
370370- pinned[i] = syntax.ATURI(r)
370370+ pinned[i] = r
371371 }
372372 }
373373